最新经验好文第一时间送达
2020.5.16
“每一个优秀的程序员都会经过实战的洗礼!”
|二度简并|
回顾一下,我的技术能力(不仅仅是编程,而是解决问题的能力)的进步大约有几个重要的节点。
阶段一:刚入行时的入门练习题
这个是当年狼厂网页搜索部门的传统,不知道现在还有没有,入职第一个任务是完成两道练习题。
一题是在Linux上用纯C(不许用C++,没有stl可用)完成一个多线程的网页抓取器,另一题是同样的环境语言完成2G大小的query(搜索查询词)的top100提取,有时间要求。
入厂之前我在Linux上没有写过代码。两天时间从Linux基本命令的熟悉,vim gcc gdb的使用学习,从malloc和free开始搞内存管理,从0开始码hashtable(还得自己写hash函数),从socket开始实现http client和各种协议码解析,使用pthread多线程和信号量互斥同步,基本把操作系统计算机网络复习了一遍。这两天把我四年本科三年研究生没搞扎实的工程基础全部补上了。
结论:
有目的的练习,尤其是一个完整的应用问题的解决,是学习的不二法门。
阶段二:接手一个完整的模块(子系统)
搞完入门练习,leader过来跟我说:现在有一个重要的模块交给你,赶紧熟悉一下,然后完成如下功能升级。这个模块是前厂存储网页的核心模块,在当年内存4g的奔腾主机上单机存储几千万网页,几台机器存下了当时整个中文互联网。
支持高性能的随机存取和顺序读,可以说把机器性能压榨到了极致。3w行,纯C。啃了几天终于搞明白了结构,(多年以后我还得感谢source insight),同时也对写这个模块的大牛佩服的五体投地,为了压榨内存把每一个bit都物尽其用,各子模块之间的分工又是那么的优雅。
然后是上手改,看懂了之后功能升级很简单,只改了十几行代码,但上线的时候真是手发抖!后来才知道这个模块好几个前任都没成功接下来就被fire了....后来又经历了若干次升级,解决各种诡异bug(搞过高并发存储系统的应该知道坑有多深),编码和解决问题的能力突飞猛进。
结论:
学习系统设计的最佳途径是看一个优秀设计的源码,检验成果的方式是改造它应用于你的实际场景。
阶段三:升级并扩展一个完整的抓取系统
与入门练习做的抓取器不同,这个完整的抓取系统(又称spider)是工业级的,需要每天完成千万级的抓取量,还需要考虑并发压力控制,网页更新调度,垃圾网页处理,去重等等诸多现实的工程问题。
大大小小十来个模块,十来万行代码,大部分是C,还有接近一万行的bash脚本(用bash实现分布式的网页去重处理你信?)这时会发现很多模块内部都有不少实现不尽如人意的地方,但是由于借口定义的好,模块直接容错性强,整个系统还是work的。
这促使我思考系统级的架构,最需要关注的重点是什么,良好的结构远胜于细节的雕琢。大约小半年后,我对这个系统基本做到出任何问题能立刻反映到是那个模块出的问题,对问题的分析定位能力又上了一个台阶。
结论:
理解了接口定义和系统结构重于实现细节,就迈出了架构师的第一步
阶段四:设计一个完整的子系统
此时大概工作快两年了,原来的抓取系统有一个很大的问题,就是积累的网页数太多,更新资源分配不过来,导致系统中大量网页在互联网上已经404但仍然会进到线上被检索出来。我们称之为死链接问题通过对死链的规律分析,我发现互联网上大部分死链存在站点或目录级聚集的现象,这个其实很好理解,一个网站无力维护了,自然就全部挂掉,目录级很可能是网站改版了,或者一个子频道关闭了。
利用这个规律,我们可以大幅度降低死链检测的资源耗费。在这个认识的基础上,我设计了一个独立的死链检测系统。上线效果很不错,检查死链的流量开销降低到原来10%,网页库中死链还下降了。
结论:
架构师首选要解决的是待解决问题的精确描述,和对问题域的分布规律的挖掘,然后才是结构设计。
阶段五:设计一个新的系统
工作第四,五年间,hadoop在业界逐渐流行起来,基于Google三件套的设计,当年的hadoop最上层的table还很不完善,但是mapreduce和hdfs已经很可以用了。
如何利用分布式基础框架改造系统,让系统更健壮(以及永更廉价的硬件给公司省钱),成了当时的一个重要问题。
整个抓取系统和建库系统的分布式改造,相当于重新设计一个新的大系统。需要考虑方方面面。
如何逐步升级兼容原有系统?如何保证功能的完整性?原有设计中有一些不合理的地方,如何利用这次迁移同步改造?主导完这些工作后,系统架构方面再也没有遇到搞不定的问题。
结论:
好的架构师需要在合适的时机解决重要的问题,业务发展才能给你这样的机会。
经过专业大牛的评估,上面5个阶段,大致是T3 T4 T5 T6 T8的水平,思考一下你现在到了哪个阶段呢?
END