《Web全栈工程师的自我修养》读书笔记

【声明】css

欢迎转载,但请保留文章原始出处→_→html

生命壹号:http://www.cnblogs.com/smyhvae/前端

文章来源:http://www.cnblogs.com/smyhvae/p/5243181.htmlgit

【正文】程序员

豆瓣连接:https://book.douban.com/subject/26598045/
github

【目录】web

  • 01 什么是全栈工程师
  • 02 如何成为全栈工程师
  • 03 从学生到工程师
  • 04 野生程序员的故事
  • 05 工程师事业指南
  • 06 全栈工程师眼中的HTTP
  • 07 高性能网站的关键:缓存
  • 08 大前端

什么是全栈工程师

全栈工程师(Full-Stack Engineer):一个能处理数据库、服务器、系统工程和客户端的全部工做的工程师。根据项目的不一样,客户须要的多是移动栈、Web栈,或者原生应用程序栈。
面试

全栈:表示为了完成一个项目,所须要的一系列技术的集合。应该从能力和思惟方式两方面,来断定一我的是不是一个合格的全栈工程师。简单来讲*全栈工程师就是能够独立完成一个产品的人。算法

一、Web开发流程

大中型互联网公司的产品研发流水线:产品设计-->交互设计-->视觉设计-->前端开发、后台开发-->测试-->发布。数据库

产品经理:产品经理实际上是对一个产品负根本责任的管理者。他一般的工做包括制订产品规划、协调多方资源、把控产品方向和质量细节,等等。有时候,他会从头策划一个新的产品,而更多的时候,他是在优化已有产品的一个部分。总之,在流水线中,产品经理须要从策划跟进到发布,是一个很是重要的角色。

用户研究员:用户研究员的工做是研究用户行为,有时候他会从宏观的角度分析数据,有时候也从微观的角度分解用户场景,有时候会召集一些用户专门来访谈,或者观察用户对产品的使用状况。从输出品的角度来讲,用户研究员通常输出用户研究报告来交付给产品经理和交互设计师,做为产品设计的目标参考。
交互设计师:交互设计师常被简称为“交互”。他与视觉设计师最大的区别是,交互设计师更多着眼于如何优化用户界面的信息分布和操做流程。交互设计师的输出品通常是描述用户与网站“交互”过程的流程图,以及描述页面信息结构的线框图。输出的线框图会交付给视觉设计师。

视觉设计师:在细分交互设计师和视觉设计师的大公司,视觉设计师根据交互设计师输出的线框图来作一些润色和设计,输出最终的产品视觉稿以后将视觉稿交付给前端工程师。在一些不细分交互设计师和视觉设计师的小公司,两者被统称为“设计师”,他们的职责就是负责整个用户界面的设计。

前端工程师:产品视觉稿在获得产品经理和交互设计师等多方确认以后,会交给前端工程师,由前端工程师制做页面,实现视觉稿以及交互功能。从头衔上的变化就能够看出,这时候才真正开始编码。前端工程师须要很是熟悉HTML、CSS和JavaScript,以及性能、语义化、多浏览器兼容、SEO、自动化工具等普遍的知识。

后台工程师:使用服务器编程语言,进行服务器功能的开发。在编程语言的选择上,不少公司都会出于团队已有成员的知识储备、程序员的供给量或者语言性能方面来进行选择。在这一方面,后台语言的选择是相对自由的一件事,不像前端工程师,为了页面兼容性,必须使用HTML和CSS。若是关注各大公司招聘信息的话,您就会了解,不一样公司使用不一样的后台语言,好比传统的C#和C++、Java、PHP,或者新潮的RoR和Python。小公司的后台工程师除了负责功能开发,可能还会负责服务器的配置和调试、数据库的配置和管理等工做。在大公司,这些工做会分别委派给后台工程师、运维工程师、数据库管理员(DBA)等岗位。

运维工程师:运维工程师是跟服务器打交道的人,他会关注服务器的性能、压力、成本和安全等信息。

测试工程师:顾名思义,测试工程师保证产品的可用性,即便在小公司,这一职位也是不可或缺的。

备注:在项目管理中,常常会用到甘特图。甘特图(Gantt Chart)是柱状图的一种,显示项目、子项目、进度以及其余与时间相关的系统的进展状况。

二、技术的发展

提到全栈技术,不得不提一个表明性的全栈框架——MEAN,它是MongoDB-Express-AngularJs-Node.js的缩写,是从数据库、服务器到前端页面的一个完整技术栈。

MongoDB是一个面向文档的、NoSQL类型的数据库。MongoDB颠覆了传统的基于表的数据存储方式,而采起了相似JSON的文档结构来存储数据,于是它在储存数据时能够更加灵活。

Express是一个Node.js框架,能够建立灵活的Web服务,好比单页面应用程序、多页面应用程序和混合型App。

AngularJS是一个开源的JavaScript框架,由Google和开源社区共同维护,它用来建立单页面应用程序。它的目标是使用model-view-controller模式来规范Web应用程序,让开发和测试富交互的单页面应用程序变得更加轻松。

Node.js是一个运行在服务器端的JavaScript运行环境,它的底层是基于Chrome的JavaScript运行环境——V8引擎。Node.js能够做为服务器端语言,用来建立快速、可扩展的应用程序。Node.js也能够在本机运行,作一些本地操做,好比加速本地开发流程,或者实现一键发布。

MEAN能够说是传统的LAMP方案的有力竞争者。由于从服务器端到页面端都采用一样的语言(JavaScript)和一样的架构模式(MVC),因此一个擅长JavaScript的工程师能够兼顾先后端的开发,而且前端模板代码和后台模板代码是能够复用的。

三、提供PaaS服务的平台愈来愈多

随着Web技术的发展和开源社区的积极努力,有不少公司提供便宜又方便的一条龙服务,能够解决独立开发者的大量麻烦。

好比Amazon提供的PaaS(Platform as a Service,平台即服务),就可让创业公司的开发者省去架设和维护服务器的麻烦。

而GitHub在2012年得到了一亿美圆融资,也能够看出市场对代码托管市场的信心。能够预期,将来可能会出现愈来愈多为开发者提供服务的公司。之后,小公司也能够用更低廉的价格得到世界级的IT服务支持,毫无疑问,更多的IT服务将托管在第三方的服务器上。

VPS(Virtual Private Server,虚拟专用服务器)是把一台物理服务器虚拟成多个虚拟专用服务器的服务。每一个VPS均可分配独立的公网IP地址,运行独立的操做系统,拥有独立的磁盘空间、内存、CPU资源、进程和系统配置,模拟出“独占”使用计算资源的体验。

四、一专多长

我跟一位行业专家讨论过全栈工程师的话题,他不是很赞同全栈工程师这个方向。他认为,工程师应该有专精的技能和目标,若是初学者贪图大而全,反而样样不精。我理解他的担忧,若是一个工程师没有坚实的基础(好比专业理论知识,对经常使用设计模式的理解,或者特定职业的基础知识),那么了解的非本专业技能越多,越容易迷失。

因此我认为,全栈工程师首先要“一专多长”。一专多长的意思是,工程师首先有一个专精的方向,在这个方向上足够精通以后(高级工程师级别),以此为突破点去学习更多的知识,增长本身的长处。若是尚未得到某个方向上足够深刻的理解,就不要囫囵吞枣地去学习其余领域的知识。

有些知识须要时间的积累,并非快速阅读就能够掌握的。“全栈工程师”这个名词可能会引发读者的误解。勿在浮沙筑高台,“全栈”是一个长期积累的过程,是专精型工程师在不断解决问题的过程当中积累知识和经验所造成的能力,而不是一蹴而就的过程。

五、解决问题,而不是醉心技术

公司存在的意义就是解决问题,公司要解决用户的问题,而员工要解决公司的问题。

公司的问题多是下降成本、扩大用户群、增长成交量、优化性能,等等。不一样的问题优先级不同,投入一样的时间,有的项目能为公司增长上百万的收入,而有的项目却只能增长几万。

互联网领域发展很快,问题的优先级永远都是在动态变化的,因此团队每每每半年或者三个月就要回顾一下当前形势,并制定新的工做计划。若是新计划不是您擅长的,怎么办?您应该立刻开始学习新的技术,这就是我说的关注问题,而不是醉心技术

高级工程师能够选择往上下游去扩展本身的能力,并承担更多的责任,给公司带来更大的收益,也给本身带来更大的成长空间。程序员在小公司里主动去承担更多责任,本身跟公司都会得到相应的成长。在自由职业市场,全栈工程师是最闪耀的明星。全栈工程师仍是天生的创业者。

延伸阅读:

  • 《黑客与画家》(美)保罗·格雷厄姆,人民邮电出版社
  • 《专业主义》(日)大前研一,中信出版社

如何成为全栈工程师

一、先精后广,一专多长

推荐采用“先精后广,一专多长”的流程来学习:先在一个特定的方向上有比较深刻的钻研,而后再将学习目标渐渐推广开来。好比先从前端方向入手,掌握了基本的HTML、CSS、JavaScript以后,不要转头向服务器端语言或者App方向发展,而是深刻到性能优化、SEO、多种框架、响应式页面等前端细节中去。通过一到两年的深刻研究以后,再去学习其余方向。

采用这种方式来学习,不光能够举一反三、触类旁通,还让咱们学习得更快,并且按部就班更符合通常人的职业生涯发展。

腾讯社交用户体验设计部招聘前端开发,要求以下:

  • 本科以上学历。
  • 两年以上工做经验。
  • 精通HTML、CSS、JavaScript等前端相关技术,熟悉W3C网页标准。
  • 熟悉至少一种后台语言的开发机制(如Java、C++等)。
  • 有必定架构能力和算法能力,有良好编码规范。
  • 良好的学习能力、沟通能力,追求完美,有工做激情,能在较大强度下工做。
  • 热爱互联网,喜欢研究各类互联网技术者更好

有的竞争者提到他很擅长页面性能优化、响应式、页面渲染效率,有的写过JavaScript框架……你须要在招聘要求的方向上以200%的能力来获得这个职位。

二、围绕商业目标

老板雇用一个员工,不是由于他能写程序,而是由于他能帮助本身赚钱。

我喜欢这样的态度:对将来有本身的方向,但也知道本身无法看得太清晰。对商业和市场有想法,并且本身也有足够的技术能力和自信向将来前进

记住,当您只有一把锤子,您看什么都是钉子。而若是您痴迷于工具,反而看不到问题所在。所以,要先看看有哪些问题须要解决,而后再补充您的工具箱。永远从商业目标的角度来决定学习哪些东西,而不是纯粹为了锻炼技术能力而去学习。

三、用户是谁

这里的“用户”仍然是一个广义的定义:全部您为之服务的人。

四、大巧若拙

大巧若拙:指真正聪明的人,不会显露本身,反面从表面看好像还很笨拙。用户体验不仅是界面和交互这样能够直观感觉的东西,还包括一些隐藏在用户界面背后的细节和规范
就像冰山,露出水面的部分只占整个冰山的1/9,用户看到的只是显露出来的部分。背后的部分通常用户是看不到的:好比用户研究,用研团队会经过调查,输出一些用户画像,影响整个产品的功能方向、设计风格;还有设计规范,设计团队在设计产品的一开始制定了规范以后,新增长的功能和页面都必须遵循已有的设计规范,这样整个产品是统一的,可以给用户专业的感受。

我若是开创一个公司须要招聘“全栈工程师”,我要求的三个能力:一专多长关注商业目标关注用户体验

延伸阅读:

  • 《重来:更为简单有效的商业思惟》 (美) 贾森·弗里德 / (丹) 戴维·海涅迈尔·汉森,中信出版社
  • 《精益创业》(美) 埃里克·莱斯,中信出版社

从学生到工程师

前端工程师要有一个基本常识,那就是结构、表现和行为要分离。具体解释以下:

  • 网站的内容使用语义化的HTML标签,而不掺杂任何表现和逻辑;
  • 网站样式表现用CSS来描述,既能在多个页面之间复用,也能够根据不一样用户来分别定义外观;
  • 页面行为逻辑用JavaScript来实现,这样保证浏览器在禁用JavaScript的时候,页面也能正常渲染和使用。

岗位优先于公司,即便在一个很好的公司里面,若是只是作着本身不喜欢也不擅长的工做,那能有什么前途呢。

其实个人设计知识仅限于自学,来自于一本书——《写给你们看的设计书》。这本书很是入门,可是浅显易懂,既有设计理念,也有实际操做,到如今为止我反复看了3遍以上。

我理解了书里说的设计四大原则对齐、对比、距离和重复。虽然我基本没有设计经验,只会一些基本的Photoshop操做,但我理解了这几个原则,每次看到好的设计和差的设计时,都能有所感悟。若是不理解,可能我只能用“上流”“高端”“简约”这样空泛的词汇来描述设计。关于设计原则,我在后面的章节中会单独提到。

校园招聘是不少大公司很喜欢的一我的才渠道,由于比起社会招聘的应聘者,毕业生更加有空杯心态、更正能量、更有激情,虽然缺乏经验,可是通过一两年的培训也能很快成为团队骨干。而若是是自己有项目经验的毕业生,或者是在GitHub上有知名做品、知名博客、去过其余大公司实习的毕业生,那就更加抢手了。至于大学考试成绩,影响不大。
社会招聘的目标是有经验者,招聘时间没有校园招聘那么固定,随时均可能有职位空缺,可是每次放出的名额不会不少。并且这时候会根据招聘岗位,有针对性地考核应聘者的专业能力与综合能力,致使社招的竞争是很是激烈的。
相对而言,我认为校园招聘的门槛并不高,重要的是找对方法。若是您的学校不是顶级,您的成绩不是学霸,那就要走不寻常的道路。

一、得到面试机会

不管您是名牌大学的高材生,仍是自学成才的专科生,在制做第一份简历的时候,我有这样几个建议:

  • 首先肯定本身的求职意向,针对特定意向填写您的简历。
  • 若是您想表达出本身的创意,不要使用各大招聘网站提供的简历模版。
  • 把简历发送到真正在招人的企业主管那里。

举一个例子,做为程序员和设计师,做品是排名最高的信号。在著名开源项目中贡献代码,说明您有能力阅读和编写好的代码,这是公司直接须要的技能。此外,这还能说明您有能力与他人协做:开源代码老是须要协做的。开源项目还能代表您对新鲜事物有热情,代表您也许英语能力不错,有查阅文档的能力……一个开源项目须要的精力也许不会特别多,但它的加分点可就很是多了,简直是一箭N雕!

为何要把简历发送到真正招人的企业主管那里?由于HR没有能力辨别技术能力的高低,他只能根据学历、分数等硬指标来筛选。因此一些技术能力优秀可是分数不高的同窗可能就很遗憾地失去了面试机会。

二、实习

实习能提高本身的实践能力,能够认为是从学生到社会人士的一个身份过渡。建议:

  • 记住团队里的每个人
  • 有任何问题,主动问导师
  • 主动介绍本身,告诉你们本身是新人,请多关照
  • 每周发邮件记录心得总结、经验教训、学习成长
  • 实习结束时,用邮件总结全部项目,给出交接文档,并向你们致谢

延伸阅读:

  • 《编程之美:微软技术面试心得》《编程之美》小组,电子工业出版社

野生程序员的故事

野生程序员是指仅凭对计算机开发的兴趣进入这个行业,从前端到后台一手包揽,但各方面能力都不精通的人。野生程序员有很强大的单兵做战能力,可是在编入“正规军”以后,可能会不适应新的作事方法。

一、Web性能优化

  • 压缩源码和图片

JavaScript文件源代码能够采用混淆压缩的方式,CSS文件源代码进行普通压缩,JPG图片能够根据具体质量来压缩为50%到70%,PNG能够使用一些开源压缩软件来压缩,好比24色变成8色、去掉一些PNG格式信息等。

  • 选择合适的图片格式

若是图片颜色数较多就使用JPG格式,若是图片颜色数较少就使用PNG格式,若是可以经过服务器端判断浏览器支持WebP,那么就使用WebP格式和SVG格式。

  • 合并静态资源

包括CSS、JavaScript和小图片,减小HTTP请求。

  • 开启服务器端的Gzip压缩

这对文本资源很是有效,对图片资源则没那么大的压缩比率。

  • 使用CDN

或者一些公开库使用第三方提供的静态资源地址(好比jQuery、normalize.css)。一方面增长并发下载量,另外一方面可以和其余网站共享缓存。

  • 延长静态资源缓存时间

这样,频繁访问网站的访客就可以更快地访问。不过,这里要经过修改文件名的方式,确保在资源更新的时候,用户会拉取到最新的内容。

  • 把CSS放在页面头部,把JavaScript放在页面底部

这样就不会阻塞页面渲染,让页面出现长时间的空白。

备注:每个条目均可以进一步深层挖掘下去。Web性能优化分为服务器端和浏览器端两个方面。

此外,因为中文的歧义性,Web性能优化这个词既能够解读成页面加载速度(Page Speed)的优化,也能够解读成页面渲染性能(Page Performance)的优化。或者是两者的集合。因此,应聘者若是能在这个问题上多作一些分析,会有很高的加分。可是若是你在网络性能方面的研究只是浅尝辄止,停留在压缩资源方面,这说明你尚未足够理解HTTP协议自己。

关于网络性能和HTTP协议,做为大公司的前端工程师是很是看重的,由于每个页面都会有亿万用户访问量,任何一点对服务器带宽压力都会聚沙成塔,最终形成很大的成本。关于这方面的技术详解,我在后面会有一篇单独的文章来分析。

二、知易行难

我问一个面试者:“关于服务器端MVC架构的技术实现,您是怎样理解的?”他说:“是数据模型、视图、控制器的分离。”

我更进一步问道:“这种架构方式有什么好处?您在项目中是如何应用这一架构的?”他回答说:“MVC的架构方式会让项目可维护性更高,全部涉及界面的代码都在视图(View)里面,全部涉及核心逻辑的代码都在模型(Model)里面,URL路由之类的代码都在控制器(Controller)里面。我在项目中使用了MVC架构的PHP框架——CodeIgniter。”

我一边打开他的网站,一边继续跟他电话沟通。当看到网站的CSS代码都直接内嵌在HTML头部的时候,我忍不住问他:“为何您的网站的CSS代码都内嵌在HTML里面呢,是使用自动化工具合并进去的吗?”他支支吾吾地说:“由于在本地调试的时候,CSS文件修改常常不生效,因此就直接在HTML里面改了,这样比较快。”

好吧,我想这是一个典型的“知易行难”的开发者,他知道采用MVC架构的项目的可维护性更高,但是在分离样式与结构上面尚未达到最基本的要求,甚至把CSS写在HTML中。至于他说的在本地环境上发现CSS文件常常缓存,可能要看看本地服务器的缓存设置是否有问题,而后再作调试。稍微了解一点HTTP的浏览器端缓存,这就不是难事了。我更欣赏在开发流程上花工夫去理解和优化的应聘者,而不是马马虎虎,只是以完成需求为目标的人。

三、什么是“野生程序员”

野生程序员”:就是没有计算机基础知识和相关教育经历,靠着对计算机开发的兴趣进入这个行业,虽然知识面比较广,可是各方面都只知其一;不知其二的开发者。

这几年我从一个求职者,转变成一个招聘者,有一个感觉就是,中国高等教育与市场需求不接轨。学校不了解市场究竟须要什么样的人才,其设立的课程和技术每每比市场技术现状落后了5年以上。我在大学学习用ASP建站,可是如今已经几乎没有人用ASP建站了。一个直接的后果是,不少高校毕业生不能知足企业的要求。

与此同时,中国互联网市场蓬勃发展,特别是移动互联网的发力,让中国跳过“WAP时代”,直接进入“App时代”。市场的热钱都投入到互联网行业,“BAT”等大公司不断扩张,创业公司也如雨后春笋,整个市场对软件工程师的需求缺口巨大,因此不少公司在招人的时候,无法招聘到“专业”的计算机专业毕业生。

在美国,由于教育与市场稳定发展了不少年,供求关系相对平衡,计算机相关专业本科已经成为基本要求。举例而言,美国的硅谷公司(如Google)绝大部分前端开发招聘岗位都有一个最低要求——本科学历,计算机相关专业。

相比而言,从中国的大公司(如腾讯)的招聘网站上能够看出,有一些前端开发岗位没有对学历的要求,也有一些要求“本科及以上学历”,少数才会要求“本科学历,计算机相关专业”。咱们的团队中就有一些成员是大专学历。许多企业在招聘的时候每每放松了对学历的要求,只看重项目和经验,而不看重学历。这是一件好事,表明市场在高等教育的规模和质量都跟不上市场要求的状况下,给予更多有兴趣和能力的年轻人进入IT领域的机会,也填补了人才市场的空缺。

美国硅谷,是世界互联网公司的中心,是全部求职者求之不得的圣地。在最开始,硅谷之因此名字当中有一个“硅”字,是由于当地企业多数是从事加工制造高浓度硅的半导体行业和电脑工业。随后,互联网公司和软件公司渐渐取代传统的硬件公司,让硅谷得到了新的生命,但硅谷这个名字保留了下来。在硅谷从诞生到发展壮大的整个生命周期中,斯坦福大学起到了很大的做用,我认为称之为硅谷的母亲也不为过。

在中国,因为政策、环境、历史缘由,还有大学教育投入上的差别,致使大学在整个互联网发展中起的做用没那么大。中美两国IT人才市场供求关系上的这些差异,也反映在整个行业文化中。

一个直观的反映就是软件工程师的“草根”化。其实不少软件工程师的收入都很高,处于中上层水平,相比金融行业的白领也绝不逊色,可是一谈起程序员,你们的印象仍是“一年四季的T恤(在行业展会上免费拿的)牛仔裤,平时也喜欢宅在家里,不会像一样收入的金融白领,平时爱好听歌剧打高尔夫球”。这种差别一方面是外部人士对软件工程师职业的偏见,另外一方面也是程序员行业的自黑习惯。在招聘时岗位要求就已经放到最低:不要求学历、上班不要求着装、上下班时间灵活,这样才好更方便地招聘。而金融行业有意识地塑造一种“精英”文化,从学历就设置高门槛,即便有些工做根本不须要那么高的学历。

回到毕业生的话题,不少跨专业的学生发现本身兴趣在互联网和计算机方向的时候,就开始了自学之路,基本上学习方式有这样几种:

:在计算机图书领域,技术难度跟图书销量是成反比的,从标签教起的HTML/CSS基础书籍卖得最好,其次是关于JavaScript和jQuery的书,Angular和Node.js之类的就没那么畅销了。

互联网:得益于全世界都在互联网上共享的资源,如今的学习者有了更多的选择,好比关于Web开发基础教学的W3CSchool,还有海量的技术博客。我我的喜欢订阅一些英文大站,好比Smashing Magazine(http://www.smashingmagazine.com/)、tuts+(http://tutsplus.com/)等。我在读大学的时候,Google Reader尚未永久关闭,那时候我很喜欢用RSS来关注这些站点的更新状况。Google Reader下线后,就基本上废弃了RSS阅读的习惯,转而用一些社交网站来追踪更新状况,可是有时仍是会淹没在大量无用的信息里面。

社团:学校的网站社团也孕育了许多能力很强的开发者,社团通过历届的传帮带,技术有所积累,好比师兄会教师弟用Sublime编辑器,这就比还在用Dreamweaver的同窗更有优点。此外,学校社团有一些定点客户,好比学校教务处、周边商户,因此有更多的实战经验,在毕业时做品集也丰富了很多。

由于有这样一些自学渠道,因此不必定只有计算机专业毕业的学生才有机会进入互联网行业。毕业以后,这些计算机爱好者进入不一样的工做岗位,不一样的是,有些进入大公司,有些进入小公司。这二者的成长轨迹每每会不太同样。

四、大公司仍是创业公司

若是你是毕业生,这种状况下我仍是建议选择大公司,由于会选择创业公司的人每每有本身的主见,已经接受创业公司的邀请去工做了,不会去发帖询问你们的意见。固然这是开玩笑,真正的缘由是,在大公司的头两年,是从学生到职场人士的一个转变,您可能会从大平台学习到一些规范的流程方法,养成一些足以影响您一辈子的习惯,认识更多的能对您职场有帮助的人脉

大公司能给你的有:

  • 较小的风险

每一个公司都有倒闭的可能,可是,显然大公司比小公司的风险低多了。若是您的风险承受能力较低,那么不得不考虑这个因素。

  • 技术最佳实践

在大公司,对代码质量和一致性的要求很高,因此通常在最终发布前会有代码审查(Code Review)流程和项目总结会等。若是您完成了一个任务,可是没有采用最佳实践,只是hack了一下,那么其余同事可能都会指出您的问题,而且要求您改正以后再提交。小公司或者创业公司人力比较紧张,在他们看来,快速实现和上线,比优雅地上线更重要,因此对于一些最佳实践类的问题,只能睁一只眼闭一只眼啦。

  • 垂直专精的技能

大公司专业分工很细,并且有更多技术沟通和沉淀的氛围,因此容易让人在垂直专精的技术方向有足够的发展。在小公司更能锻炼技术的广度,深度上缺少锻炼的环境。可是其实两者的利弊,都是外界的,技术人员的我的成长除了工做时间的锻炼,还要靠下班后的时间,外界只是给予一个环境或者机会。

  • 服务海量用户的经验

一样是作一个网站,服务少数用户量和服务海量用户量时须要考虑的事情是彻底不一样的。小网站遇到的问题,大网站必定遇到过,而大网站遇到的问题,小网站就不必定遇到过了。当一个网站发展到业内最强时,它的问题没有人遇到过,这时候就不能凡事问百度、Google或Stack Overflow了,而要本身去探索解决方案。

  • 软技能

硬技能是指每一个职位须要的专业技能,软技能则是通用的技能,好比沟通、影响力、项目管理和演讲等。越是大公司,越是看重影响力,因此会有不少培训教您如何提升影响力。

我在面试一些来自小公司的应聘者时,就发现他平时的工做中,周边环境不多有分享和沉淀的习惯。沉淀和总结是很重要的,在腾讯,设计师作完一次设计定稿以后,就会把设计的思路,包括总体的设计风格、设计规范和色彩的肯定等都总结成一封邮件或者PPT,发送给部门同事。每一个人都要有意识地维护本身的做品集,它在半年一次的考核、晋升面试甚至之后的跳槽中都很是有用。可是小公司的设计师不太会总结我的做品集,时间紧急是一方面缘由,另外一个主要缘由是环境不须要他这样作,所以就缺少了这方面的锻炼。

  • 人脉

每一年都有很多人从大公司离职去创业,这是很是天然的事情。对于大公司出来的人来讲,以前积累的人脉资源这时候会起到很大的做用,好比创业期间的一些合做机会或者资源的互利,等等。万一创业失败,也不会很惨,由于您以前接触的人脉能够给您提供工做机会。但若是您刚毕业就选择创业,创业失败以后没有人能给您提供工做机会。

  • 心态

其实大公司能给予毕业生最大的优点,就是提供一个心智培育的土壤。以前参加面试官培训的时候,我大概了解过公司招聘一个毕业生投入的成本。从校园招聘,到安排面试官面试候选人,再到封闭培训和一些课程培训,再给一段时间熟悉项目,最后3个月试用期后可能还要淘汰掉一些。若是把成本平摊到每个人身上,这些投入要一年才能收回来。而小公司不会有这么大的耐心去培育一个新人。若是没有足够的时间去学习和成长,可能在一两年后,员工的能力也比较全面,可是样样都不精通,也说不清楚本身的目标是什么,因而就变成了“野生程序员”。

综合来说,在大公司中,从硬技能到软技能都会有不少经验丰富的前辈可以教您,您会在大平台上学习到不少东西。工做几年以后,员工的选择也不少,要么走技术路线继续发展下去,作高级工程师;要么学习管理和领导力;要么出去创业。

因此,个人我的建议是,从毕业生本身前途发展的角度来看,先加入一家上市大公司是个不错的选择。

延伸阅读:

  • 《打造Facebook》王淮, 印刷工业出版社

工程师事业指南

我曾读过一本有意思的书,《您就是极客》,副标题是“软件开发人员生存指南”。其中第二章专门讲软件工程师事业的3个关键词:技术、成长和声望。前面的文章里已经讲了技术和成长,如今咱们来谈谈声望。

一、重视做品集

做品集(portfolio),是指您我的的项目和做品的集合,一份精心准备的做品集比简历更能说服人。

我很重视做品集,一方面体如今我很在乎维护本身的做品集,另外一方面我也很喜欢面试的时候看到应聘者有本身的做品集。除了工做上安排的项目,我更在乎一些课外项目,由于它展现了您的兴趣和热情所在。

从某种程度上来说,重视展现项目这种态度确实会对编程的纯粹性有所腐蚀(若是您编程自己只是为了本身的兴趣),您编写一个项目的动机可能会从纯粹为了好玩,变成获取收益。可是在这个商业化的市场里,对方(高效地)获得了您的信息,您获得了您应有的评价,这对双方是互利的。

对于程序员来讲,成本最低的一种做品展现方式就是把本身的代码发布到GitHub上。

名为“Open Source (Almoset) Everything”的一篇文章中,有这样一句话:“If you do it right, open sourcing code is great advertising for you and your company.”若是使用得当,开源代码是您和您的公司最好的广告

另外,将代码开源,你们看到的是项目功能,而不是代码技巧。若是不是本身须要,没有人会闲得帮其余人优化代码。若是您的想法够好,那么就会收获来自社区的感谢、帮助,以及您应有的声望。

顺便提一下,若是您是擅长设计和编程的全栈工程师,而且对本身的设计能力很是有自信,那么一样推荐Dribbble。Dribbble是设计师的舞台,它的社交性让您的做品很容易传播和收获“赞”。若是是能够实际预览的页面,您能够在贴上设计稿以后,在下面留下站点的实际地址。

二、我想推荐的第二种方案是静态页(好比GitHub Pages)

GitHub Pages是GitHub在代码托管以外额外提供的一个很是方便的功能,它容许您建立一个gh-pages的分支(若是是用户或者项目的主页,就是master分支),而后向其中提交静态资源,包括HTML、CSS、JavaScript和图片,而后就能够经过username.github.io来访问。

个人我的博客就是创建在GitHub Pages上,由于个人用户名是yuguo,因此对应的域名是http://yuguo.github.io/ 。若是您访问的话,会跳转到http://yuguo.us/,由于GitHub提供免费域名绑定功能,这简直是业界良心,因此我绑定了本身的私人域名。

GitHub Pages的初衷是为您的项目提供一个简单的介绍页,它提供了一些固定的模板。在GitHub网页上直接选择这些模板,就会在您的某个项目中建立一个gh-pages分支,而且容许您在网页上使用Markdown格式直接编辑index.html的内容。因此在那个时代,全部的GitHub Pages的设计都局限于GitHub官方提供的几套默认模板。

后来,Jekyll改变了游戏规则。Jekyll是一个使用Ruby编写的博客站点编译软件,经过命令行来操做。用户只须要编写Markdown格式的内容“源文件”,就能快速编译出一个完整的静态网站。技术的发展总会带来新的应用场景,GitHub Pages与Jekyll结合在一块儿,发生了美妙的化学反应。如今只须要把Jekyll的日志源代码Markdown推送到GitHub Pages站点,就能生成一个编译后的静态页。

Jekyll让您能够利用简单的几行代码,就新建一个站点框架。

GitHub Pages支持Jekyll编译以后,用户只需推送源代码到GitHub,GitHub Pages就能自动编译。两者产生了奇妙的化学反应,GitHub Pages的灵活性变得无限大,愈来愈多的开发者使用GitHub托管博客,而做品集也是一种很是适合Jekyll生成的项目。

除了Jekyll这种博客编译器之外,还有一些专门的静态站点编译器,好比Dexy。与Jekyll不一样的是,Dexy更擅长产品站点和文档的编译,好比能够直接引用某代码文件到HTML中。Dexy不被GitHub原生支持,因此您能够在本地编译出完整的静态页面以后,把生成的站点推送到GitHub Pages。

常常有人问我博客托管在哪一个服务器,我会告诉他们托管在GitHub Pages,虽然速度不是特别快,可是很稳定,可用性能够保证在99.99%以上。

三、突出重点

若是做品集有一些动态生成的内容的话,能够选择本身架设服务器并绑定域名,VPS就是不错的选择。VPS成本比GitHub Pages高,由于须要付费和配置环境,可是最终跟GitHub Pages的效果是相似的。

最后我想说的是,任何做品集都须要有一个重点。若是您想重点突出本身某个技能的深度,能够针对这个技能列出大量做品、项目、专栏或者本身的书。若是想突出技能的广度,光列出您的技能集是不能说服人的,还要在本身的GitHub上提交各类使用相关技能的项目。若是自由开发者想招揽一些客户的话,漂亮的过往项目是最重要的。

做品集不必定是严谨而无趣的,曾经有一个前端开发者就将本身的做品集用一个HTML5游戏包装起来,让人印象很是深入。

看到这里,您也许会说,有一些社交网络能够直接生成相关的做品集,好比LinkedIn、about.me等。但个人观点是,既然身为一个全栈工程师,那么花一点时间作一些特别的东西会更有趣,不是吗?

经过 about.me能够生成本身的做品集,截图来自about.me。

经过社会化媒体,树立起我的的品牌,即便不拿名片出去,也有人知道本身,这才是应该努力的方向。有人说过,“人到三十,不要去找工做,要让工做来找本身”,大概也是这个意思。

全栈工程师眼中的HTTP

HTTP,是Web工程师天天打交道最多的一个基本协议。不少工做流程、性能优化都围绕HTTP协议来进行,可是咱们对HTTP的理解是否全面呢?若是前端工程师和后台工程师坐在一块儿玩捉鬼游戏,他们对HTTP的描述可能会大相径庭,从这两个角色的视角看过去,HTTP呈现出大相径庭的形态。

一、HTTP简介

超文本传输协议(HyperText Transfer Protocol,HTTP)是互联网上应用最为普遍的一种网络协议。设计HTTP的最初目的是提供一种发布和接收HTML页面的方法。

OSI七层模型:

OSI模型义了整个世界计算机相互链接的标准,总共分为7层,其中最上层(也就是第7层)就是应用层,HTTP、HTTPS、FTP、TELNET、SSH、SMTP和POP3都属于应用层。这是软件工程师最关心的一层。

OSI模型越靠近底层,就越接近硬件。在HTTP协议中,并无规定必须使用它或它支持的层。事实上,HTTP能够在任何互联网协议或其余网络上实现。HTTP假定其下层协议提供可靠的传输,所以,任何可以提供这种保证的协议均可以被其使用,也就是其在TCP/IP协议族使用TCP做为其传输层。


备注:开放式系统互联通讯参考模型(Open System Interconnection Reference Model),简称为OSI模型(OSI model)

关于HTTP版本:

HTTP已经演化出了不少版本,它们中的大部分都是向下兼容的。客户端在请求的开始告诉服务器它采用的协议版本号,然后者则在响应中采用相同或者更早的协议版本。

当前应用最普遍的HTTP版本为HTTP/1.1,它自从1999年发布以来,距写做本书时已有16年的时间。比起HTTP/1,它增长了几个重要特性,好比缓存处理(在下一章介绍)和持续链接,以及其余一些性能优化。

2015年2月,HTTP/2正式发布。新的HTTP版本有一些重大更新,除了一如既往地向下兼容HTTP/1之外,还有一些优化,好比减少网络传输延迟,并简化服务器向浏览器传输内容的过程。主流的服务器(Apache、Nginx等)和浏览器(Firefox、Chrome、Safari以及iOS和Android的浏览器等)的最新版都已经支持HTTP/2,剩下的就须要网站管理员把服务器升级到最新版了。

例子:

下面是一个HTTP客户端与服务器之间会话的例子,运行于www.google.com,端口80。

客户端首先发出请求:

GET / HTTP/1.1
Host:www.google.com

上方第一行指定方法、资源路径、协议版本。固然这是一个简化后的例子,实际请求中还会有当前Google登陆帐户的cookie、HTTPS头、浏览器接受何种类型的压缩格式和UA代码等。备注:用户代理(User-Agent),是指一串字符,代表了当前用户使用什么样的代理在访问站点。浏览器是最多见的一种用户代理)

服务器随之应答:

HTTP/1.1 200 OK
Content-Length: 3059
Server: GWS/2.0
Date: Mon, 20 Apr 2015 20:30:45 GMT
Content-Type: text/html
Cache-control: private
Set-cookie: PREF=ID=73d4aef52e57bae9:TM=1042253044:LM=1042253044:S= SMCc_HRPCQiqy
X9j; expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com
Connection: keep-alive

上方代码中,在这一串HTTPS头以后,会紧跟着一个空行,而后是HTML格式的文本组成的Google主页。

介绍完关于HTTP的基本知识,咱们来分别看看前端工程师和后台工程师分别是怎样看待这个最熟悉的小伙伴的。

二、前端视角

前端工程师的职责之一是,让网站又快又好地展示在用户的浏览器中。

从这个角度来讲,对HTTP的理解是这样的:打开HttpWatch,而后随意访问一个网站,HttpWatch会按照浏览器请求的次序,列出打开这个网站的时候发生的请求细节。包括以下内容:

  • 发出的请求列表。
  • 每一个请求的开始时间。
  • 每一个请求从开始到结束花费的时间。
  • 每一个请求的类型(好比是文本、CSS、JS,仍是图片或者字体等)。
  • 每一个请求的状态码(好比是200、仍是from cache、30四、404等)。
  • 每一个请求产生的流量消耗。
  • 每一个请求gzip压缩前的体积,以及在本地gzip解压后的体积。

经过查看站点的HTTP请求信息,能够获得不少优化信息。每个前端工程师都知道的基本优化方法是:尽可能减小同一域下的HTTP请求数,以及尽可能减小每个资源的体积。(经过Chrome开发者工具中的PageSpeed工具,能够快速得到关于站点性能优化的建议)

备注1:HttpWatch是一个浏览器插件,它能够用来检测页面中全部HTTP请求。相似的工具还有Fiddler,或者各类现代浏览器的开发者工具中的“网络”标签页

备注2:gzip是一种开源的数据压缩算法,其中g表明免费的意思(gratis)。HTTP/1.1协议容许客户端选择要求从服务器下载压缩内容,gzip是绝大多数客户端和服务器都支持的压缩算法,它在压缩文本文件(好比HTML、CSS、JavaScript)时压缩效果很好。

尽可能减小同一域下的HTTP请求数:

浏览器经常限定了对同一域名发起的并发链接数的上限。IE6/7和Firefox2的设计规则是,同时只能对一个域名发起两个并发链接。新版本的各类浏览器广泛把这一上限设定为4至8个。若是浏览器须要对某个域进行更多的链接,则须要在用完了当前链接以后,重复使用或者从新创建TCP链接。

QQ空间的CSS贴图由程序自动生成,保证最佳的图片质量、最合理的图片摆放和最小的体积。

因为浏览器针对资源的域名限制并发链接数,而不是针对浏览器地址栏中的页面域名,因此不少静态资源能够放在其余域名下(不一样的子域名也被认为是不一样的域名)。若是您只有一台服务器,能够把这些不一样的域名同时指向一个IP,也就提升了对这台服务器的并发链接数限制(不过要当心服务器压力过大)。

把静态资源放在非主域名下,这种作法除了能够增长浏览器并发,还有一个好处是,减小HTTP请求中携带的没必要要的cookie数据。cookie是某些网站为了辨别用户身份而储存在用户浏览器中的数据。cookie的做用域是整个域名,也就是说若是某个cookie存放在google.com域名下,那么对于google.com域名下的全部HTTP请求头都会带上cookie数据。若是Google把全部的资源都放在google.com下,那么全部资源的请求都会带上cookie数据。对于静态资源来讲,这是毫无必要的,由于这对带宽和连接速度都形成了影响。因此咱们通常把静态资源放在单独的域名下。

除此以外,前端工程师常常作的优化是合并同一域名下的资源,好比把多个CSS合并为一个CSS,或者将图片组合为CSS贴图(这种作法被称为sprite image)。

还有一些优化建议是省掉没必要要的HTTP请求,好比内嵌小型CSS、内嵌小型JavaScript、设置缓存,以及减小重定向。这些作法虽然各不相同,可是若是了解HTTP请求的过程,就知道这些优化方法的最终目的都是最大化利用有限的请求数。

尽可能减小每个资源的体积:

咱们不光要限制请求数,还要尽可能减小每个资源的体积。由于资源的体积越大,在传输中消耗的流量就越多,等待时间也越久。

在面试应聘者的时候,我会问的一个基础题目是“经常使用的图片格式有哪些,它们的使用场景是什么”。若是能选择合适的图片格式,就可以用更小的体积,达到更好的显示效果。对图片格式的敏感,能反映出工程师对带宽和速度的不懈追求。

此外,对于比较大的文本资源,必须开启gzip压缩。由于gzip对于含有重复“单词”的文本文件,压缩率很是高,能有效提升传输过程。

对于一个CSS资源的请求耗时,我想说明两个细节:

  • 这个CSS资源请求的体积是36.4KB(这是gzip压缩过的体积),解压缩以后,CSS内容其实是263KB,能够算出压缩后体积是原来的13.8%。
  • 整个链接的创建花费了30%的时间,发出请求到等待收到第一个字节回复花费了20%的时间,下载CSS资源的内容花费了50%的时间。

若是没有设置gzip,下载这个CSS文件会须要好几倍的时间。

三、后台视角

前端工程师对HTTP的关注点在于尽可能减小同一域下的HTTP请求数,以及尽可能减小每个资源的体积。与之不一样,后台工程师对于HTTP的关注在于让服务器尽快响应请求,以及减小请求对服务器的开销。

后台工程师知道,浏览器限定对某个域的并发链接数,很大程度上是浏览器对服务器的一种保护行为。浏览器做为一种善意的客户端,为了保护服务器不被大量的并发请求弄得崩溃,才限定了对同一个域的最大并发链接数。而一些“恶意”的客户端,好比一些下载软件,它做为一个HTTP协议客户端,不考虑到服务器的压力,而发起大量的并发请求(虽然用户感受到下载速度很快),可是因为它违反了规则,因此常常被服务器端“防范”和屏蔽。

那么为何服务器对并发请求数这么敏感?

虽然服务器的多个进程看上去是在同时运行,可是对于单核CPU的架构来讲,其实是计算机系统同一段时间内,以进程的形式,将多个程序加载到存储器中,并借由时间共享,以在一个处理器上表现出同时运行的感受。因为在操做系统中,生成进程、销毁进程、进程间切换都很消耗CPU和内存,所以当负载高时,性能会明显下降。

提升服务器的请求处理能力:

在早期系统中(如Linux 2.4之前),进程是基本运做单位。在支持线程的系统(Linux2.6)中,线程才是基本的运做单位,而进程只是线程的容器。因为线程开销明显小于进程,并且部分资源还能够共享,所以效率较高。

Apache是市场份额最大的服务器,超过50%的网站运行在Apache上。Apache 经过模块化的设计来适应各类环境,其中一个模块叫作多处理模块(MPM),专门用来处理多请求的状况。Apache安装在不一样系统上的时候会调用不一样的默认MPM,咱们不用关心具体的细节,只须要了解Unix上默认的MPM是prefork。为了优化,咱们能够改为worker模式。

prefork和worker模式的最大区别就是,prefork的一个进程维持一个链接,而worker的一个线程维持一个链接。因此prefork更稳定但内存消耗也更大,worker没有那么稳定,由于不少链接的线程共享一个进程,当一个线程崩溃的时候,整个进程和全部线程一块儿死掉。可是worker的内存使用要比prefork低得多,因此很适合用在高HTTP请求的服务器上。

近年来Nginx愈来愈受到市场的青睐。在高链接并发的状况下,Nginx是Apache服务器不错的替代品或者补充:一方面是Nginx更加轻量级,占用更少的资源和内存;另外一方面是Nginx 处理请求是异步非阻塞的,而Apache 则是阻塞型的,在高并发下Nginx 能保持低资源、低消耗和高性能。

因为Apache和Nginx各有所长,因此常常的搭配是Nginx处理前端并发,Apache处理后台请求。

值得一提的是,新秀Node.js也是采用基于事件的异步非阻塞方式处理请求,因此在处理高并发请求上有自然的优点。

DDoS攻击:

DDoS是Distributed Denial of Service的缩写,DDoS攻击翻译成中文就是“分布式拒绝服务”攻击。

简单来讲,就是黑客入侵并控制了大量用户的计算机(俗称“肉鸡”),而后在这些计算机上安装了DDoS攻击软件。咱们知道浏览器做为一种“善意”的客户端,限制了HTTP并发链接数。可是DDoS就没有这样的道德准则,每个DDoS攻击客户端均可以自由设置TCP/IP并发链接数,而且链接上服务器以后,它不会立刻断开链接,而是保持这个链接一段时间,直到同时链接的数量大于最大链接数,才断开以前的链接。

就这样,攻击者经过海量的请求,让目标服务器瘫痪,没法响应正常的用户请求,以此达到攻击的效果。

对于这样的攻击,几乎没有什么特别好的防御方法。除了增长带宽和提升服务器能同时接纳的客户数,另外一种方法就是让首页静态化。DDoS攻击者喜欢攻击的页面通常是会对数据库进行写操做的页面,这样的页面没法静态化,服务器更容易宕机。DDoS攻击者通常不会攻击静态化的页面或者图片,由于静态资源对服务器压力小,并且可以部署在CDN上。

这里介绍的只是最简单的TCP/IP攻击,而DDoS是一个概称,具体来讲,有各类攻击方式,好比CC攻击、SYN攻击、NTP攻击、TCP攻击和DNS攻击等。

三、BigPipe:

前端跟后端在HTTP上也能有交集,BigPipe就是一个例子。

现有的HTTP数据请求流程是:客户端创建链接,服务器赞成链接,客户端发起请求,服务器返回数据,客户端接受并处理数据。这个处理流程有两个问题。

上图中是现有的阻塞模型,黄色表明服务器生成页面,白色表明网络传输,紫色表明浏览器渲染页面。

第一,HTTP协议的底层是TCP/IP,而TCP/IP规定3次握手才创建一次链接。每个新增的请求都要从新创建TCP/IP链接,从而消耗服务器的资源,而且浪费链接时间。对于几种不一样的服务器程序(Apache、Nginx和Node.js等),所消耗的内存和CPU资源也不太同样,可是新的链接没法避免,没有从本质上解决问题。

第二个问题是,在现有的阻塞模型中,服务器计算生成页面须要时间。等服务器彻底生成好整个页面,才开始网络传输,网络传输也须要时间。整个页面都彻底传输到浏览器中以后,在浏览器中最后渲染仍是须要时间。三者是阻塞式的,每个环节都在等上一个环节100%完成才开始。页面做为一个总体,须要完整地经历3个阶段才能出如今浏览器中,效率很低。

BigPipe是Facebook公司科学家Changhao Jiang发明的一种非阻塞式模型,这种模型能完美解决上面的两个问题。

通俗来解释,BigPipe首先把HTML页面分为不少部分,而后在服务器和浏览器之间创建一条管道(BigPipe就是“大管道”的意思),HTML的不一样部分能够源源不断地从服务器传输到浏览器。BigPipe首先输送的内容是框架性HTML结构,这个框架结构可能会定义每一个Pagelet模块的位置和宽高,可是这些pagelet都是空的,就像只有钢筋混泥土骨架的毛坯房。

BigPipe页面的渲染流程:

服务器传输完框架性HTML结构以后,对浏览器说:“我这个请求还没结束,咱们保持这个链接不要断开,不过您能够先用我给您的这部分来渲染。”

因此浏览器就开始渲染这个“不完整的HTML”,毛坯房页面很快出如今用户眼前,具体的页面模块都显示“正在加载”。

接下来管道里源源不断地传输过来不少模块,这时候最开始加载在服务器中的JS代码开始工做,它会负责把每个模块依次渲染到页面上。

在用户的感知上,页面很是快地出如今眼前,可是全部的模块都显示正在加载中,而后主要的区域(好比重要的用户动态)优先出现,接下来是logo、边栏和各类挂件等。

为何BigPipe可以让服务器对浏览器说“我这个请求还没结束,咱们保持这个链接不要断开”呢?答案是HTTP1.1的分块传输编码。

HTTP 1.1引入分块传输编码,容许服务器为动态生成的内容维持HTTP持久连接。若是一个HTTP消息(请求消息或应答消息)的Transfer-Encoding消息头的值为chunked,那么消息体由数量不肯定的块组成——也就是说想发送多少块就发送多少块——并以最后一个大小为0的块为结束。

实现这个架构须要深入理解HTTP 1.1的规则,并且要有前端的知识。在我看来,这就是一个极佳的全栈工程师改变世界的例子。

截止写书时,Chrome、Safari和Opera已经支持HTTP/2并默认开启,它容许服务器向浏览器“推送”内容。也就是说,返回的条目数能够比请求的条目数多,这样服务器能够在一开始就推送全部它认为浏览器“应该须要”的资源,而不须要浏览器接受并解析完HTML页面才开始请求下载CSS、JavaScript等。并且,后面的请求能够复用以前已经创建的底层链接。

延伸阅读
1.《图解HTTP》(日)上野宣,人民邮电出版社
2.《高性能网站建设进阶指南》(美)Steve Souders,电子工业出版社

高性能网站的关键:缓存

Phil Karlton说过:计算机科学中最无奈的两件事是缓存失效和命名。这是多是由于,复杂性理论方面的难题,可能最终仍是有解的。而缓存失效是分布式系统中最多见,也几乎没有最优解决方案的难题。

缓存对于站点性能起到举足轻重的做用,不少时候,优化算法和压缩图片带来的优化效果可能远远不如优化缓存。

计算机系统中的缓存有这样几种功效:(以图书为例)

  • 存储频繁访问的数据(这里的数据是图书)。
  • 内存缓存减小磁盘I/O(不用到6楼去找书)。
  • 保存耗时的操做,以便下次使用(找书和整理书是耗时的操做)。

下面我来谈谈在一个Web站点中,它的数据流从服务器端到浏览器端,哪些地方能够使用缓存来优化。

一、服务器缓存

对于一些计算量大的Web服务、服务器内存或CPU等性能很差,或者像一些独立开发者跟其余人共享虚拟服务器(所以只能获得部份内存和CPU)的时候,服务器的计算时间可能占整个页面响应时间的很大一部分。这种状况下,优化服务器端的缓存就尤其重要了。

基本的数据库查询缓存:

咱们从服务器到客户端,依次来说解缓存的做用,首先从数据库开始。

对于大型网站来讲,数据库里的数据量每每是很是大的,而对于数据的查询又是比较耗时的操做,因此咱们能够开启MySQL查询缓存来提升速度,而且减小系统压力。MySQL默认不开启查询缓存,但咱们能够经过修改MySQL安装目录中的my.ini来设置查询缓存。设置的时候能够根据实际状况配置缓冲区大小、单个查询的缓冲区大小等。

咱们从服务器到客户端,依次来说解缓存的做用,首先从数据库开始。
对于大型网站来讲,数据库里的数据量每每是很是大的,而对于数据的查询又是比较耗时的操做,因此咱们能够开启MySQL查询缓存来提升速度,而且减小系统压力。MySQL默认不开启查询缓存,但咱们能够经过修改MySQL安装目录中的my.ini来设置查询缓存。设置的时候能够根据实际状况配置缓冲区大小、单个查询的缓冲区大小等。

若是您但愿优化MySQL服务器的查询性能和速度,能够在MySQL配置中增长这两项:

query_cache_size=SIZE
query_cache_type=OPTION

上方第一行中,SIZE是指为查询缓存开辟多大的空间。默认是0,也就是禁用查询缓存。

设置查询缓存的类型,可选的值有如下这三种:

  • 0:设置查询缓存的类型,可选的值有如下这三种。
  • 1:全部的缓存结果都缓存起来,除非查询命令以SELECT S_NO_CACHE开始。
  • 2:只缓存查询命令以SELECT SQL_CACHE开始的查询结果。

具体的设置方法不是咱们讨论的重点,重点是要了解适合设置查询缓存的场景。由于每一次select查询的结果都会被缓存起来,若是数据库数据没有发生变化(没有运行INSERT/UPDATE/DELETE/MERGE等操做的话,数据库就不会变化),下一次查询就会直接从缓存里返回数据。可是若是数据库发生了变化,那么全部与该表有关的查询缓存所有失效。

因此,对于查询操做远远多于修改操做的数据库,开启数据库查询缓存是颇有益的;可是对于修改操做不少的数据库,因为缓存常常会失效,就起不到加速的效果。不只如此,因为数据库要花费时间写缓存,因此实际上速度更慢了。

这个问题就是“缓存命中率不高”,因此配置缓存以后第一件事就是查询命中率,若是命中率低,不如不作缓存。

这里须要注意的是,两次SQL文本必须彻底相同。若是先后两次查询使用了不一样的查询条件,就会从新查询。如第一次查询时没有输入where条件语句,后来发现数据量过多,因而利用where条件过滤查询的结果,此时即便最后的查询结果是相同的,系统仍然是从数据文件中获取数据,而不是从缓存结果中。再如,select后面所使用的字段名称也必须是相同的。若是查询语句中有一个字段名称不一样,或者先后两次查询所使用的字段数量不一样,都会被系统认为是不一样的SQL语句,须要从新解析并查询。

扩展数据库缓存:memcached:

MySQL的自带缓存有一个问题,它的缓存池大小是在MySQL所在服务器上开辟,能使用的内存空间是有限的。在比较大型的网站中,缓存就不够用了,这时候须要使用服务器集群来实现数据库缓存。
memcached应运而生,它是一个高性能分布式内存对象缓存系统,用于减轻数据库负载。它经过在内存中缓存数据和对象来减小读取数据库的次数,从而提升动态、数据库驱动网站的速度。memcached能够与数据库查询缓存配合使用,查询流程以下图所示。
您也许发现了数据库查询缓存的一个设计原则:其缓存失效设计是很粗糙的。只要某个表发生了更新操做,全部对这个表的查询都会失效。这是为了保证数据的时效性而下降了数据的命中率。

memcached通常查询流程:

memcached的缓存失效与此不一样,它采用的是按时间来过时的设计。memcached至关于应用程序和数据库之间的中间层,经过网络API设置和调用。memcached储存的是名值对,并且设置了一个过时时间,只要过时时间没有到,应用程序就会从memcached中获取数据。这时候即便发生了数据库更新操做,缓存的查询结果也仍然是以前保存的旧数据,直到设置的时间过时。这样提升了缓存的性能,带来的影响就是,数据多是“不新鲜”的。

memcached支持集群,并且有诸多优势,因此能够有效利用多台机器的内存,提升命中率。

若是您使用WordPress,那么开启memcached是很简单的。在服务器安装好memcached后,再去WordPress的插件列表里,搜索cache或memcached之类的关键词,能够找到不少相关的插件。根听说明安装好这些插件后,通常就能够无缝衔接缓存软件和WordPress了。

可是memcached也不是老是那么有效,由于若是只有一台服务器,就用不到它的服务器集群的优点,反而让系统更慢。

再加一层文件缓存:

除了能够将数据库查询结果缓存在内存中,还能够将被频繁造访的数据缓存在文件中。文件I/O比起内存有如下几个好处:

  • 硬盘容量比内存大,因此能够缓存更多数据。
  • 数据更安全,断电以后数据还在。
  • 易于扩展,硬盘不够用的时候还能够添加硬盘。

可是文件缓存没有内存缓存快,只能做为内存缓存的补充,在获取数据时,先从最快的地方读取,若是没有就继续日后找。查找优先级为:内存缓存→文件缓存→数据库。

PHP框架CodeIgniter的数据库缓存类,容许您把数据库查询结果保存在文本文件中,以减小数据库访问。

若是激活了CodeIgniter的缓存特性,那么在某页面首次被加载时,数据库查询的结果对象将会被序列化,并保存在服务器的文本文件中。而此页面再次被加载时,缓存文件将会替代数据库查询。如此,在被缓存的页面中,您的数据库使用率会降至零。

只有读类型查询会被缓存,由于只有这种查询会产生结果集。 而写类型查询,由于不会产生结果集,故缓存系统不对之进行缓存。

缓存文件不会过时,除非您删掉它,不然任何被缓存了的查询会一直存在。缓存系统容许您按页面清除,或把全部缓存都清除掉。通常来讲,您能够在某些事件(好比向数据库添加了数据)发生时用特定的函数来清除缓存。

静态化:

有两种静态化的方法,其中一种是相似WordPress的静态化插件,安装很简单,每次有新文章就自动生成静态页面。这种方法仍是将数据保存在数据库中,只是会读取数据库以后生成一些静态页。

这一种方法的原理跟文件缓存很类似。静态化页面以后,服务器每次接收到对这个页面的请求,都会直接给出这个页面的静态文件,因此就省略了后台运算和数据库查询。优势是能大大加快访问速度,同时减轻服务器处理大量请求的运算压力。在前面咱们也说过,由于静态化的页面对服务器的压力小,能有效承担巨大的访问量,因此还能抵御DDoS攻击。

另外一种方法就是直接抛弃数据库。好比有一些博客做者会用Jekyll系统来写博客,将整个博客站点静态化。彻底抛弃数据库的好处是,能够将生成的静态网页直接托管在静态资源站点,好比GitHub Pages或者Amazon S3,而不用操心数据库服务器的问题,不光整个系统稳定不少,费用上也更加低廉(GitHub更是彻底免费的,并且提交Markdown源代码后可让它在服务器端生成站点)。

对于彻底静态化的站点,能够采用第三方插件来支持用户生成内容。好比Disqus就是一个第三方的评论插件,经过JavaScript代码插入到静态页中。用户的评论数据都储存在Disqus的服务器上,对咱们是透明的,很方便。

值得一提的是,咱们从URL是没法判断后台是否真正静态化的。对于一个URL为/blog/index.html的页面,也有多是PHP页面经过UrlRewrite来改写的。经过Apache或者Nginx能够将一个对静态资源的请求(index.html)转给一个动态应用程序(好比PHP)来处理。

二、浏览器缓存

前面说的缓存都是发生在服务器端的,适用的状况是那些服务器性能为主要瓶颈的场合,经过缓存来将一个长的计算时间跳过,起到提升性能的做用。而当浏览器访问一个站点的时候,网络链接是主要瓶颈,咱们能够经过设置浏览器缓存来跳过HTTP请求。

若是在浏览器设置缓存,一般有两个主要做用。

  • 对用户来讲,减小请求能够更快地加载页面,节省流量。若是用户是在手机上用3G或4G访问页面,这一点就很关键。
  • 对网站来讲,减小带宽压力和费用。假设有1亿的访问量,若是能把大小为10KB的CSS缓存起来,能够节省不小的开支。

对于浏览器来讲,如何缓存一个资源是服务器端制定的策略,本身只是根据服务器的“指令”来执行而已。服务器的“指令”就是前面介绍过的HTTPS头。

服务器经过对每一个资源的HTTP响应头设置属性和值,来发出本身的缓存指令。主要会有两种缓存指令,咱们以一个图片image.png为例。

第一种:Expires

对于一个普通的请求,服务器可能会说:“您拿着这个资源吧,直到2020年您都别再向我要了。”

Expires: Thu, 15 Apr 2020 20:00:00 GMT

那么浏览器若是再次命中对这个资源的需求,就不会再去发起HTTP请求,而是直接从缓存(在硬盘中)读取。

200(from cache)

这种缓存是最快的,由于没有任何HTTP请求发生。当用户须要这个资源,浏览器就直接从缓存中读取,再也不须要询问服务器端的意见(服务器端甚至不知道您在浏览image.png)。因此HttpWatch是推荐对全部的静态资源都设置Expires。


第二种:Last-Modified

对于一些有可能过时的请求,服务器可能会比较慎重地说:“您拿着这个资源吧,这个资源上次修改时间是2014年3月1日,若是用户要用,您就问问我改变了没,或者直到2014年12月31日文件自动过时。”

Last-Modified: Tue, 01 Mar 2015 03:42:36 GMT

那么浏览器若是在2015年3月10日访问了image.png,就会将这个图缓存在硬盘中。过了几天,浏览器又命中了对这个资源的需求,就会发起一个HTTP请求。

在HTTPS头中,浏览器问:“我这里有个image.png,它的最后修改时间是2015年3月1日,如今用户又要了,您那个文件有过更新没?”

If-Modified-Since:  Tue, 01 Mar 2015 03:42:36 GMT

服务器若是回答:“没更新,您直接用吧。”这个回答中就不须要带上请求的文件体了,只用一个HTTPS头表示文件未更新便可304就是这句话的代号,表明资源未修改的意思

304

另外一种状况是,image.png后来更新过了,服务器就会说:“更新过了,我如今给您一个新的图片。”而后就正常返回请求文件(200),而且把整个图片做为HTTP正文发送给浏览器。

经过这种缓存方式,不管资源是否发生了更新,仍然至少会发生一来一去HTTPS头的传输和接收,因此速度比不上Expires。

从服务器端的角度来看,有时候咱们并不但愿对静态资源的请求中大部分都返回304。由于这可能说明咱们的不少用户都在频繁访问站点,并且咱们的资源不多更新,就好像它们一直问“资源修改了吗?”,咱们一直回答“没有修改”。这里能够使用Expires来设置过时时间,这样它们就不会“烦咱们”了。对于服务器管理员来讲,保持304为一个合理的比例便可。咱们能够经过查看服务器的log,查看304响应与200响应的比例,来作出一个合理的缓存策略。

Restful Web API:

表征性状态传输(Representational State Transfer,REST)是Roy Fielding博士在2000年发表的博士论文中提出来的一种软件架构风格。

目前,在3种主流的Web服务实现方案中,由于REST模式最简洁,也能合理地利用HTTP操做的语义,因此愈来愈多的Web服务开始采用REST风格设计和实现。好比,Amazon.com提供接近REST风格的Web服务进行图书查找。
Restful 的目的是定义如何正确地使用Web标准,优雅地使用HTTP自己的特性。原则上是对资源、集合、服务(URL)、get、post、put、delete(操做)的合理使用。

举例来讲,若是请求一个资源,可是服务器上没有这个资源,这时候就应该对HTTPS头设置404,而不是设置200。

HTTP 1.1加入的Cache-Control:

其实Expires跟Last-Modified已经能知足咱们绝大多数需求了,可是HTTP1.1又新增了一个属性Cache-Control,它的功能跟Expires相似,不过有更多的选项。

Expires的值是一个日期,表示某日期以前都再也不询问。

Cache-Control的值是:max-age=7776000,max-age的单位是秒,从浏览器接收到文件以后开始计时。
若是您不知道怎么判断,就只用Expires,或者(为了兼容某些老客户端)同时设置Expires和Last-Modified。

若是topMenu.js设置了Expires直到2020年都不过时,那么怎么让客户端知道咱们修改了topMenu.js呢?

答案是修改Query String。按照规范,Query String是URL中的一个部分,好比http://server/program/path/?query_string问号后面的字符串就是Query String。

按照HTTP规范,若是修改了请求资源的Query String,就应该被视为一个新的文件。

这个Query String能够被服务器端CGI或者应用程序理解,并且能够设置多个名值对(好比?foo=1&bar=2)。与缓存相关的一点是,若是Query String发生了改变,则被视为URL发生了改变。这时候,浏览器会认为这是一个新的资源。而对于服务器而言,若是有CGI或者应用程序捕捉或处理Query String,就会去处理,若是没有,就简单地忽略Query String,直接返回资源

下面是推荐的浏览器缓存设置最佳实践

  • 对于动态生成的HTML页面使用HTTPS头:Cache-Control: no-cache。
  • 对于静态HTML页面使用HTTPS头:Last-Modified。
  • 其余全部的文件类型都设置Expires头,而且在文件内容有所修改的时候修改Query String。

浏览器缓存的现实世界:

服务器端能够设置缓存规则,告诉浏览器应该如何遵循和实现,但在服务器不能掌控的地方也许会出现一些意外:

  • 缓存会被挤出。
  • 文件有可能在运营商服务器上被劫持。

所谓缓存被挤出,是由于浏览器的缓存空间是有限的,全部网站但愿缓存的文件都塞在用户硬盘,造成一个先进先出的队列。因此即便设置了20年的缓存时间,也基本上不能保证有那么久的生命期,而会在某一个时间点被其余网站设置的缓存挤出硬盘。并且用户也有可能主动清除浏览器缓存,某些系统清理软件也可能清理浏览器缓存。这一点无可厚非,咱们从技术层面上也没法解决,大不了让用户从新加载一下资源就行了。

第二个问题是,用户的宽带运营商为了提升速度,可能会在本身某节点服务器上缓存您的文件(好比style.css?v1),好处是当用户请求这个文件的时候,运营商无需来您的服务器上请求文件,而本身直接就给出了。

问题来了,若是您的Query String更新了(style.css?v2),按照HTTP规范,这理应被视为一个新的文件,可是运营商仍然可能会拿本身节点的缓存,而不是遵循规范。有点可恶对不对?这就是咱们在用户量极大的状况下侦测到的状况,虽不太常见,可是有可能发生。因此,为了保证更新的文件下发到全部的用户,咱们会使用更增强硬的方法:修改文件名,而不是仅仅修改Query String。

这种流程比较复杂,须要同时修改文件名和引用它的文档里的文件名。在QQ空间,咱们使用自动化的方式来生成新文件名并修改HTML中的引用。

修改资源的文件名,比修改后缀更可靠:

结论:

结合上面的分析,这是QQ空间静态资源在浏览器端使用的缓存策略

  • 对于动态生成的HTML页面使用HTTPS头:Cache-Control: no-cache。
  • 对于静态HTML页面使用HTTPS头:Last-Modified。
  • 其余全部的文件类型都设置Cache-Control头,而且在文件内容有所修改的时候修改文件名

以上就是在Web栈流程中比较常见的缓存方面的问题。缓存可否得到性能增益,取决于不少因素。一些因素是关于您的服务器压力、数据库使用状况和提供的服务类型;另外一些因素是关于您的用户如何访问您的网站,以及他们的网络环境。咱们做为工程师,只能不断优化和调整策略,往更优的方向去优化。

延伸阅读:

  • 《网站性能监测与优化》(美)Alistair Croll / Sean Power,人民邮电出版社

大前端

整体来说,在计算机程序和系统中,“前端”(front-end)做用于采集和显示信息,“后端”(back-end)进行处理。Web应用程序和桌面应用程序的界面样式、视觉呈现、用户交互属于前端。

前端工程师:

咱们最多见的Web栈中靠近用户输入的那一部分,也就是靠近浏览器的部分,属于前端的范畴。具体来讲,浏览器中发生的一切和服务器中涉及输入输出的这一部分,都属于前端工程师的工做职责。

前端工程师主要使用的语言是HTML、CSS和JavaScript,有时候会写一些服务器的页面模板语言(好比PHP)。

从2010年直到今天,可以明显感觉到的一点是,前端发展到今天,已经发生了很大的变化。

在2010年,前端开发岗位必须掌握的一项能力是对IE6和IE7的兼容性。工程师须要手动把图片拼接成CSS贴图,CSS也不经压缩就发布出去。渐渐地,IE用户愈来愈少,因此,咱们如今已经不把IE7如下的浏览器兼容性做为招聘要求。不过因为移动设备的爆炸性增加,如今前端开发岗位开始要求有移动端页面开发的经验,或者熟悉响应式页面开发。Grunt等发布流程的成熟,也让前端工程师免除了不少枯燥的工做。

总之,变化一直都在发生,这是一个须要终身学习的行业。不夸张地说,若是我一个月没有关注行业动态,就会发现本身已经错过了不少新技术。

一、知识体系

前端工程师须要涉及的知识面比较广,我大概对个人我的偏好作一下梳理。

在招聘初级工程师的时候,我通常会考察应聘者对如下知识的掌握程度:

  • 对浏览器兼容性的了解
  • 对HTML/CSS/JavaScript语法和原理的理解
  • 对编辑器和插件的熟悉程度
  • 对调试工具的了解程度
  • 对版本管理软件的熟悉和应用经验
  • 对前端库/框架的使用
  • 标准/规范

招聘中级工程师时,我通常考察应聘者对如下知识的掌握程度:

  • 对代码质量、代码规范的理解。
  • 对JavaScript单元测试的熟悉。
  • 对性能优化的应用和理解。
  • 对SEO的应用和理解。
  • 代码部署。
  • 移动Web。

高级工程师,除了上面的考察点之外,还会问这些方面的经验:

  • 代码架构。
  • 安全。
  • 对自动化测试的理解

越接近高级工程师,越考察对某个点的本质理解,以及在项目和团队中的引导做用,而不是对某工具的使用经验。对于上面的这些技术方向,我不会在本章中一一介绍,一个缘由是篇幅所限,另外一个缘由是有一些方向并不仅是前端工程师会遇到,而是跟后台工程师的知识体系相通。好比代码质量、规范、单元测试、性能、版本管理……对于这些话题,会在单独的章节中详细说明。

易于上手,难于精通:

不一样于某些“难于上手、难于精通”的职业,前端这一岗位就像暴雪公司的游戏设计同样:“易于上手、难于精通”。

举例而言,HTML的全称是超文本标记语言,超文本的意思是说,比起咱们在记事本中写的普通文本多了一些语义化的信息,好比连接、加粗和标题等。标记语言更加简单,就是用一些标签把普通文本标记起来。标记语言没有逻辑,只是描述性的标签,因此算不上是程序语言。程序语言有的循环判断等逻辑,HTML都没有。这就是它易于上手的地方。
这是一段最简单的HTML代码,但它也是一个完整的页面:

<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<p>Hello World!</p>
</body>
</html>

可是HTML又很难。前端工程师对照设计稿还原出页面以后,还要考虑机器是如何理解这个页面的。对于用户而言,视觉上加大加粗就是一个标题;可是对于机器,好比搜索引擎或者盲人使用的读屏软件,是否能理解它是一句标题?这须要咱们使用语义化的标签。

有的时候,为了完美地实现设计稿还原,一个视觉上看上去像一个下拉选择器的输入框,咱们会使用a或者span标签加上一些隐藏的列表模块来实现。当用户点击标签的时候,就用JavaScript让隐藏的列表模块滑出来。

使用这种方法,咱们能够快速地建立出在各浏览器中表现一致的按钮,并且能够轻松地自定义样式,免受各类bug困扰,但同时这种“黑”科技也带来了可访问性问题。具体来说,如何让盲人知道这是一个下拉选择器?这时候能够使用role属性来加强这个文档对象模型(DDM)的语义。这须要咱们了解WAI-ARIA的知识。

HTML虽然是比较严格和简单的语言,但有时在写代码和阅读代码的时候效率比较低。John Gruber为了改变这种现状,在2004年发明了一种纯文本格式语法Markdown13。这种语法的目标是“提供一种读起来简单,写起来也简单的语法,而且若是您乐意的话,也能够随时转化成合法的HTML”。

不少书就是使用Markdown语言来编写的。它比Word更好用的地方是,写做者无需关注字号和样式,只须要设置“一级标题”“二级标题”“三级标题”“加粗”“引用”等语义便可。具体的样式能够在美编阶段统一调整。更美好的是,它不会产生任何无心义的标签,而Word常常产生无心义的标签。

Markdown比HTML更易读易写,可是浏览器是不会渲染的,那么就必须进行Markdown到HTML的转化。开发者能够选择两种转化方式。一种是在开发环境把Markdown转化成HTML,再发布到服务器上,或者直接由服务器自动转化成HTML文件(Jekyll支持这两种转化方式),总之浏览器获得的已是一个正常的HTML页面了。

第二种方式是把包含Markdown代码的HTML页面发布到服务器上,而后当浏览器下载HTML页面以后,页面中的JavaScript代码开始把Markdown解析成对应的HTML代码。通常推荐第一种方式,由于不依赖浏览器端的JavaScript运行,可用性更好,也对SEO更有帮助。

有些在线工具能够实时把Markdown转化成HTML,好比markdownlivepreview.com。

也有人想出另外一种方法,发明了zen-coding来加快前端工程师的编码速度。zen-coding如今更名为emmet,在各大编辑器中都有插件。

前端技术的“易于上手”致使它在某些技术人员那里不受待见。他们认为HTML与CSS根本都不是程序语言,甚至认为JavaScript是一种功能不全的玩具型语言。因此直到我几年前毕业的时候,大学都没有前端相关的课程和专业。而市场对前端工程师的需求又很大,学校的输出跟市场的要求没有对接上,因此每每出现学生找不到工做,公司又招不到人的现状。

我并非建议直接开设“前端开发”专业,由于前端开发也是软件开发的一个分支,与服务器开发和其余软件开发共享一些基础课程,是全部工程师都须要学习的,好比项目管理、数据库、软件开发流程和C++等。个人建议是,在大三或者大四的方向课程设计上,或者选修课设计上增长与时俱进的前端开发课程,使用业界最新的编程语言去教学,这样对毕业生、对用人单位都是好事。

框架vs库:

框架(framework)和库(library)的区别是什么?其实这两个词在不一样的语境下,有时候是能够相互替代的。可是严格来讲,框架应该是比库更普遍的概念。

一个库是一系列对象、方法等代码,您的应用程序能够把这个库“连接”进来。这个库起到了重用代码的做用,为您省下了重写这部分代码的工做量。

而一个框架是一个软件系统中可重用的一部分。它可能包含子程序、库、胶水语言、图片等一些“资源”,这些资源一块儿组成了软件项目。框架不像库,可能包含多种语言,某些功能可能经过API的方式让主程序调用。

因此框架是一个更加灵活和宽松的名词,在具体的情景中,它可能指一个库、多个库、脚本代码,或者多个可单独运行的子程序的集合。

之前端来举例,jQuery就是一个库。jQuery是纯粹的JavaScript代码,它的目标是使用更少的代码处理DOM相关操做。当咱们使用jQuery时,至关于引入了新的对象和方法,能够利用jQuery定义的代码,不须要重写这部分功能。

而Sencha公司的ExtJS是一个框架。首先ExtJS不只包含JavaScript代码,还包含了CSS和图片。其次它的功能是方便开发者搭建可交互的Web应用程序,里面有一些完整功能的模块,好比绘制可交互的图表。因此ExtJS是一个框架。

做为一个前端工程师,面对的框架和库层出不穷,很容易陷入迷茫,到底应该使用哪一种?一个常见的误区是,存在某个强大的“终极方案”,能够解决一切Web应用程序开发的问题。常常有一些人请我推荐一些好用的前端框架,我不知道如何回答。

每一年都会有不少新的框架发布,它们的做者并非无聊想要新写一个框架,而是为了解决一个新的问题。好比jQuery的优点在于方便地操做Web界面(DOM)。而Angular并非“更好的jQuery”,而是提出一种新的解决问题的思路:经过数据绑定,让开发者直接修改数据模型,而不用关心界面(DOM)更新。GASP库发现jQuery动画慢的问题,就重点优化JavaScript动画部分,它号称动画速度比jQuery快20倍,并且能开启硬件加速,在某些状况下比CSS动画性能还要好。

所以,不要迷信大框架,有时候越是有名的框架,越须要知足更多人的需求,会封装不少您可能不须要的资源进去。对于您来讲,可能只须要一小部分功能,可是引入了一个庞大的库。我经常看到,在某些人的简单的我的博客中引入了一些庞然大物,可是其实没有必要。这对应聘者来讲,是减分的。

在出现一些热门框架时,建议开发者先去了解框架的建立初衷,合理使用,而不是盲目收集。

二、岗位细分

咱们知道前端的领域很广,因此有些大公司对它进行了更进一步的细分,好比腾讯的两个职位“前端工程师”和“UI工程师(UI Engineer)”。

UI工程师 vs 前端工程师:

在国外,UI工程师是一个比较普及的岗位。以Google为例,一个叫Front End Software Engineer,属于软件工程部,另外一个叫UX Engineer, Front End,有点相似Front End下的一个子项,属于用户体验设计部。

从使用语言的角度来分,UI工程师只负责HTML/CSS,前端工程师只负责JavaScript,这是一种简化问题的解释方法。但我认为这两种职位的区分的重点并非两者语言不同,而是责任和关注点不同。UI工程师更关注视觉上和交互上的体验,而前端工程师更关注逻辑和数据方面的体验,两者是上下游合做的关系

同时双方的工做也有一些交集,好比UI工程师也会负责一些交互或者动画相关的JavaScript,前端工程师也要熟悉HTML标签才能用JavaScript去操做。双方都必须对对方的知识有足够的理解,合做才能进行下去。两种职位的目标是一致的:给用户提供更好的体验。

腾讯的UI工程师曾经叫“网页重构工程师”。这个名称来自一本颇有名的床头技术杂文书《网站重构》(Designing with Web Standards),做者是世界上最有名的网站设计师之一,Zeldman,J.(泽尔德曼)。这本书的主要观点是,用Web标准来“重构”您的网站,而不要用之前的非标准的方式来作网站。

用一个我我的不太喜欢的大白话来讲就是:不要用table标签布局,而要用DIV+CSS。我不喜欢这句话的缘由是它不严谨,容易在纠正一个过往的错误的时候“用力过猛”。矫枉过正的后果是,如今有一些人只要看到table标签就以为是非语义化的,喜欢用DIV搞定一切。可是table并不邪恶。table用做数据表格的时候,是很是正确的。有些人在布局这一用途上用DIV干掉了table,却开始对DIV上瘾。

2003年《Designing with Web Standards》出版以前,全世界的设计师尚未Web标准的理念,都在用table标签布局,由于table可让页面规整。这本书普及了Web标准的理念,在那以后,设计师开始使用语义化的HTML和灵活的CSS来设计页面。2005年此书中文版出版后,也带来了全新的Web标准的理念。我第一次看这本书是2009年,那时我还在读大三,读完这本书以后几个月就签约到了腾讯ISD部门,职位是“网站重构工程师”,因此我对这本书有特别的感情。备注:简历中不要出现“DIV+CSS”这样的字眼,会减分;也不要出现Dreamweaver,由于Dreamweaver是老式的“所见即所得”编辑器的表明

不说远了,《网站重构》这本书的中文名是一个意译,代表在用Web标准来设计的过程当中,咱们要推倒之前的网站,“重构”一个新的网站。这也是“重构”这个词原本的意思——从新构造咱们的代码。可是这个词被用在了一个但愿能推动Web标准的职位上,给网站重构工程师这个职位带来了额外的风险:含糊不清。可能有人会认为这个职位一天到晚都在重写代码吧。这本书的译者之一王宗义在知乎上说:

“我是翻译《网站重构》一书的译者之一,当时咱们3个译者各自起了不一样的名字,这个名字是我起的,由于译者3我的中我是作程序开发的,借用了软件开发中的著名书籍《Refactoring》的中文翻译《重构》来影射当时国内网站须要用相似的方式来改变网站底层的本质。当时咱们几个也有争议,不过阿捷和dodo最终接受了个人想法。就是没想到后来居然可以成为Web前端的一个重要词汇。”

除了对岗位名字和职责的困惑,还有一个我经常被问到的问题是“重构只会HTML和CSS,有什么前途?”

个人回答是,首先重构不该该只会HTML和CSS。在前面“知识体系”一节中的全部知识点,重构工程师都须要了解和熟悉。特别是在性能、动画、SEO、可用性和移动等方面要有本身的优点。

不过,为了更好地跟国际接轨,同时避免“网页重构”与“代码重构”的混淆,咱们在2015年推进了职位改名的行动,如今咱们已经正式改名为“UI工程师”。

对于UI工程师来讲,UI开发的平台可能不会一直是浏览器,还有多是原生App。备注:你们都喜欢把它读成“诶批批”,就像一个缩写。但App不是一个缩写,而是对Application简写,因此正确地读法是[æp]。

App UI工程师:

iOS跟Android上的软件跟桌面软件,或者服务器端软件同样,都叫Application。不过因为苹果App Store的普及,加上中国全部作移动端软件的团队的推广,如今你们都默认App就是指手机端上软件。本书遵循约定俗成的规范,提到App时,就是指智能手机上的软件。

App的市场在短短几年时间内就从无到有,它的发展速度比传统互联网要快得多。就像最开始的网站只须要一个开发者,而如今须要不少工程师合力合做,App开发也在经历这样的变化。

传统的iOS开发流程是这样的:首先,设计师设计完PSD稿,作好标注,切出各类状态的图片,交给开发人员;其次,开发人员拿到各类切片,根据标注设计稿和切片,实现界面以及逻辑功能的开发。

从工程质量和进度角度讲,有这样几个问题:

  • 开发周期长

由于一个工程师要同时完成界面和逻辑的部分,因此两者只能按队列进行,须要较长的开发周期。若是发生了设计或者逻辑的变动,则会须要更多的时间去修改。

  • 代码耦合强

一我的去实现一个模块的时候,代码中不免会出现耦合比较强的状况,没有很好地MVC分离,关于视图的代码跟关于控制器的代码都混在一块儿,这为后期的修改带来了隐患。

  • 沟通成本高

由于设计师与开发人员之间经过标注和切片来沟通,可是标注自己就很不可靠,一个标注了全部间距的设计稿每每并非咱们须要的,工程师须要的是一些常量,以及当界面发生变化时的“规律”。

  • 设计还原质量低

传统的工程师在逻辑、健壮和成本上有很是敏锐的把控能力,可是在UI开发和用户体验方面的经验就略差一些。好比,标注了按钮与按钮之间的距离是20px并没有太大参考性,由于按钮周围可能会有空白区域。若是开发人员迷信标注上的数字,在代码中直接写标注的数字,成品就会和设计稿效果出现很大的误差。并且因为设计师和开发人员之间沟通不顺畅、开发时间紧急和代码耦合的问题,致使设计还原的质量低。

在时间紧急时,工程师更注重性能问题和数据逻辑是否正确,而不太关注“按钮尺寸是否正确”这样的问题。

因此我但愿推动的流程是从Web开发中借鉴经验,让咱们本来擅长用户体验的Web UI工程师来进行App UI开发,而原来的App开发人员负责除了UI以外的部分。优化以后的整个流程大概是这样的:

  • UI工程师拿到需求单和设计稿以后,跟App开发人员一块儿沟通,明确哪些UI是此次须要从新作,哪些能够复用已有的UI组件。由于UI工程师可能刚接触到这个项目,须要清楚沟通,避免重复工做,也能够开始考虑如何创建公共UI组件。
  • 若是是对于已有界面的修改,而无需改变逻辑的,UI工程师直接修改界面代码和图片资源,而后提交测试。
  • 对于新增的UI和逻辑,UI工程师与App开发人员约定双方沟通的API,而后本身在视图中实现API的细节,而且在控制器中使用示例来告诉App开发人员如何使用API。App开发人员则同时启动工做,关注后台和App逻辑,涉及视觉层就调用约定的API。
  • 界面和逻辑一块儿在测试环境上联调。

理想状态下,这个方案能解决上面的全部问题。不过有些同窗可能会内心犯嘀咕,Android原生App开发须要有Java的知识,iOS开发须要熟悉Objective-C或者Swift语言,这些都不在前端工程师的技能树里面,如何能承担这部分的工做?
这就是我下一章要讲的:向移动端转型。

延伸阅读:

  • 《精通CSS:高级Web标准解决方案(第2版)》(英)Andy Budd/Simon Collison/Cameron Moll,人民邮电出版社
  • 《单页Web应用:JavaScript从前端到后端》(美)Michael S. Mikowski /Josh C. Powell,人民邮电出版社

持续更新...

个人公众号

想学习代码以外的软技能?不妨关注个人微信公众号:生命团队(id:vitateam)。

扫一扫,你将发现另外一个全新的世界,而这将是一场美丽的意外:

相关文章
相关标签/搜索