赞
踩
对于全栈工程师 ,业界并没有严格的定义 ,并不是说一定要一种都不能少地具备哪几项知识才能叫做全栈工程师 。我倾向于认为 ,应该从能力和思维方式两方面 ,来判定一个人是否是一个合格的全栈工程师 。
国外是怎么样定义的呢?在著名的问答网站Quora上有一个高票的回答:
全栈工程师是指 ,一个能处理数据库 、服务器 、系统工程和客户端的所有工作的工程师 。根据项目的不同 ,客户需要的可能是移动栈 、 Web栈 ,或者原生应用程序栈 。
简单来说 ,全栈工程师就是可以独立完成一个产品的人 。当客户让他去做一些舒适区之外的工作时 ,他敢于迎难而上 ,并成功完成任务 。
虽然流水线式的职业划分和工程管理有很多优点,但是它就像一把双刃剑,在带来高可控性、可用性和可管理性的同时,也给工程师带来了一些困境。
当工程师希望晋升到更高级的职位 ,如高级工程师或者管理岗位时 ,公司对他的大局观会有更高的要求 ,这就不仅仅是做好 “分内 ”的工作就行的 。高级工程师需要有对设计的理解 、对后台知识的了解 ,以及有跨团队推动项目的能力 。长期研究专精的专业知识会让一个人视野变窄 ,变成 “学术派 ” ,而不是 “实践派 ” 。
因为各司其职的工作流程有效率低下 、成本高的缺点 ,所以很多创业公司都不会配备齐全的流水线 ,而是希望采用更灵活的方式来组建团队 ,全栈工程师也因此成为了理想的选择 。但是全栈工程师的兴起还离不开这两个重要因素 :技术的发展 ,以及提供 PaaS服务的平台越来越多 。
而我推崇的全栈工程师则是与专精工程师不同的另一条道路 。全栈工程师除了在一个专精知识领域有深入研究之外 ,还以知识广博和解决问题能力强著称 。所以我认为有志成为全栈工程师的学习者 ,要有这样几个觉悟 。
一专多长的意思是 ,工程师首先有一个专精的方向 ,在这个方向上足够精通之后 (高级工程师级别 ) ,以此为突破点去学习更多的知识 ,增加自己的长处 。如果还没有获得某个方向上足够深入的理解 ,就不要囫囵吞枣地去学习其他领域的知识 。
“先精后广 ,一专多长 ”是指 ,建议初学者学习全栈技能的时候 ,先在一个特定的方向上有比较深入的钻研 ,然后再将学习目标渐渐推广开来 。比如先从前端方向入手 ,掌握了基本的 HTML、CSS 、JavaScript之后 ,不要转头向服务器端语言或者 App 方向发展 ,而是深入到性能优化 、 SEO 、多种框架 、响应式页面等前端细节中去 。经过一到两年的深入研究之后 ,再去学习其他方向 。
如果是毕业生或者初学者 ,我不建议在刚开始的一到两年接触太多技术 ,杂而不精 ,结果可能会对后面的职业道路产生副作用 。
为什么要强调在开始的时候要专精方向的重要性呢?因为这样您才能在求职的时候有一个“亮点”。
无论是毕业生还是社会招聘 ,仅仅满足招聘要求是不够的 。您需要在招聘要求的方向上以 200%的能力来得到这个职位 。一个求职者在整个流程中会受到多方考核 : HR考核您的成本和价值 ,专业面试官 (不是全栈工程师 )考核您的专业能力 ,经理考核您的沟通能力 。在所有这些考核中 ,其实每一环都是漏斗型筛选 ,会过滤掉一些人 。
让我再次重复这一点 ,作为求职者 ,一定要在某个特定方向上有非常深入的理解 。仅仅会做还不够 ,还要理解背后的原因 ,还有背后的背后的原因 。
我的第一条建议是 ,在考虑做什么项目的时候 ,围绕商业利益作为目标 。归根结底 ,技术是服务于商业目标的 。
老板雇用一个员工 ,不是因为他能写程序 ,而是因为他能帮助自己赚钱 。赚钱有两种方法 :减少成本 ,或者增加收入 。程序员如果能加快内部系统的运行效率 ,让产品制作流程更加顺畅 ,就是减少成本 。如果能让用户更容易地购买产品 ,或者提高服务质量吸引更多用户 ,就能增加收入 。在老板看来 ,程序员只是一个昂贵的劳动力 ,他会不会写程序都没那么重要 ,重要的是能赚钱 。
所以如果您想成为一个高级开发者 (或者高级设计师 ) ,就一定要学会这种思维方式 。
所谓 “商业目标 ”要广义地去解读 。对于直接制作产品 ,给用户使用的团队 ,就需要对外关注如何提高产品质量 、降低产品成本 ;对内应该关注如何优化流程 、减少错误率 。如果团队输出的成果是公司内其他部门需要的原材料 ,就要关注下游的需求 ,研究如何更好地输出成果 ,如何在流程上使得输出产品的过程更顺畅 。
关注商业目标需要持久的练习 。等到自己成为全栈工程师 ,或者成为团队管理者 ,更加需要在多个目标任务之中做出选择 。全栈工程师需要做和能够做的事情是很多的 ,他会很多技能 ,也负责处理很多工作 ,所以他更需要能力从诸多事情中找到最有商业价值的一个 :可能是制作一款工具提升团队效率 ,也可能是成本上的优化 。
全栈工程师可以做得事情越多 ,就越需要具备判断做什么的能力 。如果增加一个用户需要的功能是加分项的话 ,拒绝一个用户不需要的需求更加值得推崇 。
一切都要围绕商业目标来进行 ,包括您做的项目 、您的汇报方式 ,以及您在学习新技能时进行的取舍 。永远从商业目标的角度来决定学习哪些东西 ,而不是纯粹为了锻炼技术能力而去学习 。
每一个糟糕的体验背后都蕴藏着商机(腾讯HR的故事)
用户是谁
大巧若拙
意思是指,真正聪明的人,不会显露自己,反而从表面上看好像还很笨拙
做自己会用的产品
我如果开创一个公司需要招聘 “全栈工程师 ” ,我要求的三个能力就是一专多长 、关注商业目标 、关注用户体验 。
软件工程师事业指南告诉您 ,最核心的 3个词就是技术 、成长和声望 。技术是您的武器 ,成长就是好好打磨武器 ,而声望是您一生的积累 。怎样获得良好的声望 ?很简单 ——答应做的事 ,全部都要完成 。
那如果上司真的给出一个非常棘手的问题 ,您该如何回答 ?没错 ,您不能直接拒绝 。拒绝上司是很困难的 。但您也不能什么都答应下来 ,随后又无法完成任务 。那时候您会丢掉更多的得分 。正确的方法是 ,讲出事实 。
OSI模型义了整个世界计算机相互连接的标准,总共分为 7层 ,其中最上层 (也就是第 7层 )就是应用层 , HTTP 、HT TPS、FTP、TELNET、SSH、SMTP和POP3都属于应用层 。这是软件工程师最关心的一层 。 SI模型越靠近底层 ,就越接近硬件 。在 HTTP协议中 ,并没有规定必须使用它或它支持的层 。事实上 , HTTP可以在任何互联网协议或其他网络上实现 。 HTTP假定其下层协议提供可靠的传输 ,因此 ,任何能够提供这种保证的协议都可以被其使用 ,也就是其在 T CP / IP协议族使用 TCP作为其传输层 。
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的块为结束 。
五、高性能网站的关键——缓存
1. 服务器缓存
基本的数据库查询缓存
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 源代码后可以让它在服务器端生成站点) 。
用户来说,减少请求可以更快地加载页面,节省流量。如果用户是在手机上用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头,并且在文件内容有所修改的时候修改文件名。
六、大前端
1. 易于上手、难于精通
不同于某些“难于上手、难于精通”的职业,前端这一岗位就像暴雪公司的游戏设计一样:“易于上手、难于精通 ”。
前端技术的“易于上手”导致它在某些技术人员那里不受待见。他们认为HTML与CSS根本都不是程序语言,甚至认为JavaScript是一种功能不全的玩具型语言。所以直到我几年前毕业的时候,大学都没有前端相关的课程和专业。而市场对前端工程师的需求又很大,学校的输出跟市场的要求没有对接上,所以往往出现学生找不到工作,公司又招不到人的现状。
而一个框架是一个软件系统中可重用的一部分。它可能包含子程序、库、胶水语言、图片等一些“资源”,这些资源一起组成了软件项目。框架不像库,可能包含多种语言,某些功能可能通过API的方式让主程序调用。所以框架是一个更加灵活和宽松的名词,在具体的情景中,它可能指一个库、多个库、脚本代码,或者多个可单独运行的子程序的集合。
在出现一些热门框架时,建议开发者先去了解框架的创建初衷,合理使用,而不是盲目收集。
七、向移动端转型
1. 为什么向移动端转型
技术是服务于市场的,在市场发生变化的时候,如果开发者不能顺应变化,就有被淘汰的风险,毕竟很多开发者所服务的这个岗位诞生都不到十年,消亡可能也会在十年之内发生。对于目标是全栈工程师的人来说,技术能力更是多多益善。
在大公司,一些工程师士气低迷往往就是这个原因,成功来得很慢,失败也是。因为大家害怕失败,所以想把产品调整得完美无缺才发布。但是世界上成功的软件都不是完美的软件,而是在合适的时间发布的、刚刚够用的产品。如果它能活下来,在后面的版本中,它才有机会越来越好。
《精益创业 》中有一句话:“客户需求只有在实际使用中才能辨明,再多的前期调研也只能发现客户认为他们想要什么,而不是客户实际上想要什么。因此在不了解客户真实需求的情况下,只会多做多错。”
Android原生App
使用Java编程,如果有Java编程经验,Android原生App是最好的选择,因为用户量和用户比例都在稳定增长。
WindowPhone原生App
现在用户量还很少,除此之外也不知道如何评论… …
WebApp
技术是最简单的,传统前端开发的技能树可以无缝移植,包括 HTML5/CSS3/JavaScript等。应用场景包括浏览器中打开的WebApp、微信中的页面,或者混合模式App。WebApp的好处是天然无缝移植到所有支持Web标准的平台——甚至Kindle。
此外,对于中国开发者来说,微信公众号也是一个巨大的平台。之所以提到微信,是因为微信这个平台在中国的覆盖率几乎跟Android和iOS加在一起一样多,而且微信也有比较成熟的支付方式。
混合模式App对于用户来说跟其他App一样,需要去苹果AppStore或者Android应用商店下载。所以App需要对应的操作系统平台的技术,比如Objective C或者Java制作整体框架。App启动后,它的全部界面或者部分界面中,使用网络视图(WebView)技术来实现。WebView能加载显示网页,可以将其视为一个浏览器,它一般使用WebKit渲染引擎加载显示网页。
混合模式App一些常用的优化方法如下:
把WebView的部分或者所有资源打包在App中
缺点:发布包体积会变大
把需要加载的资源设置好预先加载
缺点:第一次访问的时候可能因为没有预加载资源而导致等待的时间比较长
使用HTML5 Manifest技术实现资源缓存
不要把整个App的主要逻辑都是用WebView开实现
要结合原生技术和WebView各自的优缺点,根据不同的场景选择合适的技术。原生技术的优点在于能很好地操作 App存储数据;实现页面间切换、高性能动画、大量数据的界面(比如可以无限滚动的图片流)。WebView的优点在于开发快、技术简单;前端开发者能够利用已有的CSS3和JavaScript知识;页面能够从服务器端更新;能够分享到社交平台;在多个平台上共用等。
设计的更像一个App,而不是一个网页
5. 混合模式App开发框架
PhoneGap通过对各个平台底层功能进行封装和抽象,然后通过JavaScript暴露出一致的API,让开发者可以通过JavaScript编写跨平台的原生APP。
虽然看上去“一次编写、到处运行”的愿景很美,但是PhoneGap有这样几个缺点。
PhoneGap的编程语言其实是JavaScript,这对于非前端工作者来说,学习起来和学习原生的Objective C或Java编程语言难度差不多,想精通JavaScript,相当不易。
PhoneGap编译的App包大小比一般的会大很多。
PhoneGap的目标是方便地创建跨平台应用,但是苹果和Google都发布了自己的人机交互指南。有些情况下,iOS程序和Android程序有着不同的交互原则。使用PhoneGap就意味着您的程序在UI和交互上,既不像原生iOS程序,又不像原生Android程序。
动画性能不佳。JavaScript终究无法和原生程序比运行效率,当制作一些动画效果,或者有大量数据的长页面的时候,就表现得很明显。
当然,PhoneGap的优势也很明显 。
八、持续集成
1.版本控制
SVN
集中式代码管理的核心是服务器,所有开发者在开始新一天的工作之前必须从服务器获取代码,然后开发,最后解决冲突,提交。所有的版本信息都放在服务器上。如果脱离了服务器,开发者基本上可以说是无法工作的。
在企业内部,使用SVN没有什么问题,服务器压力和内部带宽都能够承受所有员工一起操作SVN。但是在开源世界,这种架构方法就不行了,著名的开源软件的开发人数太多了,因此诞生了Git。
Git
Git是一个分布式版本控制软件,是天才工程师、Linux内核开发者Linus开发,目的是更好地管理Linux内核源码。其第一版于2005年发布,它与SVN最大的不同之处就是基于分布式的理念。
确定分支流程
基本上所有的特性和较大的bug修复都应该使用分支来修改。
定义主干原则,并且坚守它
我们团队的主干原则是“主干对应的代码必须是可以发布并且不会产生bug的”,如果不能保证新增的或者修改的代码符合这一原则,就在分支提交代码。任何人破坏这一原则引起bug,就请大家吃饭。
不要把逻辑的修改和代码格式化操作混在一起
如果您做了一些代码格式化的操作,就单独提交这次修改。比如您去掉了代码中所有的空行,那就单独提交一个 commit,然后再做一些逻辑的修改,再提交。这样可以避免“天哪,所有的东西都不一样了”,出现问题之后更容易追溯。
不相干的代码分开提交
也就是说不要在一次提交里修复两个bug。
保持工作代码库的“干净”
如果您有文件不想也不需要提交,就加入到忽略列表(ignorelist) 。不需要提交的文件包括编译后文件、配置文件和第三方依赖等。这样的好处是,您每次打开SVN提交界面,如果没有修改过任何代码,就会看见一个空的列表 ,如果修改过代码,就显示修改过的代码。这能提醒您不要漏掉任何需要提交的文件。
在我们日常工作编写的软件中,可能有绝大部分代码都不是我们自己输入的。我们“依赖”一些第三方的框架或者库。在Web前端开发中,我们依赖各种框架、库、静态资源等;在PHP开发中,我们依赖各种框架、库;在iOS App开发中,我们依赖各种库、模块、资源等。在复杂一点的依赖环境中,您所引入的第三方库也依赖其他的“第四方库” “第五方库”… …如何保证互相之间都不会出现冲突很重要。
如何让我们依赖的资源有条不紊地在一个地方进行管理和更新,而不用重复“搜索、下载、移动”这一系列繁琐的手工操作?这就要引入“包管理”。
Node.js
Node.js的包管理器npm应该是世界上最有名的包管理器。如果没有npm,Node不会有今天的普及度。npm收集了大量优秀的Node.js代码包,然后这些库吸引更多开发者进入Node.js开发的行列,反过来又促成了npm的繁荣,就像鸡生蛋,蛋生鸡一样。
npm如何引入依赖组件?
第一种是在自己项目的根目录里写一个package.json。这是一个json对象,在其中的dependencies或者devDependencies值列出所需要的模块和版本,然后用命令行切换到项目根目录,运行npminstall。通过这种方法,其他人在得到您的代码之后,仅需要一个package.json文件,就可以简单地使用npminstall命令来安装所需要的所有依赖。模块会全部下载到node_modules文件夹。
“dependencies”: {
“gulp-util”: “2.2.14”,
“through2”: “~0.4.1”
},
因为node_modules文件夹里全都是第三方代码,实际上是脱离于自己项目的代码库的。所以应该在.gitignore或者 SVN的忽略文件列表里忽略掉node_modules整个文件夹,而且所有项目成员也不应该修改node_modules里的任何东西,否则在将来npm安装的时候可能会丢失您的修改。如果发现某个模块有修改的必要,要向原作者提出issue。或者推送请求。
有合适的分离粒度
最小知识原则
一个组件或者对象不应该知道其他组件或者对象的内部实现细节。在QQ空间中,我们的配色组件跟其他组件是完全分开的,二者没有依赖关系。一个组件或者对象不应该知道其他组件或者对象的内部实现细节。在QQ空间中,我们的配色组件跟其他组件是完全分开的,二者没有依赖关系。
DRY(不要重复您自己)
特殊的功能只能在一个组件中实现,在其他的组件中不应该有副本。这是我们的一个严格要求。
最小化预先设计,只设计必须的内容
通过良好的层级,让文件易于找到
在代码层面,有一致且可执行的命名规则
从路径名到文件名都有一致的前缀、后缀、版本规则。整个团队有一致的命名风格和注释风格。
Make和依赖关系
Make是一个经典的构建工具,现代很多构建工具(比如Grunt、Gulp等)都参考了它的一些基本原则来设计。 Make的基本模型是:定义一个任务时首先声明依赖关系,然后说明根据这些依赖调用哪些应用程序来生成目标文件。因为每一步都需要使用不同的应用程序调用不同的数据,所以这里面需要设置依赖关系。
另一方面,使用包管理工具可以把项目需要用的第三方包,以及每一个包的特定版本,都集中在一个配置文件中。此后,我们通过一句命令,就可以下载这些包到本地的开发环境。每个软件包都会涉及其他的软件包,软件包里程序的运行需要有一个可执行的环境(要求有其他的程序、库等),软件包依赖关系正是用来描述这种关系的。
所以, “依赖关系”既属于“包管理”,同时又属于“构建工具”。
Grunt和Gulp
Make很强大,而且在全世界范围内几乎所有的计算机领域用了几十年,它的稳定可靠经过了广泛验证。不过从学习成本角度来说,它需要学习者具备一些Linux编程的基础,难度较高。所以,Grunt和 Gulp诞生了,它们都是用 JavaScript来实现的构建工具。
Grunt引爆了前端架构工具的概念,得到了广泛的应用。现在,Grunt的生态环境已经非常庞大,越来越多的开发者着手Grunt开发,为它添砖加瓦。但是Grunt有几个问题 。
配置项过多。每一个插件的使用都需要配置输入项和输出项,使用比较繁琐。
子任务间的协作基于文件。基于文件的坏处是,后一个子任务必须等前一个子任务的过程完全结束,才能开始它的流程,这样比较慢。而且磁盘读写速度远远慢于内存读写。
所以虽然Grunt有先发优势,但是由于它有几个痛点没有很好地解决,所以又诞生了Gulp。
Gulp的意思是 “大口吸” ,它最初的logo是一杯饮料,上面有一根吸管,很形象地跟它的宣传语相呼应:“基于流的构建工具” 。与Grunt最大的不同就在于,Gulp基于 “流 ”的理念。
Gulp基于Node.js的流的概念,所以前一个任务的输出就是后一个任务的输入。
从语法风格上来讲,编写任务的过程更像是 “编程 ”,而不是 “编写配置” 。Gulp通过对接前一个任务的输入和后一个任务,就像一个管道,二者可以同时进行,不输出在磁盘中,没有多余的中间产物,性能更加高效。
当前,Gulp的社区还远不如Grunt成熟,有些功能的插件,Gulp可能就没有。不过从个人偏好来看,我更倾向于Gulp,它的技术理念更好。
九、理解编程语言
1. 全栈工程师最佳实践
通用用途语言 VS 特定领域语言
很多编程语言倾向于通用解决方案,而不是只解决具体问题。这些语言都被设计为可以在任何领域使用,比如C、Java、Python和XML,它们被称为 “通用语言 ”(General Purpose Language, GPL)。我们可以看到用 C编写的所有类型的软件,从游戏到客户端软件,从服务器端软件到手机端软件。
与之相对应的,有些编程语言被设计为特定领域专用,叫做 “特定领域语言 ” (DSL)。DSL的目的是解决特定领域的问题,而不是像GPL一样可以解决任意的软件问题。DSL在计算机软件开发中十分常见,比如前端开发中常见的HTML和CSS就是一种DSL,专用于Web开发。MySQL是一种DSL,专用于操作数据库。Make是一种DSL,专门用来处理Shell脚本操作系统文件输入和输出。
如果您是一个以解决问题为目标的全栈工程师 ,我建议您在考虑发明一个DSL之前先考虑以下方案 。
尽量用您熟悉的通用语言来解决问题 ,比如Python、Java或C++。
优化您的解决方案,提炼出一种真正精简、优雅的扩展库。
开源您的扩展库,根据其他人的贡献来继续优化解决方案。
如果想简化配置文件的语法,可以创建一个脚本包装器来专门为库工作,这就是您自己的DSL。
如果最后您还是想进一步优化下去,那就发明您的DSL吧。
框架和库拓展了语言
在快速开发中,真正重要的是库,全栈工程师的目标往往是快速解决商业问题,不一定需要长期完美的方案。使用方便好用的框架能大大节省学习成本和开发时间,所以有些时候我们的技术选型步骤是:先选择框架,然后选择语言。
脚本语言,是指支持用脚本的方式编写程序的语言,它无需编译即可直接在运行时环境中解析。在操作上,它缩短了传统的 “编写编译链接运行 ”过程。脚本语言通常具有简单、易用的特性,而且常常很短小。
相比编译语言脚本语言有更高的开发效率,但是在执行效率上会有所牺牲。由于现在的趋势是硬件成本越来越低,而工程师的人工成本越来越高,所以脚本语言的使用空间越来越大,有一些脚本语言( Python、Ruby )已经在成熟的商业网站中使用。
不同的脚本语言有不同的设计原则,但是它们往往有一个共同的目标,就是以简单的方式,快速完成某些复杂的任务。
脚本语言不需要编译
脚本语言的特点是无需编译即可运行,它在对应的运行环境中直接运行,运行时通过解释器来逐句解析。
因为语言跟对应的解释器(或者编译语言跟对应的编译器)是分开的两个概念,所以从科学上讲,只要给定合适的运行时环境和库支持,任何语言都可以作为脚本语言来使用(也就是编写脚本) 。也就是说, “编写脚本”是对语言的一种使用方法 ,而称某种语言为脚本语言是一种工程上的约定俗成的用法,而不是科学上的定义。
而且另一个问题是,无论是脚本语言还是编译语言,最终都需要编译成机器码让机器来执行。比如JS语言 ,在v8引擎中被编译为机器码然后执行,如果是使用Node.js。那么这个机器码可能会被缓存起来,这样的话,跟编译语言就没什么区别了。
脚本语言常常不需要关心清理内存
因为脚本语言的设计目标是快速写出能运行的程序,它更倾向于取悦工程师,而不是优化性能。所以在语法上就忽视内存管理,而该语言的解释器则各显神通,把清理内存垃圾的重担揽在自己的黑盒里面,无需工程师关注。
脚本语言常常会对特定领域优化
脚本语言常常是动态类型语言
脚本语言的抽象层常常更高
脚本语言常常有包管理器
十、全栈游乐场
1. VPS
虚拟专用服务器(VPS)是把一台服务器分割成多个虚拟专享服务器的优质服务。每个VPS都可分配独立公网IP地址、独立操作系统、磁盘空间、内存、 CPU资源、进程和系统配置,模拟出 “独占 ”使用计算资源的体验。
比较廉价的选择是虚拟主机(Virtual Host),又称虚拟服务器或虚拟空间。虚拟主机将一台服务器的某项或者全部服务内容逻辑划分为多个服务单位,对外表现为多个服务器,从而充分利用服务器硬件资源。
如果使用虚拟主机,跟其他人共享CPU和内存等资源,这就像是合租。如果其他人在使用卫生间,您就没法用了。虚拟主机的好处是很便宜,国内一些服务提供商提供年费仅几十元的虚拟主机。虚拟并非指不存在,而是指空间是由实体的服务器延伸而来,其硬件系统可以是基于服务器群,或者是单个服务器.
为什么推荐一个全栈工程师买一台VPS自己玩玩?
对网站全貌有所了解
如果采用第三方的托管服务来搭建博客系系统,新建一个账号就可以开始写了,好处是很方便,缺点是在自定义功能上比如绑定独立域名,安装插件和修改路径格式代没那么灵活。
如果有瘾vps搭建一个博客网站就麻烦一些。
初始化。linode提供一键安装操作系统,等待几分钟操作系统就安装完成了。
安装最新版的Apache。启用Apache的rewrite等模块,WordPress的URL重写会用到。
安装MySQL数据库,配置WordPress的数据链接。
配置域名和路由。包括访问路由配置,日志配置,网站域名和别名等,启动服务器,查看资源利用等等。
当然也不要忘了安全防护和设置自动备份。
看上去很折腾,不过这种折腾是有意义的,因为他那里在操作的过程中理解了web工作原理。
时间就是金钱
推荐使用vps的第二个原因就是稳定。如果您想把精力集中在有用的技术上,而不是服务器无响应或者IP北墙等一些无聊的琐事,那么vps是最有性价比的选择。
部署自己的环境
学习Linux
理解HTTP
通过自己去配置和操作服务器,会让前端工程师也得http有更好的理解。
内存一般是vps的瓶颈
CPU是相对没那么重要的性能指标
硬盘的大小和读写速度是关键。
还有一个重要的考虑就是客户服务。
关注服务及安全
能力越大责任越大,当你有了安装vps操作系统的能力,您就一定要学会保护自己的服务器。
操作系统的选择
域名解析
一般来说,域名购买商和服务器提供商都提供DNS解析的能力,不过域名在哪里注册和域名在哪里解析是两回事。
因为国内网络环境比较复杂,用户可能来自电信、联通、移动、教育网等网络,所以建议把域名的域名服务器设置为国内的智能DNS提供商,比如DNSPod。DNSPod除了可以根据用户IP来给出最佳的IP以外,还提供额外的功能,比如网站监控等增值服务。
云服务器
十一、高效工程师
1. 提速100倍
阅读英文资料
英文的技术资料更多。
stackoverflow有完善的鼓励机制。
谷歌的搜索能力非常强。
英语世界的语言风格比较严谨。
时间管理四象限
消除重复工作
给自己留出不被打扰的时间
番茄工作法
或许每个工程师会在不同的环境中,跨不同的界,但是在未来,我认为跨界出来的那部分能力才真正定义了“您”。
使用版本控制和构建系统
十二、学习设计
在前面的章节里“如何成为全栈工程师”里,我给有志成为全栈工程师的同学的的第一个建议是“关注商业目标”,第二个建议是“关注用户体验”。而好的设计师优秀用户体验的必要非充分条件。
科学家和工程师
首先,一个事实是:过去的工程师普片不在意设计。有意无意,他们忽视设计的重要性。
知乎网站上有一个帖子,问题是“为什么部分开发工程师不喜欢调节界面UI细节?”。我比较赞同下面这个回答:
我发现程序员大致可以分为科学家和工程师两类,科学家关注技术是否优越,而工程师关注产品是否完美。和科学家类型的程序员合作项目往往是件痛苦的事情,他们太过关注自己手中的的锤子是否先进,却不在意自己敲进去的钉子是否平整光滑不扎屁股,更不要说这可钉子是不是跟其他钉子对齐里。那些“资深”程序员更是如此,那个年代很多用户体验技术不成熟,能做出一个能用的东西已经不易,更不要说做出一个性能还算不错的产品。抱着这个想法走到今天,大多数应该被淘汰的程序员反而做到更高的位置,开始拿这种过时的想法熏陶小弟。(来自陈鑫的回答)
我们的解决方案:视觉设计师关注设计模块和整体氛围,只需要给出一份为PC设计的视觉设计稿。让有一定合计理论基础的前端工程师根据拿到的PC设计稿直接创建可以适配多个平台的页面,也就是一个“响应式”的页面。
另一个例子,我们想在页面或者App中创建一些动画效果。在老式Web设计中不会有很多动画,但是现在,页面和App更强调每一个操作都给用户动画反馈,有些是为了更炫,有些是为了给用户操作反馈。但是浙西动画很那在设计稿中体现,这会给设计师和工程师带来很大的沟通成本。
我们的解决方案:让有一定设计功底的前端工程师主动提出自己对动画而见解,做出效果之后再反馈给设计师去确认,优化后的流程十分高效。
设计的四大基本理论是:亲密性、对齐、重复、对比。
亲密:关系亲密的元素要放在一起,关系疏远的元素则要分开。位置的亲密性直接表现出意义的相关性。
对齐:左对齐、右对齐、上对齐、下对齐。斜线对齐比较简单,居中对齐很难处理,新手不要尝试。
重复:视觉上使用重复的图形和元素、线条和颜色等。比如QQ空间重复使用的换色跟黑色
、微信的绿色、京东的红色等。
对比:如果两个元素(的大小或者颜色)不一样,就让它完全不一样,产生视觉冲击力。
所以“设计感”其实是“科学”而不是“艺术”。这些只是理论或者“规则”,规则总是可以被打破的,但是前提是要熟练掌握这些规则。在没有掌握这些规则之前,请遵循规则。
十三、全栈思维
1. 有兴趣就够了吗
作者讲了一个把一本英文书籍交给两个很有兴趣做翻译的年轻人的故事,结果由于各种各样的理由延期交稿,延期里也不主动告知,而他们完成的部分也只能算勉强及格,错译、漏译的情况常常出现,可能存在一些能力问题,但他们给我们的感觉却是根本就不上心。
如果想拖延一件事,或者不想做一件事,总是能找到理由。懒惰的终极原因就是您想逃避这件事。对于所有刚开始工作的年轻人,我告诉你们:老板给您的任务,根本不关心您有sm理由,只关心您完成没有。
有人认为兴趣是成功的老师,无法完成某些事情是因为没有兴趣。其实我认为耐心是一种能力,有些人天生缺乏这种能力。在能力不足、困难重重的时候,唯有投入大量的时间才能保住着珍贵的信任。
新人没有经验、知识不丰富,这都可以理解,但是以此为理由输出不合格的产品,那就是自己的问题。
好的管理者能让平凡的员工做不平凡的事
高效能的管理者并不奢求完美的人才,他能让平凡的人成就不平凡的事业
《卓有成效的管理者》中的核心是5个思维习惯,这5个思维习惯环环相扣,非常经典。
有效的管理者知道她们的时间用在什么地方
有效的管理者重视对外界的贡献
有效的管理者善于利用长处,包括自己的长处、上司的长处、同事的长处和下属的长处。
有效的管理者集中精力于少数重要的领域,在这个少数重要的领域中,如果能有优秀的绩效就可以产生卓越的成果。
最后,有效的管理者必须善于做有效的决策
每一条都会花一章的篇幅来展开说明,每一章都有些让我醍醐灌顶的部分。比如“有效的管理者重视对外界的贡献”。
重视贡献,才能使管理者的注意力不为本身的专长所限,不为其本身的技术所限,不为其本身所属的部门所限,才能看到整体的绩效,同事也才能使他更重视外部世界。
沟通能力的评判往往是非常微妙和主观的,并没有一份考题能证明您的沟通能力好或者差,只是面试官能根据自己的判断来决定。为了避免无休止的争论,所以刚脆不告诉拒绝原因是最好的。
沟通是软技能
针对目标听众
佛家有一个词叫“度己度人”,就是在帮助别人的过程中,其实也在帮助自己。所以反过来想,作为需求的请求方,最开始就得找到那个很关键的人,对于他来说,帮助您对他是很有好处的。也就是说他能把这件事当作i自己的冠军任务。如果您的要求对于他人纯属累赘,那么他人自然不愿意帮助您了,任您多么会沟通,最终都不管用。
所以,授权给平级的同事的时候,最好的方法就是诉诸对方的利益。如果一件事情可以对双方的KPI都有好处,那么对方也愿意帮助您一起分担这个任务。如果您把不擅长的事情授权给对方,而作为交换,能给对方一些资源,那也是诉诸利益的一个好方法。
其次的方法就是把问题上升到上级领导,让上级领导安排资源,但是这种方法不能经常用,否则上司会认为您不会主动解决问题,只会提出问题。被授权的那一方也觉得您在拿领导压制他,可能会存在负面的情绪。
有方法
麦肯锡的金字塔原理就是,任何事情都可以归纳出一个中心论点,而此中心论点可由3至7个论据支持,这些一级论据本身也可以是论点,被二级的3至7个论据支持,如此延伸,状如金字塔。使用金字塔方法的前提是,您的有一个中心目标。不能是两个,更多更不行,只能是一个。
看到这里,这本书就读完了!
作者:Dunizb
链接:http://www.imooc.com/article/17295
来源:慕课网
本文原创发布于慕课网 ,转载请注明出处,谢谢合作
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。