怎样成为全栈工程师(Full Stack Developer)?

"Facebook 工程师说 Facebook 只招 full stack engineer,那么 Facebook engineer 都是怎样的人啦。"?

具体经验不重要,重要的是思维方式和学习能力。

首先说思维方式,那就是不为自己设限,不会想着自己是前端工程师,所以后端的东西我就一点也不碰。Facebook 的工程师,级别越高就需要保持越大的影响力。如何创造更大的影响力,就是寻找当前杠杆效应最明显的问题来解决。有些问题你解决了的话,投入进去的时间每小时能换回来一千美元;有些问题你解决了的话,投入进去的时间每小时能换回来一百万美元。然而哪些问题更值得解决,这是动态的,往往还存在衰减效应。如果现在性能瓶颈在后端,你做了一个季度两个季度优化后,瓶颈就已经不在后端了,你再优化下去衰减效应就会越来越明显。等瓶颈变成前端了,你是不是就说因为你不懂,所以不愿意碰?那就相当于寄望于公司有个前端很懂性能优化的人来解决,但如果公司没有这样的人那就没有人来解决了。 Facebook 的众多海报当中,有一张写的是「任何一个 Facebook 的问题,都不是别人的问题」。有问题,你就需要去评估是否值得解决。如果值得解决,你就应该着手去解决,而不是假设公司内会有另外一个人比你更合适解决这个问题。这时候很可能你就需要去做你从来没有做过的事情,需要学习你原本可能完全不懂的技术。如果你是个专门做数学模型的博士,加入 Facebook 原本是打算做搜索结果优化的,结果发现这不是最急需解决的问题,JavaScript 性能才是最需要解决的问题,你怎么办?如果你以为 Facebook 需要的是你做数学模型的经验,那你就错了。Facebook 需要的是你完成博士学位的学习能力。你从来没做过 JavaScript 并且觉得 JavaScript 很恶心?正确的做法是立即在网上买几本 JavaScript 入门的书连夜看完,然后着手分析性能瓶颈并且解决。在你完成手动优化后,你还可以思考一下能否把这做成自动化,例如说在代码提交时分析 JavaScript 语法树并且指出可能成为性能瓶颈的地方,又或者说从用户浏览器那里收集性能数据扔到 Hive 然后再从中分析产生瓶颈的特征。这些都可能涉及到一些你没有做过也没有学过的东西,但问题摆在那里你就需要去解决,而无论这要求你去钻研什么。

本文只把范围限定在全栈Web软件工程师,简称FSD(Full Stack Developer)

把技术当成生活,自己逼自己的结果

其实在任何公司工作,光凭工作的内容,很难成为FSD。有朋友可能不同意了,说在创业公司有很多机会做不同的工作啊,我想说的是,即便是创业公司,公司总是有主营的业务和方向的,就算能从前到后一个人做一个网站,那又怎样,从技术上说,无非也就是掌握了一种或几种数据库,一门或几门后台语言,掌握了html,js,css...大公司呢?更难了,大公司虽然方向很多,但是越是大的公司,个人的螺丝钉效应越明显,你可能成为领域专家,但很难有机会成为完整的机器的。那么全栈程序员的磨练靠的是什么?靠的是一种打心底里的执着和毅力,把技术当成生活,自己逼自己不断的猎取知识。

难以界定,每个人都有不同的理解

刚才其实没有鄙视能够完整做网站的人,相反,很是钦佩。至少本人现在在css上还不能算能完全独立。不过每个人对FSD的定义其实不一样,这跟个人的阅历有一定的关系。只想说,既不要对自己过分自信,也不要过分贬低。一方面,人外有人,天外有天,每个人覆盖到技术领域是有差异的;另一方面,FSD其实挺不容易的,不仅不容易达到,而且不容易获得存在感。正因为见的多,所以就越觉得自己渺小,我们经常说的,真正的大牛从来就是低调和谦虚的。而FSD在任何领域都不是那种呼风唤雨的专家,别人在讨论的时候可能永远都没有你插话的机会,其实你心里知道,自己还很肤浅。个人自认为是比较接近这么一个性质的程序猿,可以从我的博客的文章内容略窥一二。但是正如我不敢斩钉截铁地将自己定性到这么个层次,恐怕很多全栈程序员也不能将自己明确在这个定位上,因为总有人能站出来给你一个"反例"。

何去何从

从知乎上的回答来看,FSD似乎并不吃香。纵观人类发展历程,更细致的社会分工造就了生产力的提高。就程序员行业而言,越来越趋于细分话,似乎也是正常的趋势。作为FSD,实际上挺难的,主要是因为精力的限制,无法在广度和深度上兼顾。尽管如此,个人觉得FSD还是有很明显的优势的:

  1. 见多识广,解决问题的手段比较多,而且往往能够触类旁通的思考;
  2. 不容易被某种技术的新衰而左右,很容易转型;
  3. 合格的FSD往往具有超强的毅力和极客精神,这在某些情况下是很有用的;
  4. 由于能力广泛,又吃苦耐劳,适合创业;

个人理解

针对Web开发的话,稍稍谈一谈个人对全栈程序员能力的界定,大牛们轻拍:

  1. 用户体验层面,html45javascriptcss23,各种前端的框架...
  2. 后台业务逻辑层面,各种编程语言,现在主流的有JavaC#PythonRubyPHPNode.js...,以及配套的各种开发框架...
  3. 辅助层面可能会涉及到CC++等较为古老的编程语言,需要一定程度上熟悉掌握...
  4. 数据库,会设计和使用几种常用的数据库,mssqlmysqloracle...,数据库分析和优化
  5. 架构层面,能够设计灵活可靠,易扩展的软件架构和硬件架构。这个层面上要掌握的东西就很多了,网络、存储、操作系统、web服务器、web架构,安全等等...
  6. 一些基础理论层面的东西,算法数据结构、编译原理、网络基础...
  7. 数据分析,数据挖掘
  8. 管理层面,众人拾柴火焰高,一个人再牛b,精力是有限的,如果能够聚集并领导更多的人,那就更全面了。这包括项目管理,持续集成,敏捷开发,版本控制...
  9. 移动开发

如果你是FSD,有什么想说的呢?欢迎全栈程序员们留言交流

程序员能力矩阵

一个挺有意思的程序员能力界定,从程序员能力矩阵转载:

注意:每个层次的知识都是渐增的,位于层次n,也蕴涵了你需了解所有低于层次n的知识。

2n (Level 0)

n2 (Level 1)

n (Level 2)

log(n) (Level 3)

数据结构

不知道数组和链表的差异

能够解释和使用数组,链表,字典等,并且能够用于实际的编程任务。

了解基本数据结构时间和空间的折中,比如数组vs 链表,能够解释如何实现哈希表和处理冲突,了解优先队列及其实现。

高等的数据结构的知识,比如B-树、二项堆、斐波那契堆、AVL树、红黑树、伸展树、跳跃表以及前缀树等。

算法

不能够找出一个数组各数的平均值(这令人难以置信,但是我的确在应聘者中遇到过)

基本的排序,搜索和数据的遍历和检索算法。

树,图,简单的贪婪算法和分而治之算法,能够适度了解矩阵该层的含义。

能够辨识和编写动态规划方案,良好的图算法知识,良好的数值估算的知识,能够辨别NP问题等。

编程体系

不知道何为编译器、链接器和解释器。

对编译器、链接器、解释器有基本的了解。知道什么是汇编代码以及在硬件层如何工作。有一些虚拟内存和分页知识。

了解内核模式vs用户模式,多线程,同步原语以及它们如何实现,能够阅读汇编代码。了解网络如何工作,了解网络协议和socket级别编程。

了解整个程序堆栈、硬件(CPU+内存+中断+微码)、二进制代码、汇编、静态和动态链接、编码、解释、JIT(just-in-time)编译、内存碎片回收、堆、栈、存储器编址…

2n (Level 0)

n2 (Level 1)

n (Level 2)

log(n) (Level 3)

源码版本控制

通过日期备份文件夹

VSS和初级的CVS/SVN用户

熟练地使用CVS和SVN特性。知道如何分支和归并,使用程序库补丁安装特性等

有分布式VCS系统的知识。尝试过Bzr/Mercurial/Darcs/Git

自动化编译

只知道在IDE下编译

知道如何编译在命令行下编译系统

能够安装一个脚本构建基本的系统

能够安装一个脚本来构建系统并且归档,安装程序,生成发布记录和给源码控制中的代码分配标签。

自动化测试

认为所有的测试都是测试员的工作。

能够编写自动化的单元测试,能够为正在编写的代码提出良好的测试用例。

按照TDD (Test Driven Development)方式编写代码。

了解并且能够有效自动化安装,载入/性能和UI测试

2n (Level 0)

n2 (Level 1)

n (Level 2)

log(n) (Level 3)

问题分解

只有直线式的代码,通过复制粘贴来复用

能够把问题分散到多个函数中

能够想出可复用的函数/对象来解决大题的问题

使用适宜的数据结构和算法,写出通用的/面向对象的代码来封装问题的易改变的层面。

系统分解

N想不出比单一的文件/类更好的层面

如果不在同一平台或没采用相同的技术,能够把问题空间和设计方案分解。

能够设计跨技术/平台的系统。

能够在多个产品线和与外部体系一体化中虚拟化和设计复制的系统。同时也能够设计支持系统监视、报告、故障恢复等。

交流

不能向同伴表达想法/主意。匮乏拼写和语法的能力。

同伴能了解你在说什么。有良好的拼写和语法能力。

能够和同伴进行高效的交流

能够使用清晰的方式了解和交流想法/设计/主意/细则,能适应每种环境的交流

同一文件中代码组织

同一文件中组织没有依据

按照逻辑性或者易接近的方法

代码分块和对于其他源文件来说是易于是释,引用其他源文件时有良好的注释

文档头部有许可声明,总结,良好的注释,一致的空格缩进。文档外观美观。

跨文件代码组织

没够想过给代码跨文件组织

相关文件按文件夹分组

每个物理文件都有独立的目的,比如一个类的定义,一个特性的实现等。

代码在物理层组织紧密,在文件名上与设计和外观相匹配,可以通过文件分布方式洞察设计理念。

源码树组织

一切都放在一个文件夹内

初步地将代码分散进对应逻辑的文件夹。

没有循环依赖,二进制文件,库,文档,构建,第三方的代码都组织进合适的文件夹内。

源码树的物理布局与逻辑层次、组织方式相匹配。可以通过目录名称和组织方式洞察设计理念。

代码可读性

单音节的名称(在国内应该是那些类似用汉语拼音命名的习惯)

对文件、变量、类、方法等,有良好的命名。

没有长函数、注释解释不常规的代码,bug修复,代码假设。

代码假设验证使用断言,自然的代码流,没有深层嵌套的条件和方法

防御性编码

不知道这个概念

检查代码中所有的参数,对关键的假设进行断言

确保检查了返回值和使代码失败的异常。

有自己的库来帮助防御性编程、编写单元测试模拟故障

错误处理

只给乐观的情形编码

基本的代码错误处理,抛出异常/生成错误

确保错误/异常留在程序中有良好的状态,资源,连接,内存都有被合适的清理。

在编码之前察觉可能出现的异常,在代码的所有层次中维持一致性的异常处理策略,提出整个系统的错误处理准则。

IDE

IDE大部分用来进行文本编辑

了解其周围的接口,能够高效地通过菜单来使用IDE

了解最常操作的键盘快捷键

编写自定义宏

API

需要频繁地查阅文档

把最频繁使用的API记在脑子里

广阔且深入的API知识。

为了使实际任务中常用API使用更加便捷,编写过API的上层库,填补API之间的缺口。

框架

没有使用过主平台外的任何框架

听过但没用过平台下流行的可用框架

在专业的职位中使用过一个以上的框架,通晓各框架的特色。

某框架的作者

需求分析

接受给定的需求和代码规格

能对规格的遗漏提出疑问

了解全面情况,提出需要被规格化的整体范围。

能够提出更好的可选方案,根据经验的浮现给出需求

脚本

不具备脚本工具的知识

批处理文件/shell脚本

Perl/Python/Ruby/VBScript/Powershell

写过并且发表过可重用的代码

数据库

认为Excel就是数据库

知道基本的数据库概念,规范化、ACID(原子性Atomicity、一致性Consistency、隔离性Isolation、持久性Durability)、事务化,能够写简单的select语句

能够牢记在运行时必要查询中设计良好的规范化数据库模式, 精通用户视图,存储过程,触发器和用户定义类型。知道聚集与非聚集索引之间的差异。精通使用ORM(Object Relational Mapping对象关系映射)工具

能做基本的数据库管理,性能优化,索引优化,编写高级的select查询,能够使用相关sql来替换游标,理解数据内部的存储,了解如何镜像、复制数据库。知道两段数据提交如何工作

2n (Level 0)

n2 (Level 1)

n (Level 2)

log(n) (Level 3)

专业语言经验

命令式语言和面向对象语言

命令式语言,面向对象语言和说明型语言(SQL),如果了解静态类型vs动态类型,弱类型vs强类型则有加分

函数式语言,如果了解延缓求值,局部套用函数,延续则有加分

并发语言(Erlang, Oz) 逻辑语言(Prolog)

专业平台经验

1

2-3

4-5

6+

专业经验年龄

1

2-5

6-9

10+

领域知识

没有该领域的知识

在该领域中曾经至少为一个产品工作过

在同一领域中为多个产品工作过

领域专家。在该领域设计和实现数种产品/方案。精通该领域使用的标准条款和协议

2n (Level 0)

n2 (Level 1)

n (Level 2)

log(n) (Level 3)

工具知识

仅限于主要的IDE(VS.Net, Eclipse等)

知道一些流行和标准工具的备选方案

对编辑器、调试器、IDE、开源的备选方案有很好的了解。比如某人了解大多数Scott Hanselman的威力工具列表中的工具,使用过ORM工具。

实际地编写过工具和脚本,如果这些被发布则有加分

语言接触

命令式语言和面向对象语言

命令式语言、面向对象语言和说明型语言(SQL),如果了解静态类型vs动态类型、弱类型vs强类型则有加分

函数式语言,如果了解延缓求值、局部套用函数、continuations (源于scheme中的一种高级控制结构)则有加分

并发语言(Erlang, Oz) 逻辑语言(Prolog)

代码库知识

从来没有查询过代码库

基本的代码层知识,了解如果构建系统

良好的代码库工作知识,实现过几次bug修复或者完成了一些细小的特性

实现了代码库中多个大型特性,能够轻松地将多数特性的需求变更具体化,从容地处理bug修复。

下一代技术知识

从来没听说过即将到来的技术

听说过某领域即将到来的技术

下载过alpha preview/CTP/beta版本,并且读过一些文章和手册

试用过预览版而且实际地构建过某物,如果共享给其他人的话则有加分

平台内部

对平台内部毫无所知

有平台基本的内部工作的知识

深度的平台内部知识,能够设想平台如何将程序转换成可执行代码。

编写过增强平台或者为其平台内部提供信息的工具。比如,反汇编工具,反编译工具,调试工具等。

书籍

菜鸟系列,21天系列,24小时系列,蠢货系列...

《代码大全》,《别让我思考》, 《精通正则表达式》

《设计模式》,《人件》,《代码珠玑》,《算法设计手册》,《程序员修炼之道》,《人月神话》

《计算机程序设计与解释》,《事务处理:概念与技术》,《计算机程序设计模型》,《计算机程序设计艺术》,《数据库系统导论》 C.J Date版,《Thinking Forth》 ,《Little Schemer》(没找到其中译本)

博客

听过但是从来抽不出空去接触

阅读一些科技/编程/软件工程的博客,并且经常的收听一些播客

维护一些博客的链接,收集博主分享的有用的文章和工具

维护一个在编程方面,分享有个人见解和思考的博客

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏keinYe

外行学 Python 第十一篇 数据可视化

在 外行学 Python 爬虫 第九篇 读取数据库中的数据 中完成了使用 API 从数据库中读取所需要的数据,但是返回的是 JSON 格式,看到的是一串的字符串...

21230
来自专栏杨建荣的学习笔记

MySQL 5.5升级5.7小试

下午的时候接到业务部门的一个需求,他们有一个业务对性能要求比较高,在测试环境已经做了一些测试和优化,想看看在MySQL新版本中是否有一定的提升,现在使用的数...

55620
来自专栏程序亦非猿

Paging在RecyclerView中的应用,有这一篇就够了

经过一年的发展,AAC又推出了一系列新的组件,帮助开发者更快的进行项目框架的构建与开发。这次主要涉及的是对Paging运用的全面介绍,相信你阅读了这篇文章之后将...

9820
来自专栏悠风的采坑日记

ASP.NET(C#)操作SQL Server数据库

该段代码写在需要创建数据库对象的地方。其中Data Source为数据库服务器来源,本地服务器可用小数点表示;Initial Catalog为欲连接的数据库名称...

60320
来自专栏天马行空布鲁斯

分布式锁在JPA ID生成器中的应用

在现实生活中,很多场景都需要ID生成器,比如说电商平台的订单号生成、银行的叫号系统等。针对不用的业务需求,ID生成策略也不一样,比如电商平台的订单号可以由时间序...

11320
来自专栏WalkingCloud

CentOS6下使用pv+nc命令传输文件

由于有时Linux服务器可能网络等等其它原因没法通过rsync 或者scp的方式传输文件,那有没有更简洁的方式来进行文件传输呢

16920
来自专栏飞总聊IT

SQL 优化引擎内幕

SQL Server 的优化器是基于成本计算的,高质量的执行计划来自于对成本的准确估算。而整个计划成本的估算,则是基于对每一步操作或实现操作的每个算法的开销估算...

7520
来自专栏赵KK日常技术记录

Mysql查询及高级知识整理(上)

SQL:Structured Query Language,结构化查询语言。

8540
来自专栏大数据手稿笔记

面试题:InnoDB中一棵B+树能存多少行数据?

因为这是可以算出来的,要搞清楚这个问题,我们先从InnoDB索引数据结构、数据组织方式说起。

25720
来自专栏月小水长

开源一个小程序,还教部署那种。

之前有给小伙伴们承诺过一个开源一个小程序,今天开始开源一个部署上线的打卡小程序:一见打卡。

22730

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励