本书的做者余果,腾讯社交用户体验设计部高级UI工程师,前端开发组负责人,熟悉前端开发、iOS开发、PHP开发和Ruby开发等。这本书所讲的内容适合所程序员,不限于前端后端客户端,不少内容其实都是常识。第二遍阅读,特此整理此书精华内容笔记。css
对于全栈工程师 ,业界并无严格的定义 ,并非说必定要一种都不能少地具有哪几项知识才能叫作全栈工程师 。我倾向于认为 ,应该从能力和思惟方式两方面 ,来断定一我的是不是一个合格的全栈工程师 。前端
国外是怎么样定义的呢?在著名的问答网站Quora上有一个高票的回答:程序员
全栈工程师是指 ,一个能处理数据库 、服务器 、系统工程和客户端的全部工做的工程师 。根据项目的不一样 ,客户须要的多是移动栈 、 Web栈 ,或者原生应用程序栈 。面试
简单来讲 ,全栈工程师就是能够独立完成一个产品的人 。当客户让他去作一些温馨区以外的工做时 ,他勇于迎难而上 ,并成功完成任务 。数据库
虽然流水线式的职业划分和工程管理有不少优势,可是它就像一把双刃剑,在带来高可控性、可用性和可管理性的同时,也给工程师带来了一些困境。segmentfault
1. 工程师职责不清致使效率低下后端
2. 工程师缺少主人感致使产品质量差浏览器
3. 工程师缺少全局的视野影响我的成长
当工程师但愿晋升到更高级的职位 ,如高级工程师或者管理岗位时 ,公司对他的大局观会有更高的要求 ,这就不只仅是作好 “份内 ”的工做就行的 。高级工程师须要有对设计的理解 、对后台知识的了解 ,以及有跨团队推进项目的能力 。长期研究专精的专业知识会让一我的视野变窄 ,变成 “学术派 ” ,而不是 “实践派 ” 。缓存
4. 更多角色致使项目效率低下安全
由于各司其职的工做流程有效率低下 、成本高的缺点 ,因此不少创业公司都不会配备齐全的流水线 ,而是但愿采用更灵活的方式来组建团队 ,全栈工程师也所以成为了理想的选择 。可是全栈工程师的兴起还离不开这两个重要因素 :技术的发展 ,以及提供 PaaS服务的平台愈来愈多 。
而我推崇的全栈工程师则是与专精工程师不一样的另外一条道路 。全栈工程师除了在一个专精知识领域有深刻研究以外 ,还以知识广博和解决问题能力强著称 。因此我认为有志成为全栈工程师的学习者 ,要有这样几个觉悟 。
1. 一专多长
一专多长的意思是 ,工程师首先有一个专精的方向 ,在这个方向上足够精通以后 (高级工程师级别 ) ,以此为突破点去学习更多的知识 ,增长本身的长处 。若是尚未得到某个方向上足够深刻的理解 ,就不要囫囵吞枣地去学习其余领域的知识 。
2. 解决问题,而不是醉心技术
“先精后广 ,一专多长 ”是指 ,建议初学者学习全栈技能的时候 ,先在一个特定的方向上有比较深刻的钻研 ,而后再将学习目标渐渐推广开来 。好比先从前端方向入手 ,掌握了基本的 HTML
、CSS
、JavaScript
以后 ,不要转头向服务器端语言或者 App 方向发展 ,而是深刻到性能优化 、 SEO 、多种框架 、响应式页面等前端细节中去 。通过一到两年的深刻研究以后 ,再去学习其余方向 。
若是是毕业生或者初学者 ,我不建议在刚开始的一到两年接触太多技术 ,杂而不精 ,结果可能会对后面的职业道路产生反作用 。
为何要强调在开始的时候要专精方向的重要性呢?由于这样您才能在求职的时候有一个“亮点”。
不管是毕业生仍是社会招聘 ,仅仅知足招聘要求是不够的 。您须要在招聘要求的方向上以 200%的能力来获得这个职位 。一个求职者在整个流程中会受到多方考核 : HR考核您的成本和价值 ,专业面试官 (不是全栈工程师 )考核您的专业能力 ,经理考核您的沟通能力 。在全部这些考核中 ,其实每一环都是漏斗型筛选 ,会过滤掉一些人 。
让我再次重复这一点 ,做为求职者 ,必定要在某个特定方向上有很是深刻的理解 。仅仅会作还不够 ,还要理解背后的缘由 ,还有背后的背后的缘由 。
个人第一条建议是 ,在考虑作什么项目的时候 ,围绕商业利益做为目标 。归根结底 ,技术是服务于商业目标的 。
老板雇用一个员工 ,不是由于他能写程序 ,而是由于他能帮助本身赚钱 。赚钱有两种方法 :减小成本 ,或者增长收入 。程序员若是能加快内部系统的运行效率 ,让产品制做流程更加顺畅 ,就是减小成本 。若是能让用户更容易地购买产品 ,或者提升服务质量吸引更多用户 ,就能增长收入 。在老板看来 ,程序员只是一个昂贵的劳动力 ,他会不会写程序都没那么重要 ,重要的是能赚钱 。
因此若是您想成为一个高级开发者 (或者高级设计师 ) ,就必定要学会这种思惟方式 。
所谓 “商业目标 ”要广义地去解读 。对于直接制做产品 ,给用户使用的团队 ,就须要对外关注如何提升产品质量 、下降产品成本 ;对内应该关注如何优化流程 、减小错误率 。若是团队输出的成果是公司内其余部门须要的原材料 ,就要关注下游的需求 ,研究如何更好地输出成果 ,如何在流程上使得输出产品的过程更顺畅 。
关注商业目标须要持久的练习 。等到本身成为全栈工程师 ,或者成为团队管理者 ,更加须要在多个目标任务之中作出选择 。全栈工程师须要作和可以作的事情是不少的 ,他会不少技能 ,也负责处理不少工做 ,因此他更须要能力从诸多事情中找到最有商业价值的一个 :多是制做一款工具提高团队效率 ,也多是成本上的优化 。
全栈工程师能够作得事情越多 ,就越须要具有判断作什么的能力 。若是增长一个用户须要的功能是加分项的话 ,拒绝一个用户不须要的需求更加值得推崇 。
一切都要围绕商业目标来进行 ,包括您作的项目 、您的汇报方式 ,以及您在学习新技能时进行的取舍 。永远从商业目标的角度来决定学习哪些东西 ,而不是纯粹为了锻炼技术能力而去学习 。
每个糟糕的体验背后都蕴藏着商机(腾讯HR的故事)
用户是谁
大巧若拙
意思是指,真正聪明的人,不会显露本身,反而从表面上看好像还很笨拙
作本身会用的产品
我若是开创一个公司须要招聘 “全栈工程师 ” ,我要求的三个能力就是一专多长 、关注商业目标 、关注用户体验 。
软件工程师事业指南告诉您 ,最核心的 3个词就是技术 、成长和声望 。技术是您的武器 ,成长就是好好打磨武器 ,而声望是您一辈子的积累 。怎样得到良好的声望 ?很简单 ——答应作的事 ,所有都要完成 。
那若是上司真的给出一个很是棘手的问题 ,您该如何回答 ?没错 ,您不能直接拒绝 。拒绝上司是很困难的 。但您也不能什么都答应下来 ,随后又没法完成任务 。那时候您会丢掉更多的得分 。正确的方法是 ,讲出事实 。
1. OSI七层模型
OSI模型义了整个世界计算机相互链接的标准,总共分为 7层 ,其中最上层 (也就是第 7层 )就是应用层 , HTTP 、HT TPS、FTP、TELNET、SSH、SMTP和POP3都属于应用层 。这是软件工程师最关心的一层 。 SI模型越靠近底层 ,就越接近硬件 。在 HTTP协议中 ,并无规定必须使用它或它支持的层 。事实上 , HTTP能够在任何互联网协议或其余网络上实现 。 HTTP假定其下层协议提供可靠的传输 ,所以 ,任何可以提供这种保证的协议均可以被其使用 ,也就是其在 T CP / IP协议族使用 TCP做为其传输层 。
](https://timgsa.baidu.com/timg...
2. 关于HTTP版本
1999年发布HTTP1.1,比1.0它增长了缓存处理和持续链接,以及其余一些性能优化。
2015年2月,HTTP/2正式发布 。新的 HTTP版本有一些重大更新 ,除了一如既往地向下兼容 HTTP/1之外 ,还有一些优化 ,好比减少网络传输延迟 ,并简化服务器向浏览器传输内容的过程 。主流的服务器 (Apache 、Nginx等 )和浏览器 (Firefox、Chrome、Safari以及 iOS和Android的浏览器等 )的最新版都已经支持 HTTP/2 ,剩下的就须要网站管理员把服务器升级到最新版了 。
每个前端工程师都知道的基本优化方法是:尽可能减小统一域下的HTTP请求数,以及尽可能减小每一个资源的体积。
尽可能减小统一域下的HTTP请求数
浏览器经常限定了对同一域名发起的并发链接数的上限 。 各类浏览器广泛把这一上限设定为 4至 8个 。若是浏览器须要对某个域进行更多的链接 ,则须要在用完了当前链接以后 ,重复使用或者从新创建 T C P链接 。
因为浏览器针对资源的域名限制并发链接数 ,而不是针对浏览器地址栏中的页面域名 ,因此不少静态资源能够放在其余域名下 (不一样的子域名也被认为是不一样的域名 ) 。若是您只有一台服务器 ,能够把这些不一样的域名同时指向一个 I P ,也就提升了对这台服务器的并发链接数限制 (不过要当心服务器压力过大 ) 。
把静态资源放在非主域名下 ,这种作法除了能够增长浏览器并发 ,还有一个好处是 ,减小HTTP请求中携带的没必要要的cookie数据 ,由于这对带宽和连接熟读都形成了影响,因此咱们通常把静态资源放在单独的域名下。
尽可能减小每个资源的体积
咱们不光要限制请求数 ,还要尽可能减小每个资源的体积。由于资源的体积越大 ,在传输中消耗的流量就越多 ,等待时间也越久 。
在面试应聘者的时候,我会问的一个基础题目是 “经常使用的图片格式有哪些 ,它们的使用场景是什么 ” 。若是能选择合适的图片格式 ,就可以用更小的体积 ,达到更好的显示效果 。对图片格式的敏感 ,能反映出工程师对带宽和速度的不懈追求 。此外 ,对于比较大的文本资源 ,必须开启 gzip压缩 。由于 gzip 对于含有重复 “单词 ”的文本文件 ,压缩率很是高 ,能有效提升传输过程 。
前端工程师对HTTP的关注点在于尽可能减小同一域下的HTTP请求数 ,以及尽可能减小每个资源的体积 。与之不一样 ,后台工程师对于HTTP的关注在于让服务器尽快响应请求 ,以及减小请求对服务器的开销 。
提升服务器的请求处理能力
Apache是市场份额最大的服务器 ,超过 50%的网站运行在Apache上 。Apache经过模块化的设计来适应各类环境 ,其中一个模块叫作多处理模块(MPM)专门用来处理多请求的状况 。Apache安装在不一样系统上的时候会调用不一样的默认MPM ,咱们不用关心具体的细节,只须要了解Unix上默认的MPM是prefork
。为了优化,咱们能够改为worker
模式 。
prefork
和worker
模式的最大区别就是 ,prefork的一个进程维持一个链接 ,而worker的一个线程维持一个链接 。因此prefork更稳定但内存消耗也更大 ,worker没有那么稳定 ,由于不少链接的线程共享一个进程 ,当一个线程崩溃的时候 ,整个进程和全部线程一块儿死掉 。可是worker的内存使用要比prefork低得多 ,因此很适合用在高HTTP请求的服务器上 。
在高链接并发的状况下 ,Nginx是Apache服务器不错的替代品或者补充 :一方面是Nginx更加轻量级 ,占用更少的资源和内存;另外一方面是Nginx处理请求是异步非阻塞的 ,而Apache则是阻塞型的 ,在高并发下Nginx能保持低资源 、低消耗和高性能 。因为Apache和Nginx各有所长 ,因此常常的搭配是Nginx处理前端并发 ,Apache处理后台请求 。值得一提的是 ,新秀Node.js也是采用基于事件的异步非阻塞方式处理请求 ,因此在处理高并发请求上有自然的优点 。
DDos攻击
DDos是Distributed Denialof Service的缩写,DDos攻击翻译成中文就是 “分布式拒绝服务 ”攻击 。
攻击者经过海量的请求 ,让目标服务器瘫痪 ,没法响应正常的用户请求 ,以此达到攻击的效果 。对于这样的攻击 ,几乎没有什么特别好的防御方法 。除了增长带宽和提升服务器能同时接纳的客户数 ,另外一种方法就是让首页静态化 。
DDos攻击者喜欢攻击的页面通常是会对数据库进行写操做的页面,这样的页面没法静态化,服务器更容易宕机 。DDos攻击者通常不会攻击静态化的页面或者图片,由于静态资源对服务器压力小,并且可以部署在CDN上 。
BigPipe
通俗来解释,BigPipe首先把HTML页面分为不少部分 ,而后在服务器和浏览器之间创建一条管道 (BigPipe就是 “大管道 ”的意思 ) ,HTML的不一样部分能够源源不断地从服务器传输到浏览器 。BigPipe首先输送的内容是框架性HTML结构 ,这个框架结构可能会定义每一个Pagelet模块的位置和宽高 ,可是这些Pagelet都是空的,就像只有钢筋混泥土骨架的毛坯房 。
接下来管道里源源不断地传输过来不少模块 ,这时候最开始加载在服务器中的JS代码开始工做 ,它会负责把每个模块依次渲染到页面上,在用户的感知上,页面很是快地出如今眼前 ,可是全部的模块都显示正在加载中 ,而后主要的区域 (好比重要的用户动态 )优先出现,接下来是logo、边栏和各类挂件等 。
为何BigPipe可以让服务器对浏览器说“我这个请求还没结束,咱们保持这个连接不要断开”呢?答案是HTTP1.1的分块传输编码。
HTTP1.1引入分块传输编码 ,容许服务器为动态生成的内容维持HTTP持久连接。若是一个HTTP消息(请求消息或应答消息)的Transfer Encoding消息头的值为chunked,那么消息体由数量不肯定的块组成 ——也就是说想发送多少块就发送多少块 ——并以最后一个大小为0的块为结束 。
基本的数据库查询缓存
MySQL默认不开启查询缓存 ,但咱们能够经过修改MySQL安装目录中的 my.ini
来设置查询缓存 。设置的时候能够根据实际状况配置缓冲区大小 、单个查询的缓冲区大小等 。
能够在MySQL配置中增长这两项
query_cache_size = SIZE
SIZE是指为查询缓存开辟多大的空间 。默认是 0 ,也就是禁用查询缓存。
query_cache_type = OPTION
设置查询缓存的类型 ,可选的值有如下这三种 。
0:设置查询缓存的类型 ,可选的值
1:全部的缓存结果都缓存起来 ,除非查询命令以 SELECTS_NO_CACHE
开始 。
2:只缓存查询命令以 SELECT SQL_CACHE
开始的查询结果 。
因此 ,对于查询操做远远多于修改操做的数据库 ,开启数据库查询缓存是颇有益的 ;可是对于修改操做不少的数据库 ,因为缓存常常会失效 ,就起不到加速的效果 。不只如此 ,因为数据库要花费时间写缓存 ,因此实际上速度更慢了 。
这里须要注意的是 ,两次 SQL 文本必须彻底相同 。若是先后两次查询使用了不一样的查询条件 ,就会从新查询 。
扩展数据库缓存:memcached
memcached的缓存失效采用的是按时间来过时的设计 。memcached至关于应用程序和数据库之间的中间层 ,经过网络 API设置和调用 。memcached储存的是名值对 ,并且设置了一个过时时间 ,只要过时时间没有到 ,应用程序就会从memcached中获取数据 。这时候即便发生了数据库更新操做 ,缓存的查询结果也仍然是以前保存的旧数据 ,直到设置的时间过时 。这样提升了缓存的性能 ,带来的影响就是 ,数据多是 “不新鲜 ”的 。
可是 memcached 也不是老是那么有效,由于若是只有一台服务器,就用不到它的服务器集群的优点,反而让系统更慢 。
再加一层文件缓存
除了能够将数据库查询结果缓存在内存中还能够将被频繁造访的数据缓存在文件中。文件 I/O 比起内存有如下几个好处。硬盘容量比内存大,因此能够缓存更多数据。数据更安全,断电以后数据还在。易于扩展,硬盘不够用的时候还能够添加硬盘。可是文件缓存没有内存缓存快,只能做为内存缓存的补充,在获取数据时,先从最快的地方读取,若是没有就继续日后找。查找优先级为:内存缓存 →文件缓存 →数据库 。
缓存文件不会过时,除非您删掉它,不然任何被缓存了的查询会一直存在。缓存系统容许您按页面清除,或把全部缓存都清除掉 。通常来讲,您能够在某些事件(好比向数据库添加了数据 )发生时用特定的函数来清除缓存 。
静态化
有两种静态化的方法,其中一种是相似 WordPress 的静态化插件,安装很简单,每次有新文章就自动生成静态页面。这种方法仍是将数据保存在数据库中,只是会读取数据库以后生成一些静态页。这一种方法的原理跟文件缓存很类似 。
另外一种方法就是直接抛弃数据库 。好比有一些博客做者会用 Jekyll 系统来写博客,将整个博客站点静态化。彻底抛弃数据库的好处是,能够将生成的静态网页直接托管在静态资源站点,好比 GitHub Pages 或者 Amazon S3,而不用操心数据库服务器的问题,不光整个系统稳定不少,费用上也更加低廉 (GitHub更是彻底免费的,并且提交 Markdown 源代码后可让它在服务器端生成站点) 。
当浏览器访问一个站点的时候,网络链接是主要瓶颈,咱们能够经过设置浏览器缓存来跳过 HTTP请求。若是在浏览器设置缓存,一般有两个主要做用。
用户来讲,减小请求能够更快地加载页面,节省流量。若是用户是在手机上用3G或4G访问页面,这一点就很关键。
对网站来讲,减小带宽压力和费用。假设有1亿的访问量,若是能把大小为 10KB的 CSS缓存起来,能够节省不小的开支。
主要的两种缓存指令
第一种:Expires
这种缓存是最快的,由于没有任何 HTTP请求发生。当用户须要这个资源,浏览器就直接从缓存中读取,再也不须要询问服务器端的意见(服务器端甚至不知道您在浏览 image.png) 。因此 HttpWatch是推荐对全部的静态资源都设置Expires 。
第二种:Last-Modified
经过这种缓存方式 ,不管资源是否发生了更新 ,仍然至少会发生一来一去 HTTPS 头的传输和接收 ,因此速度比不上Expires 。
从服务器端的角度来看 ,有时候咱们并不但愿对静态资源的请求中大部分都返回304。由于这可能说明咱们的不少用户都在频繁访问站点 ,并且咱们的资源不多更新 ,就好像它们一直问 “资源修改了吗? ” ,咱们一直回答 “没有修改 ” 。这里可使用Expires来设置过时时间 ,这样它们就不会 “烦咱们 ”了 。对于服务器管理员来讲,保持304为一个合理的比例便可 。咱们能够经过查看服务器的log ,查看304响应与200响应的比例,来作出一个合理的缓存策略 。
Restful Web API
表征性状态传输(Representational State Transfer,REST)是一种软件架构风格。在 3种主流的Web服务实现方案中,由于REST模式最简洁,也能合理地利用HTTP操做的语义,因此愈来愈多的Web服务开始采用REST风格设计和实现 。
Restful的目的是定义如何正确地使用Web标准,优雅地使用HTTP自己的特性。原则上是对资源、集合、服务(URL)、get、post 、put、delete(操做)的合理使用。举例来讲,若是请求一个资源,可是服务器上没有这个资源,这时候就应该对HTTPS头设置404,而不是设置200。
HTTP1.1加入的Cache-Control
它的功能跟Expires相似,不过有更多的选项。Expires的值是一个日期,表示某日期以前都再也不询问。Cache-Control的值是 : maxage = 7776000, maxage的单位是秒,从浏览器接收到文件以后开始计时。
按照HTTP规范 ,若是修改了请求资源的QueryString,就应该被视为一个新的文件。
下面是推荐的浏览器缓存设置最佳实践。
对于动态生成的HTML页面使用HTTPS头:Cache-Control:nocache
。
对于静态HTML面使用HTTPS头:Last-Modified 。
其余全部的文件类型都设置Expires头,而且在文件内容有所修改的时候修改QueryString。
浏览器缓存的现实世界
服务器端能够设置缓存规则,告诉浏览器应该如何遵循和实现,但在服务器不能掌控的地方也许会出现一些意外。缓存会被挤出。文件有可能在运营商服务器上被劫持。
第二个问题是 ,用户的宽带运营商为了提升速度 ,可能会在本身某节点服务器上缓存您的文件(好比style.css?v1),好处是当用户请求这个文件的时候,运营商无需来您的服务器上请求文件,而本身直接就给出了。
问题来了,若是您的QueryString更新了(style.css?v2),按照HTTP规范,这理应被视为一个新的文件,可是运营商仍然可能会拿本身节点的缓存,而不是遵循规范。有点可恶对不对?这就是咱们在用户量极大的状况下侦测到的状况,虽不太常见,可是有可能发生。因此,为了保证更新的文件下发到全部的用户,咱们会使用更增强硬的方法:修改文件名,而不是仅仅修改QueryString。
QQ空间静态资源在浏览器端使用的缓存策略。
对于动态生成的HTML页面使用HTTPS头:Cache-Control:nocache
。
对于静态HTML页面使用HTTPS头 :Last-Modified 。
其余全部的文件类型都设置Cache-Control头,而且在文件内容有所修改的时候修改文件名。
文章出处:http://dunizb.com
原文连接:http://dunizb.com/2017/03/16/《Web全栈工程师的自我修养》浓缩笔记(上)/