美文网首页前端那些事我爱编程
过去的一年,我从准PM转变成了一个前端

过去的一年,我从准PM转变成了一个前端

作者: 云峰yf | 来源:发表于2018-02-15 17:13 被阅读71次

    化茧期

    去年的春节之际,我还在为自己的未来苦恼着。

    我原本以为我可以成为一名优秀的产品经理。

    还记得最早接触产品是高中时期,那时候给某在线教育机构提了一些粗略的建议,他们奖了我一个实习生的身份,可以边上学边上班。寒暑假可以上北京坐班。

    在此期间,我一直将自己当做一个准PM看待,除了课堂上教的计算机基础知识外和常规的产品助理工作内容外,还读了一些产品书籍比如《人人》、《失控》、《浪潮之巅》、《用户体验要素》等。

    但很不幸,这家公司内部组织架构产生了巨大的变动,我转不了正了。

    偶然得到的去腾讯课堂实习的机会也失之交臂。

    可学校的课还是要上的,实习是不可能实习的,学校里的老师个个都是人才,说话又好听,不如在学校做点东西。

    后来我就打造了一款这样的产品:成绩有毒,用来提供选课前的参考数据,比如哪个老师挂科最狠之类的。


    成绩有毒

    这款产品巅峰时期发展了4000+用户,当然,全部是我们学校的学生。但最后还是死于管服务器的老师手下:他们觉得这是个黑客软件,直接把教务系统换了一个...

    产品虽然死掉了,却让我喜欢上前端这门最接近用户和产品的技术了。从此我的职业生涯从产品修正为前端。

    破茧期

    这就要从3月时我抱着试一试的心态参加了网易春招说起了。

    春招

    冥冥之中注定,网易会成功地夺走了我的第一次,我也体验到了面试这种痛并快乐着的活动。


    网易春招面试通知

    这个时期的我,还是只会切图,js完全是靠着突击红宝书恶补的弱鸡。既紧张又娇羞的我,在经验丰富的小哥哥小姐姐面试官面前,完全就是一只待宰的小肥羊...

    这场网易春招笔面试的结果自然是惨败的,后来好不容易又抓住一个腾讯的面试机会,然而一面挂...

    我的春招就以2战2败的战绩收场了。

    也许是失败更能激起人的斗志,在接下来的两个月里,我做了成绩有毒,并准备以它作为简历上的项目经历去面试。顺便再读了《YDJS》、《CSS 揭秘》、《Pro Angular》、《HTTP权威指南》等书籍,以及freecodecampleetcodejs 30 days的刷题,就为秋招一雪前辱。

    秋招

    17年的秋招,似乎比以往来的更早些。还未进入状态,阿里就拿了我的一血:2017.07.16 阿里

    我天真地以为答得不错,殊不知这种感觉是面试挂前的先兆。之后的一个月时间,阿里的面试状态一直是面试中,可是我知道,已经凉了。即便我还做了笔试题

    8月16号,我迎来了面试轰炸:

    最后貌似还是抓住了秋招的尾巴,在8月31号成功上车,拿到了现在的offer。

    不过人生就像一颗巧克力,你永远不知道下一颗是什么味道。9月6号,腾讯突然给了我面试机会:2017.09.06 腾讯。可是,鹅厂的内推批是9月7号结束...这次面试自然没了下文。

    上完学校的最后一堂课后,我踏上了归家的旅途,准备好好放松一下秋招一直以来紧绷的神经。

    可是命运之神就是那么爱开玩笑,鹅厂再次给了我面试机会:2017.10.16 腾讯。持续放松了一个月的我,自然不堪一击。

    成长期

    回到家后,拿到offer的喜悦被腾讯的一面挂冲散的一干二净。这种结果仍旧提醒着我:你个菜鸡。

    的确,这个时间节点相比于我上半年对前端的知识储备,已经丰富了很多,算是踏入了前端的圈子。但还不够,我还是太嫩了。

    综合各个面试官的反馈,在前端领域内我目前至少有四处软肋:

    1. 缺乏前端工程化经验
    2. 没有深入理解库、框架设计原理和源码
    3. 缺乏服务端常识和经验:包括后端语言、操作系统等
    4. 缺乏性能优化经验

    如果说我要成为一名优秀的前端工程师或者Web工程师的话,这就是我的痛点,痛点找到后,接下来就该做需求分析并考虑如何解决问题了:这当然没有什么比实习更适合去引导我去做这两件事了。

    11月1号,我抵达北京,开始了我的实习之旅,用了将近一个月的时间熟悉环境与适应工作:2017.11.06-2017.12.01实习小记

    这三月有余,又让我对不少事物产生了新的体验和感悟:

    工程化

    我先拜读了工程化的两本经典著作:

    读完之后我得出一个结论:工程化其实就是将项目控制在自己可控范围内的各种办法。这些理论需要我在实际的开发中,不断思考、验证、调整。

    我想以这几个角度来谈谈我现在所理解的前端工程化:

    1. 模块化和组件化
      1.1 CSS模块化
      现在的前端项目越做越大,但很多人却忽略了对CSS的工程化,一个或者几个项目里CSS代码千奇百怪。好在Less、Sass、PostCss等给我们提供了嵌套、变量、混入、函数等强大的功能。

      比如说,业务各产品线的UI和通用页面设计需要统一风格,但只有个别样式如颜色、背景等不一样,不同产品线就可以通过$example-bg-color和@mixin example-header()等变量、mixin轻松实现出自己的页面。

      1.2 JS模块化
      大部分前端项目都考虑了这一点。比如一个vue项目:

      • 路由模块可以交给vue-router做
      • 状态管理可以交给vuex做
      • 工具函数和时间函数可以交给lodash和moment做
      • 一些项目里用到的公用代码可以放进一个commons文件夹下

      但是!这只是以功能来划分模块,并没有以设计层次来划分模块。比如说有一个页面,它里面有一个非常大的表单(有15-20个表单项),这些表单项有表格、树、单选、多选、单行输入框、多行输入框、开关等多种类型,它们之间的业务逻辑也被设计的很复杂(产品本身就很复杂),而后端给的数据结构也非常恶心,是一个对象套数组套对象的数据结构,你需要从里面拿出一个个表单项(有些树的子树还分散到各个对象里)。这时如果只把代码写在一个vue文件中,估计过一个星期就只有上帝才能看得懂了。

      不过,如果此时我们假设后端给的数据结构就是标准、纯净的呢?那是不是直接用就行了?如果后端不能提供的话,我们就需要对数据进行一定的处理,这就是一个数据处理中间层。同理,我们发送数据给后端之前也可以先给这一层处理。当这样的情况多起来之后,我们还可以再抽象一层-->BFF

      1.3 组件化
      组件化其实就是CSS模块化+JS模块化的封装,使用组件的人压根不关心里面的细节。而世上本没有通用组件,业务组件用的地方多了,也就有了通用组件。

      后端习惯把前端组件叫做控件,因为C#、Java的安卓甚至MFC就是这样称呼封装起来的一个组件的。而Angular、React、Vue的组件和Jquery的插件也没有本质上的区别,只是一坨代码的封装产物罢了。

      不过区别还是有的,没有使用MVVM框架的组件注定难以维护,因为那些代码只有上帝看得懂。

    2. TDD(测试驱动开发)还是BDD(行为驱动开发)?
      B端的产品,业务逻辑复杂的让开发者都不知道如何使用它的功能。每次提测,测试们都用尽几千个测试用例换来的几百个bug。

      即使是我们组的大牛之一,我的二面面试官,都不敢轻易重构他的代码:“我可不想凭空多出几百个回归性bug。”

      这种情况对前端、后端、测试都是一种摧残。

      “TDD还是BDD(先写测试用例还是先设计预期行为)?”这个问题摆在了我们眼前。

      而前端的自动化测试又主要分为两部分:e2e测试(关注界面)和单元测试(关注数据)。如果先写测试用例的话,会占据一部分开发者的时间,并且前端功能变更的频率非常高,说不定会得不偿失。

      倘若采用BDD的话,我们的设想是这样的:产品经理的PRD用自然语言把功能描述出来(设计好预期行为),然后工程师开始开发,之后将这些自然语言(比如第一步:打开xx页面,第二步:点击xx按钮...第n步:得到xx结果)转化成测试用例保存起来,最后进行批量测试,得到测试结果和报告。

      关于具体的技术,我也做了一个简单的调研,目前开源界我能找到的最好的这类工具是阿里的uirecorder,但它也只能录制生成测试用例,并不支持自然语言生成测试用例。无图浏览器是一个很好的突破口,比如google的puppeteer

      前端主要的开源测试工具
    1. 沟通
      前端工程师在一个工作流中处的位置很特别,它需要与设计、产品、测试、后端进行沟通交流。

      程序间沟通况且需要一个协议,人与人之间更需要建立一套协议了(我认为B端产品尤其需要),这需要熟悉各自岗位背景才能双赢。根据开发流程来说,我们需要有至少五个规范:

      3.1 前端规范(脚手架、npm包管理、CI、静态资源管理等)
      3.2 产品规范(原型、PRD、需求变更规范)
      3.3 设计规范(比如Ant、Material)、可从此衍生出适合自己业务场景的UI库、图表库等
      3.4 前后端规范(接口)
      3.5 测试规范(测试用例、自动化测试)

      不过此等大计不是我们这种码农能影响的,只能希望各方老大们能达成一致,减少我们搬砖码农在非编码问题上的时间浪费。

    2. 自动化
      “聪明的程序员拥有高明的偷懒技巧。”面对一个需要两小时解决的任务,不如花一小时五十五分钟写一个自动化工具然后五分钟解决它。下面是我对前端可自动化部分的认识,虽然部分功能我们自己还没实现......

    • mock接口和接口管理
      在后端没开发完接口或者接口GG的时候,拥有一个可mock的接口管理平台是多么的幸福。我们使用的是大搜车团队开发的easy-mock

    • 脚手架
      在项目数量和种类都很多的时候,有一个好的脚手架会让一线开发人员专注开发业务。

      在我的幻想中,当开始一个新项目时:

      • 有多种项目模板供我选择。比如库项目、业务类项目、CMS类项目。
      • 能一键生成组件、页面、静态页面等。
      • 切换proxy地址的时候可以不重新构建。
      • 除了配置文件,还支持环境变量、CLI来配置项目,简单项目也可零配置。
      • ......
    • CI
      每天写完代码后,生产环境自动构建+打包+测试+线上监控是件多美好的事情~

    源码

    无论是出于准备面试的源码问题还是学习优秀代码的动机,今年我还是陆陆续续地读了Vue和Moon、Lodash、zepto和jquery、element的部分源码。

    1. 首先明确框架/库解决了什么问题?比如说:
      1.1 Vue解决的主要问题就是将Dom->数据和数据->Dom的转换过程屏蔽了,不需要工程师手动操作dom,而只需要关注数据就ok了。
      1.2 lodash解决的是js原生工具api不够用的情况,比如求数组的并集交集,对函数进行节流防抖动等。
      1.3 zepto和jquery解决的也是js原生api不够用的情况,只不过比lodash涉及到范围更广,比如DOM、BOM等。为什么今天我们说jquery不值得用了,因为随着js本身的发展,很多原生api也逐渐完善,根本不需要借助第三方库也能实现一样的效果了。
      1.4 element解决的是通用UI组件不够用的情况,比如表格、单选框、多选框、树形多选框、警告框等。
    2. 它是怎么解决问题的?
      弄清框架/库解决的问题域之后,我们就可以探索它们解决这个问题的具体过程了,这个过程通常是打断点调试一步步跟踪源码走向,比如说:
      Vue的屏蔽手动更新DOM的过程,会有:
    • 创建Vue实例的过程(为什么我们要new Vue()?为什么组件的data需要返回一个函数?)
    • 从HTML中收集所谓的依赖过程(为什么v-if="flag"这个指令能够起到和js代码一样的效果?{{}}里面为什么可以放三元表达式而不能放流控制语句?)
    • 对数据创建观察者的过程(为什么数据一变,页面也更新了?双向绑定又是怎么回事?)
    • vdom的创建、diff、patch过程(为什么可以通过render函数直接渲染模板?vdom到底是怎么节约性能损失的?)
    • 生成ast和可执行代码的过程(同一个vue文件有多个v-for和v-if,它们的作用域是怎么决定的?)
    • ......
    1. 框架/库/API的设计思路是怎么样的?
      跟完细节后,我们又回到宏观层面上,去思考这个框架/库到底是基于什么设计理念的。比如说:
      3.1 Vue为什么有人说它是数据驱动(MVVM)和组件化的?这个思想来自于软件领域的哪里?这样做对前端工程师来说有什么好处?
      3.2 lodash为什么有人说它是函数式的?这个思想来自于软件领域的哪里?这样做对前端工程师来说有什么好处?
      3.3 jquery为什么有人说它是锋利的?它坚挺这么多年的原因何在?为什么还有那么多的前端工程师离不开jquery?
      3.4 element为什么需要有一套设计原则?为什么组件要分通用组件和业务组件,它们的界线在哪?写好一个组件对一个前端工程师有多重要?

    安全

    年轻时,我非常羡慕黑客。现在,我很佩服从事安全行业的人。

    我现在所在的这个部门,正尝试着将以往巫师般的、个人英雄主义的安全行业改造成工业化的、团队协作的。

    我司提出了一个理念:数据驱动安全。以前纯凭经验和运气攻击和防御,脚本小子都能造成巨大的损失。而现在,一切都需要有据可循,攻击行为可以通过大数据分析辨别出来,攻击场景也可以还原,甚至化防为攻,主动出击,干他一炮。

    整个公司好几千号人就为实现这个目标而努力,而我,为了理解其中的奥义,也做了一个demo,顺便当作本科的毕业设计:


    架构图

    拿我们学校某服务器的Web日志做了一个简单的测试:

    毕设首页.png
    毕设攻击分布.png
    顺便给g2-vue提了个pr,用来支持更复杂的G2图表组件化。

    算法

    以前我也认为,前端面试考那么多算法干什么?工作中又用不到,来到我司后,我承认我错了。无论是平常中业务涉及到的UI组件、还是解决一些纯JS问题时、抑或是要实现交互性强的组件和可视化应用时,没有算法的支撑,根本寸步难行。

    下面是一些比较典型的例子:

    可视化

    我对可视化这门让数据空间映射到图形空间的学科的认识应该还是个门外汉:

    • Echarts和highCharts基于配置驱动
    • G2基于数据驱动
    • svg和canvas是二维可视化的基础
    • webgl和threejs是三维可视化的基础
    • 地图由瓦片+Geo数据构成

    附上两个入门资料:

    文档翻译

    这是一个意料之外的收获,就是前端文档翻译组织印记中文,有个同事是创始人之一。webpack、node中文文档都出于这个组织。他说:“我就想给前端开源社区做点贡献,让国内的开发者学习时更轻松一点。”

    他这对开源社区的态度,让我钦佩不已。于是,我加入了Ionic文档的翻译工作中。

    ionic中文文档雏形

    在这期间,收获了不少在公司得不到的git经验。因为这是一个真正的开源项目,在众多分支中,如何保证合并、pr、同步等操作的顺利进行,是有很大的挑战性的。

    当然,英语阅读能力也得到了很大的提升,但离翻译境界的信达雅境界还差得很远,希望大家多提issue和pr。

    其他

    其实,在实习的过程中,还遇到了很多问题,但它们在搜索引擎、文档、issue、论坛和社区、Stack Overflow上是可以找到准确答案的,所以我就不赘述了。

    最后要说的话

    还有一个意料之外的收获,就是在年会上中了一个森海塞尔HD650,虽然我并不是耳机发烧友,不过还是挺开心的。如果哪位读者对这个耳机感兴趣可以私聊我~

    虽然实习工作内容只和我的痛点重合了第一点和第二点,但也接触到了更多可以学习的点,比如算法、可视化、安全等。但人的精力是有限的,我需要对它们进行最大可能的试错才能决定自己是否适合往那边发展。拿前端这个工种作为立足岗位,发展的方向还是有很多的呢~

    最后祝大家狗年旺旺旺~

    相关文章

      网友评论

      本文标题:过去的一年,我从准PM转变成了一个前端

      本文链接:https://www.haomeiwen.com/subject/pmeltftx.html