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

Posted 起舞弄清影

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《Web全栈工程师的自我修养》读书笔记(转载)相关的知识,希望对你有一定的参考价值。

【声明】

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

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

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

【正文】

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

【目录】

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

什么是全栈工程师

全栈工程师(Full-Stack Engineer):一个能处理数据库、服务器、系统工程和客户端的所有工作的工程师。根据项目的不同,客户需要的可能是移动栈、Web栈,或者原生应用程序栈。

全栈:表示为了完成一个项目,所需要的一系列技术的集合。应该从能力和思维方式两方面,来判定一个人是否是一个合格的全栈工程师。简单来说*全栈工程师就是可以独立完成一个产品的人。

1、Web开发流程

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

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

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

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

前端工程师:产品视觉稿在得到产品经理和交互设计师等多方确认之后,会交给前端工程师,由前端工程师制作页面,实现视觉稿以及交互功能。从头衔上的变化就可以看出,这时候才真正开始编码。前端工程师需要非常熟悉html、CSS和javascript,以及性能、语义化、多浏览器兼容、SEO、自动化工具等广泛的知识。

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

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

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

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

2、技术的发展

提到全栈技术,不得不提一个代表性的全栈框架——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的工程师可以兼顾前后端的开发,并且前端模板代码和后台模板代码是可以复用的。

3、提供PaaS服务的平台越来越多

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

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

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

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

4、一专多长

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

所以我认为,全栈工程师首先要“一专多长”。一专多长的意思是,工程师首先有一个专精的方向,在这个方向上足够精通之后(高级工程师级别),以此为突破点去学习更多的知识,增加自己的长处。如果还没有获得某个方向上足够深入的理解,就不要囫囵吞枣地去学习其他领域的知识。

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

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

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

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

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

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

延伸阅读:

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

如何成为全栈工程师

1、先精后广,一专多长

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

采用这种方式来学习,不光可以触类旁通、举一反三,还让我们学习得更快,而且循序渐进更符合一般人的职业生涯发展。

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

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

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

2、围绕商业目标

老板雇用一个员工,不是因为他能写程序,而是因为他能帮助自己赚钱。

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

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

3、用户是谁

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

4、大巧若拙

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

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

延伸阅读:

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

从学生到工程师

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

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

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

其实我的设计知识仅限于自学,来自于一本书——《写给大家看的设计书》。这本书非常入门,但是浅显易懂,既有设计理念,也有实际操作,到现在为止我反复看了3遍以上。

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

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

1、获得面试机会

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

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

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

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

2、实习

实习能提升自己的实践能力,可以认为是从学生到社会人士的一个身份过渡。建议:

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

延伸阅读:

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

野生程序员的故事

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

1、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协议,作为大公司的前端工程师是非常看重的,因为每一个页面都会有亿万用户访问量,任何一点对服务器带宽压力都会积少成多,最终造成很大的成本。关于这方面的技术详解,我在后面会有一篇单独的文章来分析。

2、知易行难

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

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

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

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

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

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

这几年我从一个求职者,转变成一个招聘者,有一个感受就是,中国高等教育与市场需求不接轨。学校不了解市场究竟需要什么样的人才,其设立的课程和技术往往比市场技术现状落后了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的同学更有优势。此外,学校社团有一些定点客户,比如学校教务处、周边商户,所以有更多的实战经验,在毕业时作品集也丰富了不少。

因为有这样一些自学渠道,所以不一定只有计算机专业毕业的学生才有机会进入互联网行业。毕业之后,这些计算机爱好者进入不同的工作岗位,不同的是,有些进入大公司,有些进入小公司。这两者的成长轨迹往往会不太一样。

4、大公司还是创业公司

如果你是毕业生,这种情况下我还是建议选择大公司,因为会选择创业公司的人往往有自己的主见,已经接受创业公司的邀请去工作了,不会去发帖询问大家的意见。当然这是开玩笑,真正的原因是,在大公司的头两年,是从学生到职场人士的一个转变,您可能会从大平台学习到一些规范的流程方法,养成一些足以影响您一生的习惯,认识更多的能对您职场有帮助的人脉

大公司能给你的有:

  • 较小的风险

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

  • 技术最佳实践

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

  • 垂直专精的技能

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

  • 服务海量用户的经验

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

  • 软技能

硬技能是指每个职位需要的专业技能,软技能则是通用的技能,比如沟通、影响力、项目管理和演讲等。越是大公司,越是看重影响力,所以会有很多培训教您如何提高影响力。

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

  • 人脉

每年都有不少人从大公司离职去创业,这是非常自然的事情。对于大公司出来的人来说,之前积累的人脉资源这时候会起到很大的作用,比如创业期间的一些合作机会或者资源的互利,等等。万一创���失败,也不会很惨,因为您之前接触的人脉可以给您提供工作机会。但如果您刚毕业就选择创业,创业失败之后没有人能给您提供工作机会。

  • 心态

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

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

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

延伸阅读:

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

工程师事业指南

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

1、重视作品集

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

我很重视作品集,一方面体现在我很在意维护自己的作品集,另一方面我也很喜欢面试的时候看到应聘者有自己的作品集。除了工作上安排的项目,我更在意一些课外项目,因为它展示了您的兴趣和热情所在。

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

对于程序员来说,成本最低的一种作品展示方式就是把自己的代码发布到GitHub上。

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

另外,将代码开源,大家看到的是项目功能,而不是代码技巧。如果不是自己需要,没有人会闲得帮其他人优化代码。如果您的想法够好,那么就会收获来自社区的感谢、帮助,以及您应有的声望。

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

2、我想推荐的第二种方案是静态页(比如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%以上。

3、突出重点

如果作品集有一些动态生成的内容的话,可以选择自己架设服务器并绑定域名,VPS就是不错的选择。VPS成本比GitHub Pages高,因为需要付费和配置环境,但是最终跟GitHub Pages的效果是类似的。

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

作品集不一定是严谨而无趣的,曾经有一个前端开发者就将自己的作品集用一个HTML5游戏包装起来,让人印象非常深刻。

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

通过 about.me可以生成自己的作品集,截图来自about.me。

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

全栈工程师眼中的HTTP

HTTP,是Web工程师每天打交道最多的一个基本协议。很多工作流程、性能优化都围绕HTTP协议来进行,但是我们对HTTP的理解是否全面呢?如果前端工程师和后台工程师坐在一起玩捉鬼游戏,他们对HTTP的描述可能会截然不同,从这两个角色的视角看过去,HTTP呈现出截然不同的形态。

1、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以及iosandroid的浏览器等)的最新版都已经支持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的基本知识,我们来分别看看前端工程师和后台工程师分别是怎样看待这个最熟悉的小伙伴的。

2、前端视角

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

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

  • 发出的请求列表。
  • 每个请求的开始时间。
  • 每个请求从开始到结束花费的时间。
  • 每个请求的类型(比如是文本、CSS、JS,还是图片或者字体等)。
  • 每个请求的状态码(比如是200、还是from cache、304、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文件会需要好几倍的时间。

3、后台视角

前端工程师对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攻击等。

3、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站点中,它的数据流从服务器端到浏览器端,哪些地方可以使用缓存来优化。

1、服务器缓存

对于一些计算量大的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后面所使用的字段名称也必须是相同的

以上是关于《Web全栈工程师的自我修养》读书笔记(转载)的主要内容,如果未能解决你的问题,请参考以下文章

《web全栈工程师的自我修养》阅读笔记

原创|读书笔记温故前端之一

Web全栈工程师修养

全栈的自我修养: 001环境搭建 (使用Vue,Spring Boot,Flask,Django 完成Vue前后端分离开发)

全栈的自我修养: 002使用@vue/cli进行vue.js环境搭建 (使用Vue,Spring Boot,Flask,Django 完成Vue前后端分离开发)

国庆5天目标计划