独立个人项目开发心得 - 任务切分、挑战性、实用性和半途而废

在写文章前容许我啰嗦一下:对于软件开发,我走了不少弯路,有时觉得自己作为API侠,无所不能,有时又觉得自己很多LeetCode题写不出来,无能为力。我有一个博客,但是写满了自己的絮絮叨叨,真正有本领的东西九牛一毛。 我甚至没有自己的“代表作”,因为我是一个急性子,想马上得到结果(事实上计算机真能马上给出结果,但开发过程不行)。我经常在“造自己的轮子”和“用别人的轮子”之间徘徊,“造自己的轮子”比较有成就感,但是难度其实很大,需要踩很多别人踩过的坑;“用别人的轮子”则没有什么成就感,做出来也不像是自己做的。而平时工作中,每天都在用别人的轮子,自己真正从比较底层开始实现的情况是非常少的,导致我在闲暇时间也不想用别人的轮子。 啰嗦一下自己的经历: 2004年,我家买了电脑,我也接触了很多电脑上的游戏。但是也许是我心浮气躁或者没有游戏天赋,我总是在游戏里输,总是追不上邻居小伙伴; 2008年,我萌生了“自己写一个什么东西”的想法。 2009年夏,小学毕业的我开始摆弄魔兽地图编辑器,虽然一点脚本都没写,做出来的游戏也粗制滥造。也开始查找“如何创建一个个人网站”。 2010年,在和初中新同学混熟之后,我们打算做一个班级网站,我找了一圈发现5566和phpwindy有免费的论坛可以注册,我们注册了一个论坛,并且想把每天的作业更新发布上去。但事实上那位同学仅发布过一次作业。 2011年,我利用爸妈给我的打游戏的时间,将网页保存下来,咬着牙研读里面的html标签,然后给我当时加入的一个魔兽争霸群做了一个纯html的“官网”。在某免费空间上注册了一个只支持asp和基础web的免费空间,用8uFTP把网站上传上去。 2014年,在学校的图书室,我昧着良心在寻找Dreamweaver的教程书,还真给我找到了。但是我根本没有自己的电脑,只能对着书发呆脑补。 2015年夏,我高中毕业,填志愿的时候几乎把“软件工程”和“计算机科学与技术”都填的满满的。我查了资料发现“软件工程”比“计算机科学与技术”学费更贵,在询问了父母的意见之后,我把“软件工程”填到了第一位,然后和父母说,一定会考上。最后我考上了一个普通的本科,开始学习软件工程专业。 2015年暑假,还有一件事情,我自己注册了(已经失效了的)域名,购买了阿里云的虚拟主机,配置了WordPress服务器,在上面写博客文章。仅仅是备份就花了一周,然后终于拿到了自己的备案号。我永远不会忘记第一次用自己的域名打开自己的网站那一刻的快乐。 2016年春,我推开软件学院大楼某间实验室的大门,然后就我大学一年级就和学长们一起做项目,当时团队里缺人写html页面,而我正好已经算是html css入门了(完全不会js),开始仿写各大网站。然后想自己写一个象棋游戏,结果找资料就找了一个下午,最后不了了之。 2017年夏,我跟着课程开始研究蚁群算法,最后实现了论文的内容。现在回想起来,对着论文依葫芦画瓢其实没什么技术含量,当打包运行并且在台上汇报之后,我真的觉得很快乐。不过,我并没有学到什么“真才实学”。 2017年秋,在Java课上,我带领团队(其实开发就我一个人)用Bmob作为后端,安卓作为前端,开发了一个“今日特价” app。我对着github上的一个高仿微博的项目,拼命的抄各种代码。而最后我觉得写的太差,而把代码都删除了,真是太可惜了。 2018年,我有了很多很多想法,但是都没有执行下去。 我想自己从零搭建一个博客,用新学的SpringMVC,替换掉WordPress。 我想做一个网站,叫做“预言”,简单来说就是让用户发表一些对未来的猜测,并且定一个时间,然后系统到了那个时间会提醒用户确认是否预言成功 我想做一个安卓app,像三国志11一样,将所有三国的人物,历史事件,城池信息,战役,单挑,舌战都完整地汇总在里面,然后再像游戏一样,将“官渡之战”、“赤壁之战”、“夷陵之战”都像三国志11一样活灵活现地展示在地图上。 当时我觉得做网页做系统已经很没有意思了,所以我决定做机器学习,深度学习。 我想考研,因为不太满意自己的双非学历。 那时候LPL竞猜挺火的,我和朋友商量写一个统计各队伍各选手的评分的系统。当时我先用jQuery写了前端,拼命的append html标签,导致我自己写完的时候都不知道自己在写什么。 2019年春,考研没考上,但是数学二确实也让我复习了高数和线代。借助这点基础,我选了一个“手写汉字识别的研究”的题目,然后开始学习吴恩达的机器学习入门,学习深度学习Tensorflow,学习卷积神经网络等等,然后由于自己的电脑的显卡是1050ti,有点不够用,我就花钱去租专门用于训练的服务器,印象中要6块1小时。那时候为了一个好的结果,,花了不少家里的钱。 2019年春夏之交,我的论文提交给了一个不太懂机器学习的老师,老师一看就觉得我在抄别人的论文。给我的建议是,我要么一意孤行继续这样答辩,但可能延毕;要么就把手写汉字识别改成某个系统,走需求分析,UML设计,数据库设计,开发,测试,结论的框架。当时我感到了深刻的绝望,自信心几乎被击垮,支离破碎。仗着自己之前也曾一个人咬着牙实现过不少系统,我决定把这个算法的研究都丢掉,转用百度提供的手写汉字识别api,包装成一个笔记系统,手写的笔记拍个照就转储成汉字。 2019年秋,我入职某软件公司,我终于会写Vue了。在之前我总是写jQuery。我甚至以为jQuery是最好的解决方案。也许2015年前是,2015年后就不是了。 2020年,我虽然是Java开发工程师,但是做了很多很多前端的内容。我被迫花很多时间去调CSS,去抄别人的js来完成移动端的h5网页的展示效果。我感到非常的厌恶,觉得自己的能力被封锁了。领导想弄区块链,想提供API接口给其他公司使用,但现在看来根本没有任何优势,仅仅是困兽之斗。另外,为了能把智能客服的问答预料快速查找,我学习了ElasticSearch数据库的用法。为了爬取一些信息,我学习了Python开发。 2020年秋,我被“发配”北京,每天都过得很不开心,回家遥遥无期。本来说好的出差一个月,到了地方之后却要求长期驻地开发。而那套系统的代码很乱,找到机会我马上就离职了。 2021年,我来到上海,接触了游戏服务器开发。我第一次发现服务器是如此的庞大。 我学习了新的架构:Actor架构。 我受到网上的信息“蛊惑”,觉得hibernate已经过时,但在游戏这个场景里,hibernate比mybatis更适合。 我以前不理解Zookeeper到底用来做什么,他们总是只教我存和取,现在我知道可以配置系统信息; 我自学过netty,但是不理解为什么要用netty,现在我知道了,封包解包,NIO这些情况用netty确实快人一步。 我以前觉得mysql能力有限,但是在mysql前加一层缓存的话,速度就会成倍提高。还有索引和主键的配置也是有考究的,慢查询也是可以分析的。并不能武断的认为mysql能力不行。 还有一些完全没听过的,比如protobuf,akka,集群,ticker,在我之前的认知里只有json是唯一通信的结构。 2022年,我回过头来发现,我好像是从2021年之后,才真正打破“啥都会,啥都不会”的尴尬局面。在此之前,我好像什么都会: Web前端:html,css,js基础语法,jQuery的用法,简单的WebPack打包,简单的Vue Java后端:SpringMVC过渡到SpringBoot,MyBatis 移动端:基础的Android开发 数据库:使用过关系型的Oracle,mysql,也使用过非关系型的mongodb和ElasticSearch Python:爬虫相关 服务器:只会简单的java -jar部署,netstat -nlp看端口,然后给我所有的电脑都装好双系统。 又啥都不会: Web前端不会最有技术含量的React Java后端不会hibernate,HashMap的底层逻辑,Java虚拟机的垃圾回收机制都是用背的。 移动端:不会用kotlin写安卓,也不知道最新的安卓有什么内容 数据库:从没有仔细学习mysql背后的存储优化原理,也没有上手实操过 服务器:以为服务器只是java -jar,而没有研究过docker,zookeeper,jenkins等更优秀的工具和中间件。装双系统也就装的那一刻用一下,真要做事还是用虚拟机多开…… 没有研究过消息队列。 总的来说就是,都是浅尝辄止。当跑完hello world,把环境搭起来的时候,我就觉得自己行了,牛了,然后关掉编译器去玩了。 不过有意思的是,2021年我在10年工作经验的主程面前点开8uFTP的时候,他惊讶地问:“woc你怎么在用这个东西?太老了这个,可以换一下Filezila”。而我会心一笑。后来团队发生了变动,换了个新主程。在闲暇时间我和他攀谈“网页三剑客”,向他展示我2015年就搭建起来的博客,和他开玩笑说,我和他是同一个软件开发时代的人,我是Young OG! 但也仅此而已了。也许我真的是Young OG,但是我总是缺了点什么很关键的东西。以前我觉得自己不懂坚持,总是半途而废,而现在,在上海工作了一年多之后,我发现我的能力并没有任何问题,我的问题在于不知道怎么将工作切分,不知道怎么保存自己的体力,不知道自己的目标是什么。 不管是写LeetCode,写项目,还是研究某个新框架,都需要安排时间,都需要统筹自己拥有的资源。特别是写项目,写项目有一点像写小说。只有将小说里每个章节都完成并且有所关联(长篇小说),才能是一部优秀的小说。长篇小说家也不是一朝一夕能写完一部大作,我们软件开发人员自然也不能一朝一夕写好一个系统,更何况我们还需要测试自己的代码。 所以我们需要对任务进行切分。 任务切分的方法和意义 最近两三个月,在工作中,我开始使用画图工具来画一些流程图或者架构图。这些图不是标准的UML图,但是是我自己能看懂的图。 简单说一下本次系统做了什么。 我平常会看LPL比赛,尤其是季后赛或者国际赛事。这些赛事一般是BO5(五局三胜制),一局比赛一般30分钟,加上休息的10分钟,如果打满5局大概4个小时多。如果中途出了点差错,还有暂停的时间。 而最好看的比赛往往不是前两三局,而是第四局或者第五局。因为如果第三局就结束这场BO5,只有可能是3-0碾压,没什么意思。而如果打到第四局,必然是2-1,这时领先方再加把劲就赢下整场比赛,而落后方已经站到悬崖边,这时候的比赛是最好看的。 但要打完3局,至少也要两个多小时了。如果我手头上有一件其他的事情要做,那么我就需要经常点开某个APP检查比赛是否到了2-1?又或者我对两队的实力很信任,我相信他们一定能打到2-2进决胜局,那我就很可能需要在三个小时内不断的抽时间查看比赛进度。这会影响我手上的事的效率。 所以,不如写一个系统,每隔好几分钟去请求一下LPL的接口,和数据库的预定比赛信息比对,如果到达了我预定的比赛比分,或者到不了我预定的比分,就发邮件提醒我。我只需要开着QQ,等着右下角提示就好了。 技术选型 回到上一节说的“造自己的轮子”和“用别人的轮子”的讨论,我平时的工作用Java进行开发,如果用SpringBoot,在路由,操作数据库逻辑,发送邮件那几块的内容,在数据库设计好了的情况下,我会写的很快。 在这个情况下,“用别人的轮子”就是用SpringBoot,“造自己的轮子”就是用某个自己没学过的语言或者框架,边做边学。 本次我选用的是Go语言和Gin,对标Java和SpringBoot。...

四月 5, 2022 · JohnathanLin