Web全栈工程师的自我修养读书笔记
一直以来有个梦想就是做一个全栈工程师,而且很喜欢开发Web,但是因为求学路上选择的原因和自身的不够努力,梦想就一直是梦想。2016年找好了一个工作,研究生阶段也就顺理成章的剩下了论文,虽然不是一挥而就的事情但是相对地有些时间来做自己的事情。某天在图书馆闲逛的时候,全栈的心思又进入了我的脑海了,信手一搜就找到了这本刚入库不久的余果先生的Web全栈工程师的自我修养,我想也许这是一种暗示,我该为这个梦想上路了,所以,读了这一本,下面是读书笔记:
[TOC]
Web全栈工程师的自我修养
什么是全栈?
栈:是一系列子模块的集合。这些软件子模块或组件组合在一起可实现既定功能,不再需要其他模块。
我想作为一个全栈需要有自己实现产品需求的能力,将一个东西从无到有的做出来。
Web栈:服务器(Nginx、Apache)、数据库(MySQL、MangoDB)、服务器端编程语言(Java、PHP、Python)、HTML、CSS、JavaScript
APP栈:与Web栈类似,后端技术是是通用的,将前端部分换成iOS或者Android开发技术
从能力和思维方式两方面来判定一个人是否是一个合格的全栈工程师
全栈工程师需要能够一个人完成一个产品并且在舒适区之外工作的时候,敢于迎难而上,并成功的完成任务。作为一个全栈需要时刻准备着应对各种可能出现的挑战并能够克服之。
全栈工程师是指:一个能处理数据库、服务器、系统工程和客户端的所有工作的工程师。根据项目的不同,客户需要的可能是移动站、Web栈或者原生应用程序栈。
虽然全栈大包大揽,看似并不能够实现。但是从一个栈专注入手还是能够将这个全搭建起来的,虽然我之前一直做的是C++桌面程序开发,但是之后的日子我想从前端入手搭建属于自己的第一个全栈。
Web开发职位及流程介绍
产品经理:从头策划一个产品或者优化已有产品的一部分,从策划开始跟进到发布、是产品的灵魂人物之一。
用户研究员:研究用户的行为,既有宏观的数据分析也有微观的场景分析,召集用户开会或者静静地观察,输出用户研究报告给产品经理和交互设计师,我觉得这个是一个先行者的角色但是在大部分情况下估计是产品经理的工作
交互设计师 :研究用户界面的信息分布和操作流程,输出用户与界面交互过程的流程图以及描述信息的线框图给视觉设计师。
视觉设计师 :有时候与交互设计师并不分家,主要工作是根据交互设计师输出的线框图进行润色和设计,输出产品的最终视觉设计稿给前端工程师进行实现。
前端工程师 :页面的制作者,需要熟悉前端三驾马车、性能、语义化、多浏览器兼容、SEO、自动化工具等广泛知识。
后台工程师 :进行服务器功能的开发,技术选型比较自由,包括C#、C++、Java、PHP、ROR、Python等。出了开发还需要负责服务器的配置、调试,数据库的配置和管理。在大公司职位还会细分为后台工程师、运维工程师(服务器的配置和调试)、数据库管理员(DBA)等岗位。
运维工程师 :关注服务器的压力、成本、安全等信息
测试工程师 :测试产品的,对于全栈来说TDD也是一种不错的想法
专业工程师成长的几个问题
缺乏主人感导致产品质量差,初级阶段可以多磨练技术,但是不要丧失了对于产品目标的把握
缺乏全局的视野,高级工程师不仅仅是做好分内的工作,需要对设计的了解,对后台的了解,跨团队推进项目的能力,做一个“实践派”
MEAN:全栈框架,包括MongoDB,面向文档、NoSQL类型的数据库,采用类似JSON的文档结构来存储数据。Express,Node.js框架能够灵活地创建Web服务。AngularJs,前端框架,致力于使用MVC模式来开发前端,使开发和测试交互的页面更加轻松。Node.js
MEAN与LAMP,LAMP中并没有体现前端框架的应用
全栈工程师最好一专多长
全栈工程师的首要目标是解决问题,不是醉心技术,我会用比我完全懂有意义。主动承担更多的责任,给公司带来更多的收益。DONE IS BETTER THAN PERFECT!
如何成为全栈工程师
先在一个方向上有比较深入的钻研,然后再将学习目标渐渐推广开来。比如从前端方向入手,了解了基本的三驾马车之后,不要急着转向服务端语言、或者App方向,而深入到性能优化、SEO、多种框架、响应式页面等前端细节中去,经过一两年的深入研究再学习其他方向
说到底就是不要急于求成,学习的时候了解一个东西就要了解地深入一些,解决问题的时候DONE优先,不要死扣技术
你需要在招聘要求的方向上以200%的能力来得到这个职位
面试官的问法是从经验问到操作过程、再问到技术原理一直深入下去直到面试官问不下去或者求职者答不上来,所以理解地越深刻越有优势。
全栈工程师考虑做什么项目时需要考虑到商业目标、帮老板赚钱。自己的知识体系可以复用
对于商业和市场有想法,而且自己有足够的技术能力和自信想未来前进
每一个糟糕的用户体验背后都蕴藏着商机
关注用户体验,关注每一个您为之服务的人。PPT的听众(他们要什么),邮件的收件人(你想让他知道什么),老板(选择题),尽量用流程化的方法解决问题,如果不行,就用工具搞定他。
大巧若拙 :真正聪明的人从来不显露自己,功夫花在背后,花在基础,花在真正有用的地方,不为炫技,不为虚名。
做自己会用的产品 :随时切换大师状态和小白状态
全栈工程师三方面:一专多长、关注商业目标、关注用户体验
从学生到工程师
岗位优先于公司,不要在一个公司做自己不喜欢也不擅长的工作。首先还是要想清楚自己喜欢什么,但是从稻盛和夫的观点来说,只有去做了才知道自己是不是真的喜欢,或者让自己喜欢上。所以我觉得还是需要先钻研,好的是我的公司Morgan招聘的就是全栈,或许能够让我有所成长,当然我还是更想去腾讯。
招聘过程中需要的是找对方法,在自己对于一个东西的理解之上做出一些实际有用的东西来,包括博客、作品以及公司实习
- 首先确定自己的求职意向,根据特定的意向填写自己的简历
- 表达自己的创意,不要使用标准的模块,我觉得可以使用自己设计的模板
- 将简历发送到真正招人的主管那里(找项目组)
作者十分推崇参加一个知名的开源项目,所以之后需要自己参加一个。
实习和进公司的建议:
- 记住团队里的每一个人(横向和纵向,不同部门之间)
- 有任何问题,主动问导师
- 主动介绍自己,告诉大家自己是新人,请多关照
- 每周发邮件记录心得总结、经验教训、学习成长
- 实习/工作结束,总结所有项目,给出交接文档,并向大家致谢
野生的程序员(需要引以为戒的东西)
Web性能优化:
- 压缩源码和图片:JavaScript混淆压缩、CSS普通压缩、JPG文件根据质量压缩、PNG将24色变为8色、去除PNG格式信息等
- 选择合适的图片样式:颜色较多使用JPG,颜色较少使用PNG,如果能够通过服务器判断浏览器支持WebP,可以使用WebP和SVG格式
- 合并静态资源:包括CSS、JavaScript和小图片,例如:雪碧图之类,较少Http请求数
- 开启服务器端的Gzip压缩:对于文本压缩非常有效,对于图片压缩比率不大
- 使用CDN,增加并发下载量,和其他网站共享缓存
- 延长静态资源的缓存时间:需要通过修改文件名的方式(这个在介绍缓存的那一章有讲)
- 把CSS放在页面的头部,把JavaScript放在页面的尾部:js不阻塞浏览器渲染,防止出现长时间页面空白
- 每一个条目都可以深挖下去
关注网络性能和HTTP请求协议
拒绝”知易行难” :要去应用一些觉得不错的开发方式,遇到问题需要进行深入的了解和分析,例如例子中提出的CSS缓存问题
大公司的垂直专精、最佳实践、软技能、人脉、心态
工程师事业指南:如何做一个不错的工程师
软件工程师的核心:技术、成长、声望
那个什么都会的家伙并不一定什么都会,是日积月累的声望造就的。如果你每天能够完成的请求超过收到的请求,那么你就能够积累声望。每一个请求都有人会注意。所以当你不能完成的时候,正确的方法是:讲出事实
积累作品集
如果使用得当,开源代码将是您和您的公司最好的广告,开源并宣传自己的作品
觉得自己的代码不够好而不开源,理由不成立
每次签入代码的时候都比签出代码的时候好一些,那么这个代码库就会越来越好
擅长设计和编程的全栈工程师可以使用Dribble
还可以使用静态页面加上github,我当前使用hexo在github上搭建了一个静态博客,是一个不错的开始。
突出重点
任何一个作品集都需要有一个重点。突出技能的深度就针对这个技能罗列出大量的作品。突出技能的广度就在github上提交相关技能的项目。
花点时间做一些有趣的事情,突出自己的存在。
全栈工程师眼中的HTTP(互联网核心协议的解读)
HTTP版本
- HTTP/1.1从1999年使用至今与HTTP/1相比,增加了缓存处理和持续连接(长连接)以及其他一些性能优化
- 2015年2月,HTTP/2发布,重大更新:减小网络传输延迟,简化服务器向浏览器传输内容的过程,主流服务器和浏览器都支持,需要升级服务器版本
HTTP示例
|
|
第一行指定方法、资源路径、协议版本,上例是简化之后的情况,实际使用中还会有cookie,HTTPS头,浏览器接受何种类型的压缩格式和UA(User-Agent,表示用户正在使用什么样的代理访问网站,最常见的是浏览器)代码
服务器应答如下:
|
|
需要搞清楚HTTP请求和HTTP返回的各个属性、意义以及用法
在返回头之后有一个空行,然后是HTML格式的Google主页
前端视角
前端可以使用Http Watch或者Chrome调试观察打开网站时候的请求细节,包括:
- 发出的请求列表
- 每个请求的开始时间
- 每个请求从开始到结束花费的时间
- 每个请求的类型(文本、CSS、JS还是图片、字体)
- 每个请求的状态码(200,frome Cache、304、404)
- 每个请求产生的流量消耗
- 每个请求gzip之前的体积和gzip之后的体积
前端基本优化方法:
- 尽量减少同一个域下的HTTP请求数:IE6/7和Firefox2对于同一个域能够发起两个并发连接,目前能够发起4到8个,如果需要更多连接就需要等到当前连接之后重新使用或者建立。
静态资源可以放到其他域名下,当然只有一台服务器的话,可将几个域名指向同一个IP,但是需要担心服务器的压力。
将静态资源放在非主域名下还能够不必要的cookie数据,例如cookie放在google.com的域名下那么对于google.com的所有请求都会带上cookie,对于静态资源完全没有必要。
- 尽量减少每一个资源的体积
注意每种图片格式的使用场景
对于较大的文本文件,开启gzip压缩,gzip优秀于压缩重复单词的文件
对于一个CSS资源的请求耗时:
- 请求资源体积以及压缩比
- 连接建立时间与资源下载时间
后台视角
让服务器尽快响应,减少请求对服务器的开销
浏览器对于并发数的限制是为了保护服务器,而某些恶意客户端并不会限制。
Apache 服务器使用模块化设计来适应各种环境。其中多处理模块用来处理多请求的情况。在不同系统上会调用不同的多处理模块,在UNIX上时prefork,为了优化可以改成worker
prefork与worker模式的最大区别是prefork采用一个进程维持一个连接,而worker使用一个线程维持一个连接,prefork内存消耗大,但是很稳定。worker采用一个线程维持一个连接,一个线程崩溃可能导致相关进程和线程都挂掉,但是内存消耗明显减少,适合用在高HTTP请求的服务器上
Apache与Nginx。高连接并发情况下,Nginx是Apache不错的替代和补充。Nginx更加轻量级。Nginx处理请求是异步非阻塞的,而Apache是阻塞的,在高并发情况下Nginx能保持低资源、低消耗、低阻塞
Apache与Nginx各有所长,Nginx用处理前端并发而Apache处理后台请求
DDOS攻击
DDOS攻击使用肉鸡,攻击客户端并不限制连接数,而且每个连接不会马上断开。
DDOS攻击防范:
- 增加带宽,提高服务器能够同时接纳的客户数
- 首页静态化。DDOS攻击者往往攻击有数据库操作的界面,这样的界面更加消耗资源。静态资源对服务器压力小,而且可以部署在CDN
DDOS的类型:TCP/IP攻击、CC攻击、SYN攻击、NTP攻击、TCP攻击和DNS攻击
HTTP请求流程
客户端建立连接、服务器同意连接、客户端发起请求、服务端返回数据、客户端接受并处理数据
HTTP阻塞模型中,用户感受到的延迟包括服务器生成页面的延迟、网络延迟以及页面渲染延迟
- HTTP底层是TCP/IP,需要三次握手才能建立连接。每个新增的请求都是重新建立连接。
- 现有模型中,服务器端计算页面会生成整个页面才开始传输,三个部分都是阻塞式的
阻塞模型中,服务器将页面相关数据一次产生好,然后通过response返回给浏览器,然后浏览器进行渲染。
BigPipe
BigPipe首先输送框架性的HTML结构,该结构定义每一个Pagelet模块的位置。传输完架构之后,服务器不断开连接,并告知浏览器先渲染。
用户感知BigPipe是网页很快出现了,但是各个部分都在加载。
BigPipe能够让服务器告知浏览器请求没结束,保持连接使用的是HTTP/1.1的分块传输编码。HTTP/1.1的分块传输允许服务器为动态生成的内容维持HTTP持久连接。体现在HTTP消息(请求或者应答)的Tranfer-Encoding,如果这个值为chunked,说明消息有数量不确定的块组成,最后以一个大小为0的块结束。
除了IE,HTTP/2已默认开启,服务器可以向浏览器推送消息,多于浏览器的请求数,不需要等浏览器解析完HTML在请求CSS、JS直接复用之前的连接推送。
Web中的缓存问题,高性能网站的关键
服务器缓存
数据库主要是开启查询缓存
MySQL中默认不开启缓存,但可以通过修改my.ini来设置查询缓存,包括缓冲区大小以及单个缓冲区大小。
MySQL缓存配置优化:
query_cache_size = SIZE;配置缓冲区大小,为0 的时候表示禁用查询缓存
query_cache_type = OPTION;三种缓存类型:
- 0 不缓存也不从缓存中获取查询结果
- 1 缓存除了以SELECT S_NO_CACHE开始的全部查询
- 2 只缓存以SELECT SQL_CACHE开始的查询结果
当对于数据的查询多于修改的时候,开启缓存是有效的。但是当数据库经常修改时,缓存频繁失效,此时效率反而降低。
能够利用缓存,SQL语句的内容需要完全相同,如果一个有where,一个没有会重新从系统获取数据。针对不同的字段名也会重新解析。
解决MySQL单点缓存的问题,升级解决方案memcached,可以数据库缓存配合
memcached 高性能分布式内存对象缓存系统
在数据库缓存设计中有一个原则:当某个表发生了更新操作,所有关于这个表的查询都会失效。为保证数据的时效性而较低命中率。
memcached采用按时间来过期的设计
12345678910 > st=>start: 开始> op=>operation: Request Key from memcached> cond=>condition: Does key exist?> op2=>operation: 从数据库加载数据> op3=>operation: 更新memcached> e=>end: 使用数据> st->op->cond> cond(yes)->e> cond(no)->op2->op3->e>
>
memcached储存的是键值对,只要设置的过期时间没到就会从memcached中获取查询结果,因此数据可能是不新鲜的
WordPress可以使用memcached插件,但是在只有一台机器的情况下memcached反而会更慢,因为需要进行两次查询
数据库缓存之上加一层文件缓存
将频繁访问的数据放在文件中
- 硬盘的容量比内存大
- 数据安全,断电恢复
- 易于扩展
查找优先级:缓存->文件缓存->数据库
PHP框Codelgniter的数据库缓存允许将结果放在文本文件中,只有读操作会产生结果集生成缓存文件,可以按照页面或者设置某些事件触发的缓存清除
采用静态化来避免对于数据库的操作
- WordPress的静态化插件,每次有新的文章就生成新的静态页面,这个静态页面就相当于文件缓存。服务器收到页面请求直接返回静态页面。静态化减少了服务器的压力。
- 完全抛弃数据库。jekyll让整个博客静态化,不用担心数据库服务器的问题。
浏览器缓存
浏览器设置资源缓存有两种方式:
- Expires:服务器会给返回的资源设置Expires,到日期之前都不需要重新获取,对于这种资源的请求会返回200(from cache),推荐所有的静态资源使用
- Last-Modified:服务器在返回资源中设置Last-Modified,浏览器将资源缓存。在下次请求命中资源时,浏览器请求中带有If-Modified-Since。如果没有修改,服务器返回304,如果修改了就正常返回200以及相关资源
需要研究服务器的log确定304和200在一个合适的比例。尤其是对今天资源访问较多,而修改较少时使用Expires消除一波304
Restful Web API
他是一种架构风格,定义如何正确地使用Web标准,包括:资源、集合、服务(URL)、get、post、put、delete操作。例如:当请求资源时,服务器上没有相关资源,应该返回404而不是200
HTTP/1.1 Cache-Control
Cache-Control设置了浏览器保存资源的时间、从浏览器收到资源后开始计时
当设置了Expires,如何通知用户文件的变化呢?
|
|
修改文件的QueryString也就是上例中问号后面的内容。QueryString会被服务器端的CGI或者应用程序理解。QueryString变化时浏览器认为是访问了一个新的资源。
浏览器缓存设置最佳实践
- 对于动态生成的页面HTTPS头中设置Cache-Control:no-cache
- 对于静态界面HTTPS头中使用Last-Modified
- 其他所有文件使用Expires并在文件内容修改时修改QueryString
浏览器缓存的实际情况
服务器告知浏览器缓存策略,但是可能出现意外
- 缓存被挤出:缓冲之间占用空间、用户清理等等,重新加载就好
- 文件被运营商劫持:运营商在自己的节点上缓存了你的文件,并且在修改QueryString时,他仍有可能用自己的缓存滥竽充数
当出现运营商劫持的时候,在QueryString之外还可以使用修改文件名的方法强制重新加载资源(这个当然用程序来统一实现)
大前端
前端知识体系:
初级前端工程师:
- 对于浏览器兼容性的了解
- 对于三驾马车语法和原理的了解
- 对于编辑器和插件的熟悉程度
- 对调试工具的了解程度
- 对版本管理软件的熟悉和应用经验
- 对前端库/框架的使用
- 标准/规范
中级前端工程师:
- 对代码质量、代码规范的了解
- 对于JavaScript单元测试的了解
- 对性能优化的应用和了解
- 对SEO的应用和了解
- 代码部署
- 移动Web
高级前端工程师:
- 代码架构
- 安全
- 对自动化测试的了解
越接近高级就会问对于某个点的本质了解,以及在项目和团队中的引导作用
HTML的难点在于前端工程师实现了页面之后还需要考虑机器和盲人如何理解这个页面:需要语义化的标签。
Markdown不会产生无意义的标签,不用关注样式而是更注重于内容本身,Markdown转换为HTML的方式有两种:
- 在开发环境将Markdown转化为HTML,在发布到服务器上或者有服务器自动转化成HTML文件
- 将Markdown发布到服务器上然后在用户访问HTML页面时有其中的JS代码将Markdown转换成HTML
推荐第一种方式:不依赖浏览器端的JS运行,可用性好也便于SEO
还有zen-coding也就是emmet的转化方法可以去了解一下
框架与库
一个库是一系列的对象、方法等代码,而一个框架是一个软件之中可以重用的部分,包括子程序、库、胶水语言、图片等一些资源。框架可能包含多种语言,某些功能提供API的方式让主程序调用
当出现一些热门的框架式,建议开发者先去了解框架的创建初衷,合理使用而不是盲目收集,不要在一个简单的东西中引入一个庞然大物
UI开发流程
- UI工程师拿到需求单和设计稿,和App开发人员共同,有哪些需要重新做,哪些可以复用
- 只是对界面的修改,无需改变逻辑的,UI修改资源和界面,然后提交测试
- 新增的UI和逻辑,UI工程师与APP开发人员 约定双方沟通的API,UI在View中实现API细节,并在Controller中使用示例来demo API使用
向移动端转型
行动重于计划
不要太多顾虑当前自己的优势劣势,而是应该尽早地行动起来。
- 如果你不把自己的手弄脏,就没办法成为一个好外科医生
- 自己给自己挠痒
一定要是自己产品的用户
移动端方向选择:
iOS原生APP
Andriod原生APP
Windows Phone原生APP
Web APP:包括所有Web平台以及微信公众号
混合模式APP
APP启动后,他的全部或者部分视图使用WebView来实现,常见的这种APP的优化方法如下:
- 将WebView的部分或者所有资源打包在APP中,APP的体积会变大
- 将需要加载的资源预先加载好:在启动的时候从后台下载需要的资源并存在手机的沙盒中,第一次访问比较久
- 使用HTML5 Manifest技术实现资源缓存
- 要结合原生技术和WebView各自的优势:不要完全依赖于WebView实现所有功能逻辑,包括页面切换,大量数据的页面等等
在使用WebView时需要学习WebView和原生代码之间通信
混合模式开发框架:PhoneGap
PhoneGap对于各个平台进行封装并通过JS暴露出统一的API,但有一些缺点:
- 编译出来的APP包比一般的要大很多
- PhoneGap应用的交互可能既不像苹果又不像安卓
- 动画性能不佳,在有大数据量加载的页面表现地更明显
PhoneGap适合于写一些小应用,应用UI交互不是很复杂的应用
持续集成
版本控制的最佳实践:
- 鼓励频繁地提交:创建一个分支然后在分支中频繁提交,不要在本地留下脏代码
- 确定分支流程:基本上所有的特性和bug修复都应该使用分支来完成
- 定义主干原则并坚守:主干对应的代码必须是可以发布并且不会产生bug的
- 不要把修改逻辑和代码格式化混在一起,给代码格式化一个单独的提交,然后再去修改逻辑
- 不相干的代码分开提交:不要在一次提交中修改两个Bug
- 保持工作库的“干净”:将该忽略的忽略,善用.gitignore
包管理(依赖管理)
程序的原则:一个程序只做一件事并做好
npm
可以通过命令行或者package.json来下载依赖组件
在package.json中的dependencies中写下袭来的模块和版本然后使用npm install就可以引入,模块会被放在node_modules文件夹中
|
|
npm命令行使用示例如下:
|
|
save说明这个依赖会出现在package.json的dependencies中,其余后面跟的后缀表示该配置包会出现在相关情况的dependencies配置中,最后一个参数暂时不知道意思
Bower
用于管理各种前端资源,解决前端代码本地化所造成的更新困难。依赖树扁平。
Bower使用Bower.json来进行依赖的定义,例如bootstrap对于jquery有依赖
|
|
然后运行
|
|
命令行就会提示依赖关系,虽然这里是层次形式显示的,但是最后他们会安装在同一个目录下
与npm相比,Bower并没有自己的服务器来托管所有的包,直接运行在git,npm发布包会将包发布到registry.npmjs.org或者对应的镜像上,而Bower直接将一个包名绑定到一个git仓库,然后代码本身推送到Git仓库即可,操作示例:
|
|
Bower使用软件包的时候直接使用install命令即可,来源可以是注册名,用户名/项目名,Git库,或者URL
其他的包管理器: Composer(PHP),gem(ruby),CocoaPods(应用程序级别,Objective-C)
版本号的规定
V3.2.1
3:主要版本号,API变更导致与旧版可能存在不兼容的情况变更
2:次要版本号:新增功能但是向下兼容
1:补丁:修复向前兼容的bug
版本指定方法
1.2.3,=1.2.3:指定版本为1.2.3
> 1.2.3,<1.2.3:大于/小于1.2.3
>=1.2.3,<=1.2.3
1.2.3~2.3.4:大于1.2.3并且小于2.3.4
~1.2.3:合理靠近1.2.3,等价于>1.2.3-0 <1.3.0-0,1.3.0-beta就不满足这个条件
~1.2:从1.2.0-0,< 1.3.0-0
~1:从1.0.0-0,<2.0.0-0
*:任意版本
前端构建工具
对外前端优化原则与对内前端开发的原则有一些不同,比如:合并CSS,不使用import,减少请求和阻塞等等。
一面朝向浏览器:关注性能、缓存、较少重复、保持一致,一面朝向前端团队:关注维护、发布流程
前端项目架构原则
- 合适的分离粒度:将合适的组件提取出来,保持整体一致
- 最小知识原则:一个组件或者对象不需要知道其他组件或者对象内部实现细节,比如将两个不同功能的组件分开
- DRY(Don’t Repeat Yourself):特定的功能只在一个组件中实现,在其他组件中不应该有副本[严格要求]
- 最小化预先设计,只设计必须的内容:为组件流程足够的地方,并不去考虑组件内部的实现
- 通过良好的层级让文件易于找到,基于项目区分代码库或者为了共享组件采用扁平化的目录层级,看具体情况
- 在代码层面,有一只且可执行的命名规则,从路径名到文件名有一致的前后缀、版本规则。整个团队有一致的命名风格和注释风格
Make
将大量的脚本命令组合起来放在一个makefile文件中,常用版本有BSD Make和GNU Make
Make使用makefile列出需要执行的任务,每一个任务的依赖资源,以及怎么完成每一个任务。示例如下:
a.txt: b.txt c.txt //说明a.txt是目标,需要b.txt以及c.txt作为前置条件
cat b.txt c.txt > a.txt //命令,以tab开始,然后是一句shell命令
Make的基本模型是:在顶一把一个任务时,首先声明依赖关系,然后根据依赖,调用相应的程序和数据,生成目标文件。
包管理也是根据依赖关系,将所有相关的软件包导入,所以依赖关系既属于包管理有属于构件工具
Grunt、Gulp
Grunt拥有众多插件:less,Sass,CoffeeScript等等,可以执行压缩、编译、单元测试、执行
存在的问题:
配置项过多,每一个插件的使用都需要配置输入项和输出项,使用比较繁琐
子任务之间的协作基于文件。这使得后一个子任务必须等待前一个任务过程完全结束才能开始自己的流程
Gulp:大口吸,基于流的构件工具,前一个任务的输出就是后一个任务的输入。没有多余的中间产物,不输出在磁盘
理解编程语言
编译方式和解释方式,还有运行时编译JIT,保留了编译器的高性能,也有解释器的灵活,首次比较久,后面比较快
编程就是在和编程语言的设计者玩一个故事接龙的游戏,真正了解设计者的讲的故事,才能把自己的这一段故事讲好
Facebook 的PHP与C++,HipHop For PHP,将PHP编译成C++源码。语言的特性吸引用户,用户群会反过来影响和改变语言本身
编译器和语言本身是两回事,同一个语言可能有不同的编译器实现,所以不能说A语言的效率比B语言高而是A语言的X编译器生成的代码比B语言Y编译器生成的代码更高效
全栈工程师最佳实践
GPL:通用解决方案语言,DSL:特定领域语言
建议在发明创造新的DSL之前,首先:
- 尽量使用自己熟悉的通用语言来解决问题
- 优化自己的解决方案,真正精简、优雅的扩展库
- 开源扩展库,根据其他人的贡献继续优化解决方案
- 脚本语言包装器
- 发明自己的DSL
脚本语言的优势:
- 脚本语言不需要编译
- 脚本语言常常不用关心清理内存,这个事情由引擎干了
- 脚本语言会针对特定领域做优化,比如PHP针对HTTP请求的优化
- 脚本语言常常是动态类型语言
- 脚本语言的抽象层次更高,更符合自然语言
- 脚本语言有包管理器
全栈游乐场
VPS
搭建自己的博客的步骤:
- 初始化。操作系统啥的
- Apache或者其他服务器
- MySQL
- 域名和路由,启动服务器,查看资源利用等等
- 安全防护和设置自动备份
VPS选择建议:
- 内存一般是VPS的瓶颈,至少选择512MB的
- CPU相对没有那么重要
- 硬盘的大小和读写速度是关键
- 客户服务
服务器安全
- 新建普通用户,不使用root登录
- 使用SSH的名值对登录,禁用用户名和密码的登录方法
- 禁用root账户通过SSH登录
- 安装一个防火墙
- 安装Fail2Ban,杜绝字典攻击
软件设计方法
设计模式的关注点在于:
- 高效编写代码
- 高可复用性
- 抽象带来的可读性
创建型模式:对于创建对象的过程进行了封装,作为客户程序仅需要去使用对象,而不再关系创建对象过程中的逻辑
JavaScript单例模式示例:
需求:当用户点击网站的登录按钮时,会弹出一个输入框,同时背景出现一个半透明的黑色遮罩,生成遮罩的代码如下:
|
|
以上代码在每次点击的时候都会创建一个新的div,显然是不合理的。使用单例的思想,创建之前首先检测是否存在,如果不存在就创建一个,代码如下:
|
|
在匿名函数的运行环境内,声明了局部变量mask,然后返回匿名函数,在这个函数对象创建时候会检查mask是否存在如果存在直接返回
“惰性初始化”模式:推荐对象的创建、数据的计算等需要耗费较多资源的操作,只有在第一次访问的时候才执行。
结构型模式:结构型模式主要解决类、对象、模块之间的耦合关系,例如:用一个统一的接口,适配所有可能的情况,用于多人合作或者兼容旧版的接口
其他结构型模式还有:桥接模式、组合模式、装饰模式、外观模式、享元模式和代理模式等
行为型模式:用来识别对象之间的交流模式并加以实现。
观察者模式:在这种模式中,一个目标对象管理着所有依赖他的观察者对象,并在他本身状态发生改变时主动发出通知
MVC架构中观察者模式也很常用,例如希望数据(Model)的变更可以被界面(View)察觉到。
架构模式: 教如何构建一个系统。关于以下两点:
- 多个职位(前端、后台)可以平行工作同时进行
- 构建一个软件系统的多种技术
MVC模式:本质在于代码的分离,Controller是这个模式的核心,控制器更新数据,数据变化通知控制器;视图的用户操作被控制器拦截,控制器更新视图内容。
工程师的水平高低并不在于敲代码有多快(越快越好),复杂性多么高(解决问题就好),而是能够快速地理解其他工程师的代码并且自己编写的代码也能够让其他工程师理解
设计原则
- DRY:在一个系统里,对于任何数据或者变量,都应该配置在有且只有一个地方,其他的地方应该引用这里的数据,那么在改动数据的时候,只需要调整一处。与这个原则相关的还有三法原则,当代码重复出现的时候,考虑是不是要有子程序替代它,如果出现了三次以上那么就这么干。
- 惯例优于设置:尽量减少需要配置的地方,此处举例PHP的Codeigniter的路由配置的例子
- KISS原则:大部分的系统设计越简单越好,有不必要的复杂性应该避免。如果一个系统非常复杂,就应该分解为多个简单地组件,做好足够的分解和抽象
- 最少知道原则:松耦合原则的具体事例。每一个单元都应该只知道关于其他单元的有限信息。每一个单元都只有自己关系密切的单元讲话,不和陌生人讲话。每个单元都只暴露出少量的API,隐藏内部实现原理,重构类的时候只要API不变,就不会影响这个系统
高效工程师
Move fast, with Stable infra(快速行动,稳定架构)
提速100倍
- 阅读英文材料,使用英文进行搜索,stackoverflow,中文阮一峰的博客等 V2EX
- 时间管理的四象限:如果平时没有做重要的事情,那么就会发现自己一直在做紧急的事情。
- 重要而紧急的事情,最好的判断力立即执行。但是要是一直重要而紧急就是在瞎忙
- 紧急不重要的事情:首先看能不能请人代劳
- 重要但是不紧急的事情,建议80%的时间放在这个象限里
- 不重要不紧急的事情:逛论坛、看电视剧、玩游戏、刷朋友圈,基本就是浪费时间,不值得花时间。学会正确的休息。
- 消除重复工作:记录自己的时间花费,然后想着怎么去优化
- 给自己留出不被打扰的时间:编写程序需要大量的精神投入,整块连续的时间很重要,也不要被自己想玩的想法打乱,坚持很重要。
- 番茄工作法
- 跨界思考:还能和整个项目中的产品、设计师等一起交流,要了解他们的思路
- 纸上头脑风暴:写文章,写下关键词然后层层分解。写程序先把每一步要做的事情写下来,类似伪代码
- 使用版本控制工具和构件系统
- 尽量拒绝加班,提高自己的工作效率,注重工作的结果而不是工作的时间
学习设计
工程师应该将设计与实现融合起来,给用户更好的体验。设计和工程师的分割不一定是最高效地解决方案。
设计基础
我们需要去了解一些东西然后才能将其他东西和他关联起来
设计的四大基本理论:亲密性、对齐、重复、对比
- 亲密:关系亲密的元素要放在一起,关系疏远的元素则要分开。位置的亲密性直接表现出意义的亲密性
- 对齐:左对齐、右对齐、上对齐、下对齐、斜线对齐、居中对齐
- 重复:视觉上要使用重复的图形和元素、线条和颜色等。比如:QQ空间重复的使用黄色和黑色,微信的绿色,京东的红色。
- 对比:如果两个元素(大小或者颜色)不一样,那就让他完全不一样,产生视觉冲击力
设计理念会影响写代码和设计网站架构的方式:
重复:提醒网站全局使用同样的加载图标
设计稿中有两个颜色相近的元素,假定他们是同一颜色~
设计工具
处理与创作:处理是处理设计稿,photoshop与Fireworks;创作是使用自身技术优势创作一些设计师不擅长的东西,响应式页面,APP交互与动画,CSS3动画和滚动视差
- Axure:全部产品信息架构和功能,以页面为最小单位,输出整个网站的页面脉络以及每个页面的交互框架
- Sketch:轻量级设计工具,基于线框图增强设计感,但是好像是mac专用
- Quartz Composer:图形化编程工具,专门用来生成各种复杂和细腻的动态视觉效果,以及可交互的界面原型
- 代码:用HTML/CSS实现响应式的高保真设计稿,然后放在云服务器上,给老板和客户看看意见
全栈思维
如果想拖延一件事,或者不想做一件事,总是能找到理由。懒惰的终极原因是想逃避这件事。
老板给您任务,根本不关心您有什么理由,只关心您完成没有 用诚恳的态度说明当前的进度以及未来能否如期完成,如果不能直接说出来
在职场中,评估一个人不是根据他的能力,而是他所承担的责任。在能力不足、困难重重的时候,唯有投入大量的时间才能保住这珍贵的信任。
新人没经验,知识不丰富,这都可以理解,但是以此为理由输出不合格的产品,就是自己的问题了
将自己的名字与自己的产品联系起来
沟通技能:
对平级同事授权,最好的办法就是诉诸对方的利益,度己度人
针对上司:要在20秒内让他知道您的目标
- 汇报:求表扬
- 请求:需要上司做事
- 询问:上司对于某项任务的要求
金字塔原则
任何事情都可以归纳出一个中心论点,然后这个中心论点有3-7个论据,一级论据本身也可以是论点,然后再引出二级的论据支持。只能有一个中心目标,不能是两个。
表达自己的想法:
无论想法多么复杂,经过多么复杂的推演,沟通的时候注意两点:一是让自己要表达的立场足够简单,二是围绕着唯一的立场去沟通
书中的例子,减轻了汇报的部分,主要传达需要帮助的部分。说白了就是突出中心论点,给论点找论据,其他的提一下就好。
示例:谈PPT
- 不要有太多文字,让听众关注自己
- 设定进度
- 对待错误:放松
- 录像对比,提高
几个意识:
- 自我意识:精准地察觉自己的情绪波动
- 社会意识:能够感知周围人的情绪,并敏锐地捕捉到周围发生的事情
- 自我管理:根据自身情绪,灵活地调控自身行为
- 关系管理:感知周遭的”情绪场“,掌控自我情绪并把握他人情绪,让双方进行更好地互动
后记
终于整理完了这本书的读书笔记,以前读过一些书但是静下心来整理还是第一次。书中对于技术的介绍大多都是浅尝辄止的,但是拓宽了技术的视野,后续我想要提升的话还需要对于提到的技术都做一些实践。整理这个读书笔试是在新年的假期,我一直以为自己能在一天之内搞定,最后发现用了两整天的时间包括晚上,也是对于自己消耗时间经验的积累。最后我今年真的开始改变了,加油,坚持下去~