代码之始

始?屎!

我从何时开始写代码?我为何开始对写代码这么感兴趣?

原本已经遗忘在了人生的长河中。

最近和某同事改写某个项目时的痛苦,让我不禁思考,这种程度编程水平的同事,为何能够独占鳌头?独赢领导青睐?

所以本文名为写我走上“码农”道路的《代码之始》,实为对某同事堆的“屎”不满发泄的《代码之屎》。

一切的开端

其实大学时有位好友曾经问过我是什么时候开始自学编程,又是怎么会想到去学编程的。

当时我给出了一个答案,现在的我已经不记得这个答案有几分真又有几分假了,但是当这个答案说出口那一刻开始,我的记忆就默认将这个答案标记为了唯一且正确的答案。

当时我回答的是,因为很久以前,我妈给我买了个手机,那是部诺基亚的小屏键盘机,搭载的是塞班 S40 系统,可以运行 .jar 程序,但是当时的 .jar 程序大多数都是给大屏幕的手机用的,对于小屏手机基本都是可以打开,但是显示不正常,要想使用,只能使用“魔改版”的程序。

在寻找可用的“魔改版”过程中就接触到了一些专门“魔改”程序的大神,也看到了他们出的魔改教程。

在跟着他们学魔改的时候,其中一篇教程的某句话让我印象深刻,大意是:“魔改只是不得已而为之的,只有自己写自己的程序才是最好的”。

于是,我就此走上了学习编程之路。

现在,让我用我那不太可靠的记忆,对这个答案进行扩充一下。

巧合

我接触到的第一台手机应该是我还在上小学时,我叔叔因为充话费送了一台手机,于是就拿给我爷爷用,而那时候恰好我爸爸需要晚上自己一个人去看守隔壁的“荒废”大楼,为了方便他联系外界,我爷爷又转手把这手机拿给我爸爸用。

之后我就经常拿我爸的手机玩。虽然那台手机除了打电话外就只有一个浏览器功能,但是对我也是有莫大的吸引力。

我只是拿着瞎翻里面为数不多的功能都觉得很快乐。

捣鼓着捣鼓着,不小心订购了一份手机报,每天会用彩信发送一些新闻,还会配上几张模糊不清的图片。

但是在我看来这信息量可太大了,至今仍记得,我从来没有完整的看完过任何一天的手机报。

现在想想,其实哪有多大的信息量啊,就寥寥数条新闻简报而已。

再后来又捣鼓浏览器,发现居然还有网页文字游戏这种东西,并且几乎所有网页文字游戏都是标注的“永久免费”,我理所当然的认为是免费的了。

其实那种所谓游戏都不能称之为游戏,就是个很简略的文字网页,可以做一些不同的操作选择而已,别说是动画,甚至连图片都没有。

当然,玩了两天就被发现了。

游戏确实是免费的,只是上网需要流量费啊,那时候的流量费还挺贵,虽然这些文字游戏也没有多大,但是也经不住我这么玩啊,于是手机欠费了,就被发现了。

而我的第一台手机并不是上面说的诺基亚手机也不是我爸那种充话费送的手机,而是一部杂牌机,用现在的话来说应该叫做 功能机 或者是 老年机

一块板砖似的机身,配上尺寸、分辨率都极小的屏幕:机身大部分空间都被键盘占去。

功能简单,不支持安装应用或是扩展功能,但是除了有浏览器外还支持手机 QQ 。

支持手机 QQ 对于我来说已经是不可想象的极大提升了,我得以用手机乱加人,然后和不认识得、认识的人胡乱聊天,说些有的没的。

那时候我哥哥还会经常趁我晚上睡着时偷拿我的手机去用浏览器看小说。

再之后其实我爷爷还买过更多的各式各样的奇怪的杂牌山寨机,但是无一例外的都是支持下载应用的杂牌机。

只是那并不是智能机,当然,用的也不是类似塞班 S40 那种准智能机系统,而是一种叫 MTK 平台的系统。

也可以安装很多游戏、应用,但是山寨机之所以叫山寨机是因为它不仅下载应用是收费的,甚至连打开“应用市场”也是收费的,收费方式就是发短信“点播”增值服务。

而且所谓“应用市场”也很奇葩,居然是从手机自带的一些基础应用的菜单里面,点击“更多应用”打开的。

梦开始的地方

大概是在我初中时,我姑姑买了一台小巧的诺基亚手机。

圆润的机身,小巧的模样,最最重要的是,它居然支持免费下载安装新的应用!

这在我看来简直是惊为天人。

当即就找姑姑借来把玩,甚至都忘记要还给姑姑了,直到姑姑第二天来找我让我把手机还给她,她要打电话,我才依依不舍的还给了她。

那时候开始我就无论如何也想要一台这样的手机。

终于在我的软磨硬泡之下,妈妈终于同意给我买一台。

去到手机店原本想买姑姑同款,但是店员说那个不适合我使用,那个更适合女生用,然后就给我推荐了另外一台类似的手机,但是不同于姑姑的手机,它自带内存更大,且支持插内存卡!

那时候我才知道,原来这个手机的系统叫做塞班 S40 系统。

自从我拿到这台手机后,我就废寝忘食的把玩它。

但是后来发现自带商店的应用非常少,而且大多在国内都用不了,或者是我用不上。

偶然的机会,我发现原来这个系统不仅支持从应用商店下载应用,更支持直接从浏览器下载文件后直接安装。

这一下子就给我打开了新天地,我开始四处搜寻各种各样的应用。

但是慢慢的我就发现,好多应用下载下来后都安装不了,要不就是安装了打不开,即使能打开里面的 UI 样式显示也不对。

一番搜索了解过后才知道,原来很多厂商开发的应用都只适配了大屏幕,而没有适配我这种型号的小屏幕。

而想要使用这些没适配的应用,只能去找民间大神手动修改的版本。

在找修改版应用时,发现了一个叫 乐讯 的论坛,里面有非常多的大神以及各种各样琳琅满目的修改版应用。

论坛里面还有很多我此前闻所未闻的 Hack 技术,像什么“免流”、“刷钻”之类的。

所谓免流其实就是当时三大运营商对于访问它们自己的门户网站是不记流量费的,于是就有民间大神琢磨出可以通过逆向运营商判断访问门户网站的方式来伪装我们实际访问的任意网站来达到全局免流量费的目的。(还记得吗,上面说过,那时候的流量费是非常非常贵的)

而刷钻则是指通过漏洞,免费开通腾讯QQ的绿钻、红钻等等会员以及衍生出来的一切增值付费服务的方法。那时候普遍采用的刷钻原理简单来说的话大概是由于腾讯服务器和运营商服务器之间同步数据存在延迟,而运营商又推出了一个权限极高的取消任意增值服务的接口,可以一键取消任意增值服务,此时我们通过腾讯提供的短信接口发送短信开通会员,然后立即通过运营商取消接口取消掉这个服务,这样,由于数据延迟,在运营商这边就会认为我们已经取消了这个服务,所以不扣款,而在腾讯看来,它只收到了开通服务的请求,并没有收到取消服务的请求,所以我们就得以在不扣款的情况下获得了会员服务。

在论坛里面泡久了,自然而然的就萌生出了我也要自己学习改应用的想法。

但是那时候我没有电脑,有的只是这个小屏幕的搭载塞班 S40 的手机。

那时候,诺基亚还有一个智能手机操作系统叫 塞班 S60,当然,S60 向下兼容 S40 的应用,所以很多修改版软件都是基于 S60 的应用修改的。

而 S40 由于系统非常简单,也没有对应的修改用的工具,所以就无法通过手机直接修改。

逐渐的,我又产生了想要一部 S60 的手机想法。

但是我至今仍未体验过 S60 系统,它就已经倒在了滚滚向前的时代洪流中。

是的,安卓操作系统,它来了。

安卓机器人来了

最早亲眼看到安卓系统是某日去某同学家找他时,看见他正在拿着一台神似大屏山寨机的手机在玩游戏,见我来后就关机准备和我一起出去。

但是我却惊讶的发现,这手机怎么跟电脑似的,关机还有进度条,关个机居然需要这么慢吗?

那时候我并不知道原来这就是日后占据了手机操作系统半壁江山的安卓系统。

之后乐讯论坛中,逐渐多了很多关于智能手机的信息,以及对于塞班究竟算不算智能手机操作系统的争论,还有关于未来究竟是安卓系统会成为主流还是微软的 Windows phone 携手诺基亚能继续稳坐手机一哥的位置的分析讨论。

我记得那时候我还和某个朋友讨论,以后谁会更火,我坚持认为安卓会火,而他却认为“鲁妹”(即 Lumia)才是未来。

其实那时候我们都不知道什么是安卓,什么是 Windows phone,我们也只是在看了论坛里的帖子后就开始大放厥词而已。

理所当然的,在我的软磨硬泡之下,我终于拥有了我的第一台安卓手机。

那是一台康佳的手机,搭载了最新的 Android 2.3 系统。

我还记得当时论坛还在争论 Android 到底算不算 Linux ,他开发使用的究竟是不是 java。

而我自然不忘初心,依旧还想着要学习我的软件修改大业,但是那时安卓的兼容性好太多了,而且我的手机也不再是那种小众的需要自行修改兼容的手机。

于是我就想学习写一个自己的 APP。

但是那时候我依旧没有电脑,依旧只有这台普通的安卓手机。

那时候也没有一款可以在安卓系统上编写安卓 APP 的 APP。

但是论坛里的大神说,谷歌有一个叫 SL4A 的开源项目,可以在安卓上运行诸如 lua、python 等脚本语言,而且它也提供了可以直接访问安卓系统 API 的框架。

大神们说,如果没有电脑还想学习编程的话推荐使用 SL4A 学习 Python,因为相较于其他语言,Python 更简单,更适合新手入门。

于是我就一头扎进了 python 的世界中。

那是我第一次真正意义上的接触 Python,我不仅对 python 毫无概念,甚至对编程也毫无概念。

而且那时候我也还没形成自己的学习方式,加之只是通过看论坛中大神们发的零零散散的教程,所以进步非常慢,我花了非常久的时间才逐渐理解编程中那些抽象的概念。

记得有次,我想使用 python 编写一个计算脚本,非常简单,就两个输入框,分别输入两个数值,然后再选一个四则运算符,点计算就算出结果。

但是那时候我根本没理清楚变量类型的概念(学的第一个语言就是python这种动态类型语言,难怪当时理解变量类型这么费劲呢)。

于是当我计算 “1+1” 时却只是得到了 “11” 这样的结果。

我百思不得其解,后来在论坛中疯狂查阅资料,似懂非懂的查到到原来我输进去的值还有类型的区分啊,如果要得出我想要的 “1+1=2” 的结果,我需要把我输入进去的字符类型的数据转换为数值类型才行。

看的我一头雾水,但是我还是将信将疑的按照教程转换了一下输入的数据的类型,再次运行,欸!真的等于 2 了。

虽然不知道为什么就等于 2 了,但是当时兴奋的我直接冲出门骑上自行车“咻”的一下子就冲到了湖边(当时我家住在一个半坡上,坡底是一个湖)然后又吭哧吭哧的骑回家继续学习。

既然成功解决了 1+1=2 的问题,我又想了,现在只能进行四则运算,而且还只能手动输入两个数值并选择运算符,那如果我想输入更多数值或者进行四则运算之外的运算呢?

我尝试了一下只保留了一个输入框,然后点击计算时直接输出输入框输入的数据,那这样是不是就能直接计算了呢?

我改好后输入了 “1+1+1” 结果输出的还是 “1+1+1”。

我继续上论坛查找教程,边找边想,莫非还是那个什么类型的问题?

查找了一番之后终于找到了,原来如果直接输出输入的内容,那么输出的其实就是输入的“字符串”,而我直接在代码中写输出 “1+1+1” 能够正常输出 3,是因为虽然它俩都是 “1+1+1” ,但是实际上一个是代码,一个只是内容为 “1+1+1” 的字符串,要想把字符串转为代码运行,还是需要转换一下,这次需要使用 eval 来转换。

我依旧是将信将疑的试了一下,输出真的变成 3 了!

兴奋的我冲出家门跨上自行车又冲向了坡低。

在我往坡低冲时,我不断的在尝试去理解刚才看到的教程和运行的情况。

突然,我恍然大悟,一刹那间就锊顺并理解了这一切。

我激动的往回蹬,到家直接把车仍在门口就冲进我房间继续验证我的想法。

那一天我反反复复的冲出家门跨上自行车又扔掉自行车冲回房间。

我妈当时恰好在我房间门口剁当天需要喂猪的猪草,她问我干什么呢,我只是嘿嘿的笑,没有回答她,因为我知道就算我说了她也不会懂的。

不久之后,我就写出了一个名为《学生工具箱》的APP(或者说是脚本,虽然 sl4a 支持将脚本打包为 apk,但是实际上也只是把python环境和脚本打包到同一个安装包而已,最终还是直接运行的 python 脚本)。

它除了拥有我上面说的简易计算器功能外,还涵盖了我当时知识范围内的各种计算(我当时上初中),例如解一元二次方程等。

之后我就将这个 APP 发到了乐讯论坛中,当时大概率是没有什么影响的,因为我现在对于我发帖这件事除了我曾经发过帖之外已经没有任何印象了。

我当时使用 python 写的最火的脚本其实还是上面说到的刷钻脚本,因为当时刷钻成功与否最重要的因素之一就是发送短信的速度。

当时普遍做法是开启飞行模式,然后把所有短信编写好并发送,但是由于处于飞行模式,所以短信是发不出去的,此时取消飞行模式,短信就会被一股脑的一起发出去。

但是这个方案有个缺陷,很多刷钻不仅需要“手速”,还需要严格控制短信的发送顺序,如果使用飞行模式的方法,还是有很大概率会失败。

于是我就写了一个脚本,可以一键完成刷钻,并且取名为 《刷钻神器》 发到了论坛中。

这个脚本引来了众多的用户,还有很多人找我定制他们想要刷的钻的脚本。

当时可是让我收获了满满的成就感。

再之后,在论坛中有人发帖称发现了一个名为 AIDE 的安卓 APP,可以在安卓手机上编写安卓原生应用,于是 SL4A 就被我抛弃,转而投向了安卓原生开发的学习中去。

我记得当时我用 AIDE 写了一款修改某游戏的存档的 APP,然后发到了这个游戏的贴吧中,但是遭致了大量的“差评”,因为当时安卓原生开发只学了个半吊子水平,加之我第一门语言学习的是 python ,所以非常讨厌 java 繁琐且杂糅的语法,就没有好好的去学习 java 的各种特性,导致app 写的很差,有极大的性能问题,修改一个很简单的存档,都需要运行十几分钟才能完成……实际上以我现在的目光来看,这种类似的 APP 即使是当时较为孱弱的硬件水平也是可以做到即点即修改完成的。

样样通,样样松

高中的时候,在奶奶的资助下,我拥有了第一台笔记本电脑。

那时候我因为青春期特有的莫名其妙和无知懵懂,不小心触犯了乐讯论坛的版规,导致账号被封了一段时间。

之后即使我账号被解封了,但是我还是决定再也不去乐讯论坛了。

就在这个时候,我了解到了自建论坛,也了解到一个叫做 phpbb-wap 的手机论坛程序。

看名字就知道,这是个基于 php 的程序。

于是我又开始长期混迹于 phpbb-wap 的官方论坛中,甚至还混进开发组,结识了它的众多核心开发者。

但是其实当时我并不会 php。

后来 phpbb-wap 也逐渐式微,我就开始想着自己开发一款论坛程序。

其实与其说是论坛程序,不如说是一个个人博客程序。

于是乎,我又开始学习 php,有了前面的 python 和 java 语言的经验,php 学习起来非常快。

与之对应的,我同步学习了关于前端开发(html,css,js)和数据库(mysql)的相关知识。

当时是啥都去学一点,然后啥都不去精通。

纯粹的就是 “样样通,样样松”。

第一次系统化学习

上面说到的都是我自己靠着零散的教程去学习编程相关知识,我从来没有系统性的学习过。

一直这么零零碎碎的东一榔头西一棒子的学习直到高中时。

某次信息技术课,任课教师在下课前提了一下如果我们谁对计算机方面的知识感兴趣的话可以去找他。

他就是陆老师,当时也是刚毕业没多久的大学生,想要闯出一番天地。

放学后,和我关系很好的一个同学找到我说我们一起去找陆老师吧,我觉得以后计算机会是很热门的东西,让他教我们一些真本事。

当我们站在陆老师面前时,他问我们对于计算机有什么了解,我同学说他什么也不会,我说我会写python,我还会写安卓。

陆老师点头说,他准备教我们编程,然后去打比赛。

那时候我还没有买电脑,所以使用电脑打字非常慢,于是我略带羞涩的问:但是我打字速度非常慢,没有关系吗?

陆老师和办公室的其他老师都笑了。

笑罢了,陆老师说:打字速度慢反而是最小的问题,以后你熟悉了就会越打越快的。

那之后,每天放学和周末我们都会去找陆老师,他也向学校申请并准备了系统化的教案。

我们学习了计算机基础知识,学习了 C 语言,学习了 C++,学习了各种数据结构,学习了各种算法。

但是当初和我一起去找陆老师的同学却因为跟不上进度中途退出了,取而代之的是某日看到我们在机房学习时好奇的张望也被拉进来的另外一个同学。

在刷了无数道题后,陆老师为我们报名了那一年的 NOIP(全国青少年信息学奥林匹克联赛),我们学校成为了我们市第一所派出队伍参加比赛的学校。

而我们,自然就是我们市第一次参加比赛的队员。

最终比赛结果是我拿到了省级二等奖,其他人也拿到了省级三等奖。

这自然是我们学校乃至我们市第一次获得奖项,于是陆老师更有干劲,在暑假还开办了暑期夏令营,第二年的机房坐满了人,而在我最开始学习那一年,偌大的机房除了陆老师就只有寥寥数人,稳定每次都来的只有我和另一个同学,其他人总是来了又走,走了又来。

其实我至今仍然记忆尤新的是,当时参加复赛的所有人中,除了第一名是满分外,其他人都是只有100-300分。

当时复赛是 6 道题,一道题 100 分。

我记得我只做出来了第一题,第二题手算出了部分结果然后直接输出,其他题目都是随便写了点。

我的得分好像是100多分还是200多分,具体忘记了,但是就这样的水平我居然还能排到二等奖,足见当时我们省的整体水平。

但是外界可不管你的分数,只看你的奖项,于是我凭借二等奖的奖项获得了参与大学自主招生的资格。

也许你会以为这会是我从此走向正轨的开始,事实上,这只是我唯一的高光时刻。

现实就是现实

现实就是现实,想要实现跃升不是那么容易的。

我自主招生选择了陆老师的母校。

虽然当时我获得了自主招生资格,但是我去参加自主招生面时时猛然发现,其他人都在不停的练习。手里还拿着一本不知道哪里来的面试技巧指南。而我却只是一个人背着一个包,什么也没准备,连面试会面什么都不知道就和朋友坐着绿皮火车去了大学所在城市:重庆。

我去面试时,朋友就在学校里面闲逛等我。

面试官问了什么我已经基本忘记了,只记得他问我的一个问题:你觉得你学习编程对你以后有什么帮助?

我紧张的头脑紧绷:学习编程可以培养我们日后学习其他领域知识时的逻辑思维能力而且对其他领域的也有极大帮助

面试官:什么样的逻辑思维?能够有什么样的帮助?

我一时不知道该怎么回答,只能机械的重复:编程可以培养我们的逻辑思维,以后学习其他东西会有很大的帮助。

面试官:什么样的帮助?

我:……

不用说,我面试没过。

其实即使我面试过了也没用,因为自主招生的前提条件是高考分数需要过一本线,显然,我的高考分数也没过一本。

面试没过归没过,我和朋友还是在重庆好好的玩了一番。

没过多久,应上面说到的认识的 phpbb-wap 的开发者的邀请,我还和他们一起组队去上海参加了一场黑客马拉松。

毫无意外的,因为我们什么都没准备的,所以什么都没做出来,自然什么奖项都没拿到。

在那儿之后,我开始填报志愿,险些全部滑档,好在被服从调剂兜底了。

最终大学填报的计算机专业被调剂了到了四大天坑之一的材料学。

大学时因为挂科错过了转专业的机会,大学毕业后去了某大厂打螺丝(字面意义的“厂”和“打螺丝”)。

一切似乎跌落到了谷底。

不屈

打了几个月螺丝后,终于忍受不了暗无天日的流水线生活,果断辞职跑路。

幸运的是,在辞职之前找到了一份老家的工作,而且还是我心心念念的软件开发岗位,虽然不是软件公司,而是一家传统制造业公司,但是对于我这个非科班,且上一份工作是流水线打螺丝的两不沾求职者来说,有公司能够愿意收留我就不错了。

去这家公司前本身也不抱有太大的期望,只当是作为一个跳板,让我有一份软件开发的履历,方便后期跳槽。

因此当来到公司发现加上我所有软件部门只有四个人的时候我并不意外。

当发现软件开发流程各种不规范,没有测试,没有产品,没有UI,一个人就要负责所有的东西时我甚至还觉得这样很自由呢。

毕竟怎么做,做成什么样全是我自己说了算,领导只看最终的结果而不会关心我是怎么实现的。

于是我按照自己从网上学习到的各种优秀开源项目的结构和写法慢慢的把公司的项目改造成了我看起来“赏心悦目”的样子。

因为这是家小公司加上只是为公司的硬件设备写配套 APP,所以平时几乎没有需求,除了隔三差五的维护一下现有软件外,几乎没有什么事可做,于是我开始自己学习一些新的技术,研究更多的开源项目。

因为我也知道自己的薄弱点在于对知识不够深入,并且知识没有成体系。

所以我就在恶补这方面的知识,但是越是恶补越是觉得这公司就像草台班子一样。

所以我萌生了想要尽快跳槽,去真正的软件公司好好学习的想法。

结果我还没跳槽呢,公司先倒闭了。

最终我来到了现在这家公司,

这是一家几乎所有员工都是开发的公司,做的是自有产品,也不是外包。

产品、测试、UI、开发 各个岗位配套齐全,我以为我真的可以实践我学到的规范式开发了。

屎!

1

一直以来我都自觉我的代码写的很不规范,不知道的东西很多,但是我从来不吝学习新的东西,不懂的东西我总要去弄懂。

也总是确保自己的知识体系保持更新。

甚至到了有点强迫症的地步,软件有更新必须第一时间更新、框架有更新必须第一时间跟近、第三方模块也要保持在最新版本。

当然,在吃了几次不兼容的亏后,现在老实了很多。虽然还是喜欢保持最新,但是更新前会更谨慎,确保不会更出问题来。

(点名批评某些框架明明采用的是语义化版本,却不按照规范发版,导致我还以为只是小更新,结果却存在破坏性兼容问题)

所以在进到这家软件公司的时候我还是有点忐忑的,生怕我会跟不上公司节奏,但是事实证明,是我想多了。

我入职接手的项目是一个原生安卓项目,这个项目总的来说比上家公司的项目规范多了,虽然用的是非常陈旧的框架,一些代码写的也不是很规范,但是还算是正常级别的,毕竟人总有偷懒的时候嘛,写一点不规范的代码只要能跑得起来,没有 BUG 也算情有可原。

虽然这些不规范的写法埋下的坑也着实坑了我好几次,但是也能接受。

最最最最最最让我无法接受的是,在这家公司入职半年多后,领导让我帮另外一个项目赶赶进度。

这个项目是个 Flutter 项目,只是我应聘的时候明明应聘的是原生安卓啊,我也明确表示过我不会 Flutter。

不过既然领导让我写 Flutter 那我就写吧,还能带薪学习新技术我当然是愿意的了。

没曾想,这就是梦开始的地方,可惜是噩梦而不是美梦。

我敢说,自从我接触编程以来,从未见过如此恶心的项目……

从代码仓库拉代码时就给了我一个下马威,拉下来的代码无论如何跑不起来。

因为我此前没有学过 Flutter,我也不敢妄下结论。

所以即使编译器一直提示我缺少xx文件、没有找到xx方法时,我依旧认为是我配置有问题。

直到多次排查后,我终于是确信了,代码仓库的代码不全,缺失了很多代码。

我赶紧和领导说明了情况,领导让我去找同事S,也就是现在负责这个项目的人,但是 S 对我爱搭不理的,过了很久才给我发了一个压缩包过来,他说这就是我缺少的那几个代码文件,让我复制到项目里面就行了。

等我学了一段时间 Flutter,正式开始着手写需求的时候,头只有那么大了。

Flutter 一直都被广为诟病的地方就是代码嵌套太多,一个简单的页面就可能会被嵌套非常多的层级。

我在学习 Flutter 时这个问题被各种文档教程反复提交,并且反复强调需要合理的抽出布局代码,避免嵌套过深。

当我好不容易找到我需要改的模块时,映入眼帘的代码让我目瞪口呆。

洋洋晒晒几千行代码全部塞到一个方法中,没有任何拆分……

而且同事S似乎还嫌天下不够乱,在某行代码中嵌套了几十上百个三元操作符,是的,你没听错:

一行代码!!几十上百个!!三元操作!!

并且没有任何的格式化!!!

好巧不巧的,我要改的地方就在这上百个三元操作符中。

你知道这对一个 Flutter 新手是多大的震撼吗?

我只能慢慢的试图锊清这一大坨究竟是什么东西。

这就不可避免的造成进度延期,于是我只能在晚上留下加班。

这是我这辈子最后悔留下的一次。

也许是他们也没想到还有人在公司加班,总之在我试图锊清这坨狗屎的时候,我听见同事S正在和领导远程开会。

同事S抱怨需求太多他做不完了,领导就说让他别担心,xx(我)不是已经在慢慢开始帮他写了吗?

同事S听完直接炸锅了,怒气冲冲的说:就他写的那都是些什么玩意儿,根本没法用,都写了些什么东西,我宁愿自己加班写也不会用他写的东西。

接着就是一顿对我的各种诋毁。

那瞬间,是我最后悔留在公司加班的一次。

于是我趁着他们还没开完会就自己灰溜溜的回家了,连加班都没提报。

当然,这件事发生在我刚入职的那一年,自那以后,领导也没叫我再写过 Flutter 项目。

2

过了几个月后,领导又开始让我写 Flutter,只是这次写的时一个全新的模块,而且涉及到的更多的是原生侧的东西。

这次就不会和同事S的代码产生太多的冲突。

也就是从这次之后,我终于知道了为什么同事S会炸锅,以及为什么他会写出这么逆天的代码来了。

当我从拉出的开发分支中写完这个相对独立的模块,让同事S同步一下代码,把这个模块并进他的“主分支”时,他,一个从业至少五年的软件开发,居然,不会用 git!

我终于明白为什么我刚来时代码仓库拉下来的项目会缺少这么多文件了。

知道我为什么“主分支”要用引号吗?因为得益于他的git知识,这个仓库根本不存在主分支的概念。

所谓“主分支”就是他自己在用的那条改的乱七八糟的分支。

然而,这只是一个开始,后来可能是看我这次任务完成的不错,领导开始渐渐的给我安排更多的 Flutter 任务。

每次写 Flutter 都是一种折磨,你永远不知道同事S会给你什么惊喜。

不会分支管理,不知道什么是 commit、什么是 push、pull,不知道怎么合并代码,怎么解决冲突,更遑论 cherry pick 等操作了。别问我为什么需要用到 cherry pick,感谢同事S的不管理分支,如果发版时需要单拎出来某个功能上线时,只能通过 cherry pick 牵出实现这个功能的 commit 了。

对了,说到这里,感谢同事S,每次提交的 message 永远都是 “修复 BUG”,一看几百条提交记录,全是 “修复 BUG”,你要是想找到某个功能点是在那个提交被修改的,你就找吧,一找一个不吱声。因为他不仅不好好写 message,而且每次提交都会混杂无数的改动……同个功能点也会给你杂糅在多个完全不相干的提交中……

在我多次教他怎么使用 git 后,他似乎很少再出现不知道怎么解决冲突的情况了,我以为是他去学习了解了怎么使用 git,直到某一天……

测试提了一个 BUG,我复测后猛然发现,我的修改全部不见了!

我很惊讶,这是怎么做到的?能把我的修改全部弄没了?

过去一找他,好嘛,我以为是他学会了怎么使用 git,原来是不知道从哪里搜出来的一个带 GUI 的 git 软件,平时他对 git 的操作就是在这个软件里面点点点。

好家伙,我从来不反对使用 GUI,甚至有点厌恶那些整日鼓吹只有使用命令行才是真大佬的人,但是厌恶归厌恶,需要用到的知识我都会去学,例如即使很讨厌那些动不动就鼓吹应该使用 vi 的人,我自己也还是会去了解 vi,并且偶尔也会用一用,但是更多的情况下我也还是会去选择更方便的 GUI 软件。

只是这也并不妨碍我在使用方便的带图形界面的软件时首先了解它的实现原理,再不济也得了解这个软件的使用方法吧。

像同事S这样根本不了解 git 的运行方式,只是一味的对着图形点点点,暴雷只是早晚的事。

搞笑的是,也许他之前一直是单打独斗,所以不喜欢提交代码,或者总是提交了不 push,又或许是他不知道这两者的关系。

总之,在我加进他这个项目之后,他不得不开始提交代码了,然后我就发现,他不仅会不提交很多文件,而且还不知道 .gitignore 的存在,所以总是把编译缓存提交到代码仓库中,每次我都会把这些加进 .gitignore ,然后下次同步代码时他又给我删掉了……

直到某一天,CTO 艾特我和同事S,并且附上截图,原来是我们的代码仓库容量已经达到惊人的十几G,超出了配额,CTO 问我们怎么回事。

同事S还想甩锅给我,立马就抢答:因为分支太多了。

(因为他自始至终只用一个分支,而我会建不同的dev、feature、hotfix分支)

CTO 一脸懵逼的说,这和分支数量有什么关系,这又不是 SVN。

我看了一下代码仓库,突然醒悟……

这货提交了十几个G的编译缓存到仓库中……

CTO 无奈只能封存了原仓库,重新建立了新的仓库。

然后我再次把 .gitignore 配置好,并且让他不要再删 .gitignore 了。

他还一脸不乐意一直在那里逼逼叨叨。

一通逼逼,总结就是,这个事情还是怪我

3

这位神人的操作远超你们的想象。

之前我不是提到过他写的代码几千行全部扔到一个方法中,根本没有任何解耦,妥妥的高耦合,低内聚嘛。

你以为你只是修改了一个小小的功能点,但是实际上牵一发而动全身,很多地方都会开始暴雷。

于是我每次修改需要改的模块时,都会习惯性的给他们拆分成小的方法模块,最大程度的实现复用,在他写的一坨代码中捋清逻辑后写上注释,并且把代码格式化好。

然后,等我下次同步代码就会发现,这位大神,把我注释删了,代码改了,格式化也去掉了,又全部扔到一坨去了。

后来我算是怕了他了,只要能起新文件的我都起新文件,尽量不要去用他的东西。

但是如果是一些不可避免的需要用到他写的代码的地方,简直就是灾难。

他似乎不知道常量是什么东西,整个项目中充满了魔法数字、魔法 key。

而且他的变量命名也让我看的一头雾水,也从来不声明变量类型,一个 dynamic 你就猜去吧。

这也就罢了,更多的时候他传参会直接传递一个 map。

往里面塞一些乱七八糟的数据,你要用的时候你就找 key 去吧,一找一个不吭声。

如果是需要确定某个数据是在哪儿被改了,你就做好找一天的准备吧,因为参数是个 map,key 是直接写的魔法 key,你永远不知道这个数据是在那次传递时被改掉的,IDE 的 lint 根本没法用。

如果你以为就算参数是个 map,就算 key 是魔法 key,至少参数的流动是单向的呀,这有啥不好找的话,那么你就错了。

他还喜欢一个参数在完全不相干的功能模块中复用,好嘛,该复用的时候不复用,不该复用的时候瞎复用了属于是。

4

也许你会说,那他这么写没人管吗?

我也不知道为什么,总之在公司时,后端和他就接口问题争论时从来没有赢过,即使后端才是占理的一方。

因为他有一招绝技,就是 “那我们去找x总呗”,只要此话一出,基本宣告对方死刑了,因为不管是 x 总,y总还是z总,总是会偏袒同事S一方。

随便举个例子,在某些接口,后端需要同事S POST 一个列表过去,但是同事S一口咬定 Flutter 不支持直接 POST 列表,必须要以 KEY-VALUE 的 map 形式提交数据。

后端同事表示闻所未闻,什么请求框架居然还会有这种限制?

结果自不必说,最终是后端妥协。

后来某次和这位后端对接功能时,他也不服,就问我 Flutter 真的只支持 POST map 吗?

我说没有啊,可以直接 POST 列表的啊,你看看我之前对接的 xx 接口不就是直接 POST 的列表吗?

后端一脸茫然:那同事S为什么一口咬定不支持?

我:因为我们公司这个项目之前的开发封装了一个请求框架,那个框架中只支持 POST map,但是后来我不是加上了 POST 列表了吗?

后端:啊?同事S就这么菜的理所当然啊?

最能体现领导对同事S无条件偏袒的还得是下面这件事。

有段时间因为公司组织结构变更,需要重新备案公司的域名,备案期间域名不能解析,所以为了确保不中断服务,领导要求同事S的 Flutter 项目和我的原生安卓项目都紧急发布一个版本。

确保在主域名无法使用时自动切换到备用域名,解决方案我们自己去研究。

最终完成这个需求时,同事 S 和我选择了两种不同的解决方案。

同事S使用的是方案A,我在查阅资料以及实际测试后发现方案A在某些边界条件下存在问题,可能会导致误判,于是我选择了方案B。(事先我们互相都不知道对方的方案选型,因为是两个独立的项目)

在临上线前领导问我用的什么方案,我说我用的方案B。

领导质疑的说:同事S用的是方案A,你为什么不用方案A?

我:方案A我也考虑过,但是我测试下来存在xxx问题,所以选了方案B。

领导:同事S写出来不是没有问题吗?怎么你会有问题?确定不是你写错了?

我:我演示给你看

演示完后领导依旧依依不挠的说同事S写的都没问题,就我问题多。

……

最终结果就是,上线后不久我们的服务就出现了大范围的中断。

直接惊动了大老板在全员群中要求立即解决这件事并且彻查原因。

5

这还只是一个缩影,至今我和同事 S 的开发环境都不匹配。

因为不知道为什么,这个项目使用的环境版本特别古老,已经是快十年前的版本了,现在各个 IDE 都已经不再兼容这个环境版本了,但是我们项目却还在使用它。

一开始我还以为是项目创建的比较早。

直到我某次无聊翻看项目原始仓库的提交记录。

我突然发现,在同事S入职之前,这个项目的分支管理都还是正常的,而且提交信息也是正常的,甚至使用的环境版本也是尚未被弃用的较新版本。

但是这一切自从某条名为 “修改BUG” 的提交被 push 上来时,什么都变了。

环境版本被修改为了上古时代版本、其他人的提交都没了,自此之后的两年多里,整个 git log 中只剩下了 “修改 BUG”。

原本井井有条的代码文件也变得越来越臃肿,一个文件上千行各种嵌套的代码只是家常便饭。

6

一不小心就吐槽了这么多,其实我写这篇文章的导火索还是最近又开始改这个项目,实在是改的我头大。

之前虽然零零散散的在帮忙写着 Flutter 项目,但是涉及的需求都比较少。

最近同事S不知道怎么想的,去找了领导好多次,每次都去诉苦自己任务太多了做不完了,怎么也要领导把 Flutter 的需求任务多分点给我做。

领导同意了,然后就让我以后全权负责xxx模块。

恰好最近这个模块需要修改,我就开始吭哧吭哧的修改。因为领导发话这个模块以后由我来负责了,所以我没有按常规的能不用同事S的代码就不用同事S的代码的策略,而是选择直接修改原文件。

我花费了大量的时间把这个模块的文件重新整理拆分并写好注释,然后开始写这次的需求。

一切顺利,没有任何问题,测试环境测试通过,预发布环境测试通过。

到了上线那天,同事S突然找我说:你这个地方的实现不行啊,我建议你换成我之前的实现。

我没有理会他,只说现在测试都通过了,马上上线了,不要再改了。

然后就是等同事S发版上线。

(我没有发版权限)

原本一切无事,结果过了几天我在写另外一个需求时,突然发现上次上线的商用环境的那个功能,有个严重的 BUG,但是我本地运行却复现不出来。

我怀疑是同事S修改了我的代码,于是重新同步代码,但是没有任何更新。

于是我就让同事S把他的代码 push 一下,我要写新需求了。

同事 S 把他一周多没有 push 的代码推上来了后我人傻了……

他把我上次写的代码全部删除了,换成了他认为合理的实现方式……

而他所谓的合理实现方式就是所有代码挤在一堆,不格式化,不剥离不同的功能方法,变量参数全部使用 map,不写数据模型,不加中间变量……

于是你就能看到满屏幕的 (xxx?["yyy"]??{})["zzz"] 搭配上同事S 特有的三元操作符仙人风格,那酸爽……

好,代码问题咱就不说了,我就请问了,在商用发版前突然删掉已通过测试的代码改成你自己觉得好的代码然后不通知我,不通知测试,不通知任何人,代码也不提交,我请问呢,您是想干嘛?

我真的气的想当场破口大骂,但是想了想之前的和他争论的同事的下场,我只是默默的把一切证据录屏录制下来,然后还给他留了情面的只是私发给他。

结果他气冲冲的跑过来质问我:“这哪里有问题!!我什么时候改你代码了!!!”

我:“你要说你没改过代码那我能说什么了,你看视频了吗?视频录的很清楚了”

他:“哪里有问题!没有问题!”

我:“你看完视频再说”

…………

7

其实我一直不理解为什么领导总是对同事S这么偏爱,根据我观察以及和大多数同事的交流,就没有不讨厌同事S的。

但是同事S却深得领导的喜爱,我也仔细想过,为什么会这样。

这样的水平却能拿着比我高的多的薪资,而我却连一份工作都难以找到。

为什么呢?

后来能想到的答案也许就是同事S什么都喜欢去参一脚,明明不是他管的事他也要去参一脚,在我看来我非常讨厌这种行为,因为每次开会都会因为他的参一脚而变得复杂且漫长。

举个例子,同事S负责的是项目A,我们在开会时在说项目B,同事S总会跳出来说项目B的哪里哪里不合理,哪里哪里不对劲,项目B的同事就得花费大量口舌给他解释,因为同事S并不负责项目B,所以很多东西他并不了解,就需要大量的额外解释。

这种行为在我看来是非常令人讨厌的行为,但是领导似乎就很喜欢他的这种行为。

而且最最重要的一点是,他非常卷,每天总是最后一个走的,几乎没有不加班的时候,而且他是真的在写项目代码,不是在摸鱼。

我想这是领导喜欢他的最重要的原因吧。

但是,他这种卷,emmm……就很难评价。

属于工作效率极低的卷。

举个例子,作为一个 Flutter 新手,我在学习 Flutter 时就已经学会了利用 IDE 去调试项目,例如用 Flutter Inspector 配合 Debug 调试。

而同事S呢,我曾经开玩笑的说他是古法调试。

他就直接硬看代码,最多就是打个断点,插个日志。

我原以为是他水平高深,最高端的 debug 只需要最简单的方法来找……

结果,我现在非常确信他就是不会,甚至压根不知道有这些辅助调试工具。

他也不是什么高手,我不仅一次的和他一起找一个 BUG,我很快就找出来了,而他经常需要古法调试半天甚至一整天才能定位到 BUG。

他似乎还是反驳型人格,不管是什么需求,他总要想方设法的去反驳,反驳后端、反驳产品、反驳UI,没有什么东西是能入他眼的。

这就导致原本只需要十分钟写完的东西,他要先去找产品吵架两小时,回来后再找后端吵架两小时……

这么搞,你不加班谁加班?

8

因为自知我不是科班程序员,也没有经过系统的培训,所以一直以来我总是会小心翼翼且孜孜不倦的学习各种新知识,了解各种工具。

毕竟工欲善其事必先利其器。

但是,同事S这种水平还能在公司中混成“中流砥柱”,不禁让我怀疑,职场原来并不需要你有真本事吗?

对此,我的最终评价是:

一个连我已经告诉他有问题的代码在 X 行,让他改一下,他都会去拿着滚轮硬滚几千行的人。 (注1)

一个告诉我说他要把 .jar 库名字改成 .zip 然后修改其中的某个方法并重新打包成 .zip 并改名成 .jar 后就能用的“人肉反编译大神”。(注2)

一个连 git pull 是什么都不知道的人。(注3)

一个脱离了低级趣味,只享受纯粹的编程乐趣的人,如果不是记事本不能直接构建,他也不会用命令行构建,那么他一定是全司第一个使用记事本写代码的人。

一个永远不会犯错的人。(注4)

一个眼中容不下一丁点瑕疵的人。(注5)

补充

注释

注1

某次测试提了个 BUG,因为看他古法调试实在费劲,于是就帮他定位到了 BUG 所在文件和所在行并发给他。

然后就看见他在疯狂的转动鼠标滚轮,转了半天还没转过去。

我:你怎么不直接跳转?行号不都给你了

他:什么叫跳转?

我:Ctrl+G

他:不知道,不会,不管了,再说吧

注2

某日,他问我,他想修改项目中某个第三方 .jar 的代码,应该怎么改?

我表示这不是开源项目,没有源码改不了的。

他立即反驳:我直接从 IDE 中点开这个 .jar 都能看到源码啊,怎么可能改不了

我:.jar 是已经编译后的二进制文件了,你用 IDE 能看到是因为 IDE 会自动帮你反编译

他:那我直接把 .jar 改成 .zip 解压出来改了再打包回去不就行了吗?

我:……那是编译后的二进制文件,你怎么改?行嘛,你实在想改你就直接把他全部反编译了,然后改完再编译一下也行嘛

他:反编译是什么东西?我直接改成 .zip 不就行了吗?

我:……

他:你看嘛,我改成 .zip 都能看到类了

我:……

注3

某日,他使用的 git 图形化软件不知道出了什么 bug,即使重启软件,重启系统也不会同步代码,于是我告诉他自己手动拉一下不就好了。

他:怎么拉?这个软件都不显示有变更了

我:我说让你直接输入命令拉

他:什么命令?

我:你打开终端,欸,终端,对对对,就这个终端,输入 git pull 就行了

他:git pull ?这是什么?从来没听说过,你确定是这个?这东西我从来没有见过啊

我:……

注4

无论什么时候什么人,只要给他说他的项目哪里有 BUG,他总会立马反驳:不可能!没有问题!怎么可能有问题!是你自己的问题!

如果这个 BUG 涉及到后端请求,他会直接跑去骂后端:你他妈的改了什么玩意儿,现在出 BUG 了!

但是往往后端排查下来都是同事S的问题,此时他通常还要反咬一口:谁说这里可以这样写了,我就不这样写!

甚至最最离谱的是,有时候我只是修改了某个模块的很小的一个地方,那完蛋,这个模块认我当爹了,但凡以后这个模块出现问题,他就会看都不会看一眼,直接跑过来就说是我改出来的 BUG,但是不用说,排查下来通常都是他自己导致的 BUG.

注5

曾经我在写某个模块时,封装了一个通用组件。

某次同事S也需要做一个类似的组件,他正在抓耳挠腮的想应该怎么做的时候,我不知道抽什么疯,居然主动过去给他说这个组件我已经封装好了,你用就行。

他:哦?你写的什么垃圾,我才不用。

叠甲声明

因为我记忆一直不怎么好,好多事情都是记了个大概,所以如今回忆起来不免会“添油加醋”,所以上面说的事只敢保证大方向上的符合事实的,但是细节可能不太经得起推敲。

另外还有一个最大的问题是上面说的那些事件虽然都是真实发生的,但是不一定是按照记录的时间顺序发生的,因为好多事我已经记不太清是什么时候的事了,即使我已经尽力去求证确保时间线无误,也还是难免会有错漏。

这篇文章最开始写于 2025.09.28,因为不想被顶到博客首页,所以文章日期填的是2024.01.01

尾声

其实这篇文章想写很久了,但是因为我受过良好的教育,知道随便在背后蛐蛐别人是不好的行为,所以一直忍着,最多只是和好友吐槽一下。

直到最近这位神人直接在发版前连夜删我代码的事情真的让我愤怒的怒了一下,是的,我除了自己生闷气没有任何办法。

已经有无数的案例证明,和他争执,是必输的,而且是单输,甚至连双输都难以做到。

但是一直憋着实在难受,只能写成文章发泄一下了。

(补充:原本我写完之后把 “屎” 这一章隐藏了才发布的,因为我觉得写完发泄完就够了,就不公开发表了。但是,就这短短几天这位神人又三番五次的在发版前不告知我的情况下直接删我代码改成他的实现实在让我忍无可忍,故决定去他的仁义道德,我就是要公开)

恰好经由这件事,我突然开始在骑车下班的路上猛的想起了我最开始写代码时的事,现在想着还是会觉得那时候是多单纯啊。

单纯的以为程序员就是纯粹的写代码,而代码永远是纯粹的,程序员也是纯粹的。

最后修改于: 2025-10-11 09:41:13; 备注: 修改 《代码之始》 (e4da681)