在写文章前容许我啰嗦一下:对于软件开发,我走了不少弯路,有时觉得自己作为API侠,无所不能,有时又觉得自己很多LeetCode题写不出来,无能为力。我有一个博客,但是写满了自己的絮絮叨叨,真正有本领的东西九牛一毛。
我甚至没有自己的“代表作”,因为我是一个急性子,想马上得到结果(事实上计算机真能马上给出结果,但开发过程不行)。我经常在“造自己的轮子”和“用别人的轮子”之间徘徊,“造自己的轮子”比较有成就感,但是难度其实很大,需要踩很多别人踩过的坑;“用别人的轮子”则没有什么成就感,做出来也不像是自己做的。而平时工作中,每天都在用别人的轮子,自己真正从比较底层开始实现的情况是非常少的,导致我在闲暇时间也不想用别人的轮子。
2004年,我家买了电脑,我也接触了很多电脑上的游戏。但是也许是我心浮气躁或者没有游戏天赋,我总是在游戏里输,总是追不上邻居小伙伴;
2008年,我萌生了“自己写一个什么东西”的想法。
2009年夏,小学毕业的我开始摆弄魔兽地图编辑器,虽然一点脚本都没写,做出来的游戏也粗制滥造。也开始查找“如何创建一个个人网站”。
2010年,在和初中新同学混熟之后,我们打算做一个班级网站,我找了一圈发现discuz和phpwind有免费的论坛可以注册,我们注册了一个论坛,并且想把每天的作业更新发布上去。但事实上那位同学仅发布过一次作业。
2011年,我利用爸妈给我的打游戏的时间,将网页保存下来,咬着牙研读里面的html标签,然后给我当时加入的一个魔兽争霸群做了一个纯html的“官网”。在某免费空间上注册了一个只支持asp和基础web的免费空间,用8uFTP把网站上传上去。
2014年,在学校的图书室,我昧着良心在寻找Dreamweaver的教程书,还真给我找到了。但是我根本没有自己的电脑,只能对着书发呆脑补。
2015年夏,我高中毕业,填志愿的时候几乎把“软件工程”和“计算机科学与技术”都填的满满的。我查了资料发现“软件工程”比“计算机科学与技术”学费更贵,在询问了父母的意见之后,我把“软件工程”填到了第一位,然后和父母说,一定会考上。最后我考上了一个普通的本科,开始学习软件工程专业。
2015年暑假,还有一件事情,我自己注册了域名,购买了阿里云的虚拟主机,配置了WordPress服务器,在上面写博客文章。仅仅是备份就花了一周,然后终于拿到了自己的备案号。我永远不会忘记第一次用自己的域名打开自己的网站那一刻的快乐。
2016年春,我推开软件学院大楼某间实验室的大门,然后就我大学一年级就和学长们一起做项目,当时团队里缺人写html页面,而我正好已经算是html css入门了(完全不会js),开始仿写各大网站。然后想自己写一个象棋游戏,结果找资料就找了一个下午,最后不了了之。
2017年夏,我跟着课程开始研究蚁群算法,最后实现了论文的内容。现在回想起来,对着论文依葫芦画瓢其实没什么技术含量,当打包运行并且在台上汇报之后,我真的觉得很快乐。不过,我并没有学到什么“真才实学”。
2017年秋,在Java课上,我带领团队(其实开发就我一个人)用Bmob作为后端,安卓作为前端,开发了一个“今日特价”
app。我对着github上的一个高仿微博的项目,拼命的抄各种代码。而最后我觉得写的太差,而把代码都删除了,真是太可惜了。
2018年,我有了很多很多想法,但是都没有执行下去。
2019年春,考研没考上,但是数学二确实也让我复习了高数和线代。借助这点基础,我选了一个“手写汉字识别的研究”的题目,然后开始学习吴恩达的机器学习入门,学习深度学习Tensorflow,学习卷积神经网络等等,然后由于自己的电脑的显卡是1050ti,有点不够用,我就花钱去租专门用于训练的服务器,印象中要6块1小时。那时候为了一个好的结果,,花了不少家里的钱。
2019年春夏之交,我的论文提交给了一个不太懂机器学习的老师,老师一看就觉得我在抄别人的论文。给我的建议是,我要么一意孤行继续这样答辩,但可能延毕;要么就把手写汉字识别改成某个系统,走需求分析,UML设计,数据库设计,开发,测试,结论的框架。当时我感到了深刻的绝望,自信心几乎被击垮,支离破碎。仗着自己之前也曾一个人咬着牙实现过不少系统,我决定把这个算法的研究都丢掉,转用百度提供的手写汉字识别api,包装成一个笔记系统,手写的笔记拍个照就转储成汉字。
2019年秋,我入职某软件公司,我终于会写Vue了。在之前我总是写jQuery。我甚至以为jQuery是最好的解决方案。也许2015年前是,2015年后就不是了。
2020年,我虽然是Java开发工程师,但是做了很多很多前端的内容。我被迫花很多时间去调CSS,去抄别人的js来完成移动端的h5网页的展示效果。我感到非常的厌恶,觉得自己的能力被封锁了。领导想弄区块链,想提供API接口给其他公司使用,但现在看来根本没有任何优势,仅仅是困兽之斗。另外,为了能把智能客服的问答预料快速查找,我学习了ElasticSearch数据库的用法。为了爬取一些信息,我学习了Python开发。
2020年秋,我被“发配”北京,每天都过得很不开心,回家遥遥无期。本来说好的出差一个月,到了地方之后却要求长期驻地开发。而那套系统的代码很乱,找到机会我马上就离职了。
2021年,我来到上海,接触了游戏服务器开发。我第一次发现服务器是如此的庞大。
2022年,我回过头来发现,我好像是从2021年之后,才真正打破“啥都会,啥都不会”的尴尬局面。在此之前,我好像什么都会:
又啥都不会:
总的来说就是,都是浅尝辄止。当跑完hello world,把环境搭起来的时候,我就觉得自己行了,牛了,然后关掉编译器去玩了。
不过有意思的是,2021年我在10年工作经验的主程面前点开8uFTP的时候,他惊讶地问:“woc你怎么在用这个东西?太老了这个,可以换一下Filezila”。而我会心一笑。后来团队发生了变动,换了个新主程。在闲暇时间我和他攀谈“网页三剑客”,向他展示我2015年就搭建起来的博客,和他开玩笑说,我和他是同一个软件开发时代的人,我是Young OG!
但也仅此而已了。也许我真的是Young OG,我已在软件开发的路上,满打满算走了14年,但是我总是缺了点什么很关键的东西。以前我觉得自己不懂坚持,总是半途而废,而现在,在上海工作了一年多之后,我发现我的能力并没有任何问题,我的问题在于不知道怎么将工作切分,不知道怎么保存自己的体力,不知道自己的目标是什么。
不管是写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。
语言 | 路由 | ORM |
---|---|---|
Java | SpringBoot | MyBatis |
Go | Gin | Gorm |
在这次开发中,我不再像过去一样无头苍蝇乱撞,而是先画了好几个框框,来分析到底自己想做什么事情。
别看内容不多,事实上这一步是非常重要的。我们对于某个需求,可能仅仅是觉得“这个拿出来,然后和那个比一下,有就做这个,没有就做那个”,最后加一句“不就好了吗?”。但在实际操作的过程中,大概率会发现“这个”不好拿出来,“那个”也不太好取出来,取出来不知道在哪里“比一下”,“有”的情况可能不方便“做这个”,“没有”的情况可能不方便“做那个”。
所以不要说“不就好了吗”,对于自己不熟悉的领域来说,做什么都会遇到问题。如果用的是自己熟悉的内容,那么就失去了提升自己的机会了。
首先我先用一句话把我脑中的需求写明白。只要自己看懂就好。
然后我开始幻想前端,前端要做几件事?我列出了5件事:
在这个简单的需求中,这5件事就是5个接口(最后开发的时候发现“执行预约”和“创建预约”的功能是重合的,但是无所谓,这里更多的是提供思路)。
而在后端那块,我从前端要做的事情反推后端应该要有什么功能:要发送请求肯定需要路由,要落库肯定要操作数据库和设计数据库。在需求里需要读取比赛到达的某个比分,那么就需要一个轮询的定时器,每隔一段时间发送请求问一下,然后通知就用邮件,因为邮件协议是通用的,而且QQ邮箱的提醒非常醒目。最后业务逻辑也是需要时间进行设计的。
基于前后端的内容,我开始排工作:
事实上这个工作安排,虽然是11条,但是每一条的工作量并不平均。我感觉在任何项目组,切分工作也不代表工作量是平均的。
现在做完回头看,发现go语言对邮件发送和ticker有自带的支持,然后gorm的逻辑和gin解析json的逻辑几乎一致。其实并没有浪费多久时间。
这次我没有预估具体时间,因为我心里没底。事实上更好的做法是稍微评估一个时间长度。
任务切分的意义在于,任务有时候不像买来的蛋糕,你可以用肉眼看到蛋糕的大小和形状。你手上只有一把塑料刀,对着盲盒里切。
但是有意思的地方在于,任务这块“蛋糕”的结构虽然乱七八糟,但是你大概能找到你知道的位置,然后胡乱的“划一刀”。这种切分可能并不准确,你并不知道你的蛋糕具体是什么样的,但是当你用这种方式多“划好几刀”之后,你的图中会有一个大概的系统模型,这会反过来指导你接下来要怎么划分工作内容。当工作内容越来越细,你就越能准确的评估每一块的时间和困难点。
也就是一件事变成了好几件事。而每一件事都有单独的内容,有单独的评判标准。从而能清楚的知道自己做了多少内容。
关于评估时间,我发现自己经常落入一个陷阱里:认为简单的事情一定能很快做完。但实际情况是,一个任务的时间长度,既取决于难易,也取决于工作量。我经常忽视工作量的大小,乐观的估计比较简单的工作任务。其实在拿不准时间的情况下,可以把时间评估的更长一些,是没有问题的。
如果说在公司工作是为了谋生,那么在业余时间做自己的项目就是为了取乐。
如果不是为了取乐,那么也没有必要再浪费时间了。
经过这次的开发,我发现自己的开发内容其实也不少,但是我没有觉得很不开心,相反,我感到很兴奋。
在21年10月我有自学Go语言的语法,但是我不知道怎么去应用于实践。而编写一些基础语法的训练代码,让我觉得很像读书时看着例题做例题。
挑战性不能太高,比如写一个完整的用户注册登录找回密码的体系,然后提供第三方token登录这种,对于一个人开发来说,太难,而且也是重复造轮子的工作。
也不能太低,比如写一个golang的Hello world,包装一个在网页上发邮件的功能等,做出来没有意义。
自己的项目,应该是有点挑战,然后尽可能实用,能在生活中用得到。如此一来,才不会陷入“我做这玩意又没钱赚,学不到东西,我不知道为了什么而写”的错误想法中。
结合上一节写的“任务切分”,当有一个想法在脑中亮起,请你拿出纸笔或者打开画图软件,花一个晚上或者一天做一做简单的功能设计和任务划分,你就能知道自己的想法值不值得做,需要什么资源,做出来是为了什么。
如果一个需求没有实际的作用,那么就没有必要浪费时间了。如果“实用性”仅仅是为了“让大家知道我有本领”,而没有办法在生活中应用到,或者是让人感到很快乐,又或者能带来收入,那么尽早停止吧。(当然了如果“让大家知道我有本领”能让你升职加薪跳槽,那么就属于“能带来收入”的范畴了)
翻看github和gitee,我有很多想法和点子。
但真实的情况是,我每次花了一天做一点内容,就觉得浑身难受,没有任何正反馈。比如自己的博客那个,我花了一晚上调style样式,然后已经没力气写后端了;中国象棋我把基础的棋盘和走子逻辑对着书里翻译成kotlin就花了一周的休息时间,界面是用命令行print的,而这一周我一点游戏都没玩!预言家的网站也是用bootstrap写了个基础的主页和个人中心,后端那块就没体力做了。Unity和UE根本不知道怎么入门,或者说看看教程自己弄一下一天也就过去了。
我属于是又想学,又想做,但更想玩的人。我无数次觉得自己是很糟糕的人,因为我有这些想法和点子,却从未付诸实践。
而从前两节的分析上来讲,这几个需求大多都属于挑战性逆天高,实用性几乎没有的需求。而我其实并不特别喜欢这些需求做完之后的具体效果。
自己写网站(凌天战队、自己的博客、预言家的网站)对我来说其实还是很消耗时间的,即使我现在有能力能做的很快。自己的用户体系就算建起来也需要维护,还不如直接作为一个信息发布平台+邮箱联系的模式,作为自己的名片;
中国象棋则是属于做出来就是为了自娱自乐,但是也没有多有趣,因为象棋游戏现在多如牛毛,我要的功能现在天天象棋也有了,如果是为了学习剪枝算法,倒是值得一学,但是为了做一个游戏系统,又不打算捞钱,就是浪费时间了;
睡眠宠物是属于难度特别特别大,需要自己测很多很多轮,但是没什么收益的东西。而且还需要美工的支持,不然就毫无用处和趣味了;
英雄联盟数据平台是属于爬虫爬到数据库+命令行展示结果即可的功能,做一整套系统属实是为了装逼,但事实上代码放到github上,然后在Readme里贴出结果,反而更有范儿;
三国数据平台属实是劳民伤财,挑战性拉满,而实用性还不如百度百科。
学习Unity或者UE,首先应该先学基础,而不是先做RPG,现在根本没办法做好系统设计和切分需求。
有想法是好事,但是现在的情况是,你想到的东西,前人肯定有人也想到了,他们没有做成功,所以才轮到你想到。
而这次做的赛事预约平台,则是我第一次用正确的方式分析、设计、排期、开发、测试,还差一步上线。整个过程里我不觉得有多辛苦,而是觉得这个系统还可以有很多地方可以优化,让他更人性化,甚至让他不再依赖接口爬虫等,保障系统数据来源正常提供。并且这个系统真真切切能为我提供便利,让我能更专注于我的工作内容,又不落下比赛。
我接触代码已有14年之久,但为自己开发一个完整的系统(包括前后端和测试),并且真正用于实际,是头一回。一起拿我不过是个“雇佣兵”,为了学校的学分,为了公司的工资而疲于奔命,而自己的想法又太过庞大。
以此次经验为鉴,今后一定可以有很多有意思的想法,在“任务切分刀”切分之后,逐步完善。成为我自己的“代表作”。