作者:陈天
今天讲讲软件开发升级打怪之路。因为留言中有大量的类似问题:我刚刚上完了 xx 语言的课程(或者自学了 xx 语言),下一步该怎么学习才能达到开发产品的水平?
这是个好问题,相信困惑不少人,尤其是学生。
办法很多,程序君讲讲自己最喜欢的,也是最暴力的 —— 直接动手使用你刚掌握的技能开发产品。
这有两种途径:(1) 加入一个使用该种技能的团队进行产品开发;(2) 自己动手开发。
途径(1) 在任何时刻都是最佳选择,一群人在一起探索(尤其里面可能还有一些高阶能手)的效率是最高的,你的成长也是最快的。但世间之事往往郎有情而妾无意,你看得上的团队未必瞧得起你。这时候,(2) 便成了唯一的选择。
可是我都不知道自己该开发些什么,怎么办?
程序君可以举个例子 —— 你可以拿这个例子练手,也可以顺着这个思路,想想其它对你更有意义的『产品』进行开发。
这个例子源自前几天的有人在留言中写错的成语『血脉喷张』,我将其纠正为『血脉偾张』,有人又纠正我说应该是『血脉贲张』。后来我查了百度百科,『血脉偾张』和『血脉贲张』都是正确的。我就想,可不可以做个产品,对一篇文章中的成语进行自动纠错?
这个问题很大,做起来有不少坑需要填。很多时候,同样的结果,如果你问对了问题,那么处理的难度要小不少。我们把这个问题稍稍改改:可不可以做个产品,对用户输入的成语进行自动补齐?
这下简单多了。能满足 80% 的需求。
(1) 获取一个包含尽可能多的成语的词库
(2) 读入词库,以特定的方式存储,以便于扫描
(3) 根据用户的输入进行判定和补全
对于(1),最简单的方法是导出某个输入法的成语词库(可能还需要做些过滤的工作),对于(2),可以考虑将词库建个前缀匹配树,对于(3),将满足前缀匹配的结果推荐给用户。
这问题解决起来不难,详细的实现手段我就不说。接下来你可以考虑这些问题:
(1) 如何进一步提升匹配的速度(performance)和精度?(还有什么更好的算法吗)
(2) 如果将其封装为一个 unix service,该怎么做(比如说将匹配和推荐做成一个服务,监听 tcp/unix domain socket,让本地,甚至远程的进程也能访问)?你会制定什么样的协议(protocol)来规约客户端和服务器?
(3) 如果将其封装成一个 web app,该怎么做?如何达到类似 google suggest 的效果?
有人觉得(2)(3) 很类似,其实差别很大。对(3) 而言,每个 http 访问都是一个单独的请求,互相之间没有状态,所以你不能和(2) 一样直接使用已有的加载好的词库,但如果每个请求都加载,代价很大。所以你要么使用(2) 的成果,要么启动一个缓存服务(如 redis)将词库按照你的存储方式加载进去。
这样一步步走完后,你可以问自己更多的问题:
如果用户在连续输入,而不是特定输入某个成语,我该如何进行自动补齐的推荐?如『顿时感觉血脉』,这时候能推荐出来『贲张』么?
如果这个问题也解决了还意犹未尽,可以研究下一个问题:可不可以做个产品,对用户输入的成语进行自动纠错?
纠错和补齐是两个概念。纠错会难很多。比如:对于『血脉贲张』,如果用户输入的是『雪脉贲』,能否推荐出来『血脉贲张』呢?
或者,回到最原始,可能也是最难的问题:可不可以做个产品,对一篇文章中的成语进行自动纠错?
程序君就不一一分析了。以上例子如果你能潜心研究下去,并做出一个解决方案,那么我相信 BAT 会乐于吸收你入伙的。
这个例子本身仅仅为了抛砖引玉。它可能并不符合你的口味,但我相信在生活中你总能找到很多很多类似的问题你认为值得花时间用程序员的方式去解决。它们一开始可能是一个很大,很难搞的问题,但只要你一点点简化下去(使用递归分治等手段),思考下去,最终能找到一个适合自己去实现的问题,实现之,然后再一层层回溯。你会感受到打怪升级的那种成就感。
但有一点一定要注意:如果问题已有答案,可以借鉴,但不要抄。也许以上的问题别人已经有了解决方案,但那毕竟是别人思考和练习的结果,你 copy&paste 一百次,也抵不上自己的一次思考,一次练习。
所以,找个问题,深入下去,并(最好和别人一起)寻求解决之道,这就是程序君眼中的软件开发升级打怪之路。