Hello,这里是记录我从有记忆时起至2021年底编程相关历程的博文,如果您读到了这篇博文,可能是因为好奇点进来亦或是我又在装逼了,在此声明:我是废物、菜鸡。以下所有描述均属我的真实经历,记录这一切主要是给我自己留下一份回忆,也可以对自己经历的每一个阶段做一个总结,自省一下是不是已经开始停滞不前或已经开始急流勇退呢?
由于篇幅非常的长,我打算把经历切分成小标题给大家展现,基本是按照时间顺序发展的,其中部分包含了★的标题代表该段经历对我很重要。每个人都有自己的成长方式,文中会大量夹带我个人思想私货,希望在我的探索之路上能为您带来一点启发,如果想法与您有较大的差异也随时欢迎您进行批判。
0x00 写在前面
我们和世间万物的规律从生命诞生时起就牢牢地绑定在一起,如果以拉普拉斯妖假说中的描述来说,那现在发生在你面前的一切就是过去的结果、未来的原因,你所能够感知和分析的数据越多,那你就越能够预测下一步会发生的结果。在这个假说面前,命运仿佛不存在了,因为一切几乎都是由过去的因所注定的,如果你觉得它充满了未知,那就是你所能了解的信息太少了。
人类害怕未知,也在努力消解未知,信息差是永远能够产生价值的,学会信息的交流是古人类进化中至关重要的一环,信息交流产生语言文字,而语言文字使我们能够沟通思想,共同的思想产生文明。所以从古至今,我们都在竭尽全力的利用客观规律为我们搭建更快更高效的信息传输方式。
编程并不是什么高大上的东西,它只是人类在进行信息基建过程中的工具,它所衍生出的大量语言与技术概念、相关名词都只是让编程更加高效和方便协作,所有只为了实现一个目的:程序化,让代码按照特定的流程完成预设的功能。在编程的世界中,你即是拉普拉斯妖,你拥有上帝视角,你能够从一个叫“内存”的东西中,监测到程序运行时的所有数据,你能够预知代码的下一步将要做什么,此时如果把视角切换到正在运行的程序眼中,它无法预知未来,只能回忆过去,哎,这不就是咱无知的人类吗?但你却早已化身算命大师,算完了它的命运。
“一个仅靠工艺技能谋生,不关心建筑精神层面的匠人,不配当一名建筑师。”这是《建筑十书》中我很喜欢的一句话,每个产品都是一座建筑,它拥有它对外宣称的所有功能,仅此就够了吗?机器是绝对理性的存在,人类却是存在感性的,一个产品能否抓住用户的心,它的“灵魂”很重要,程序员作为产品生产的一环,不应永远只实现现有需求,而是应该以超出需求的眼光感性的看待整个产品,尽管许多时候你并不能左右产品设计,但这能够让你的代码设计足够的人性化、能够高效的解决问题并拥有更强的鲁棒性。
0x01 电
小时候,老家所在城市的供电设施还不够完善,夏天经常会面临因为用电负载过高而导致整条街停电的情况,这时许多人家都会随手拉出一台柴油发电机,仿佛停电已经是家常便饭,在家人拉动发电机后,看着旁边接线板的电压表与电流表指针跳动起来同时亮起的还有一颗钨丝灯泡,这对于那时的我来说就像魔法一样,也是从这开始我对电产生深厚的兴趣。
再往后,螺丝刀在手,家里的各种小电器(如电话机、手电筒、耳机、复读机、磁带、电风扇、光驱、收音机等)都没能幸免于我的毒手之下,妥妥的拆家小能手,稍微复杂点的电器拆开后不能说看懂一点,只能说是一窍不通,也基本是属于装回去还能多出几颗螺丝的水平。不过我很喜欢研究一些电器中机械的运行原理,倒是碰巧修好了一部分电器。
曾经还冒出过一个十分危险的想法,我从收音机拆了根天线,接到了一颗从电风扇拆下的启动电容,然后放到家里顶楼的露台顶上,正好是夏雷高发期,在想着如果闪电劈到这颗天线上会发生什么,原本已经预想看到遍地电容碎渣了,然而屋顶四周的避雷针似乎比它更有吸引力,自然是不可能轮到你个没接地小小电容的。
还曾用手指去戳老式电热水壶底座的金属点,按住一颗没反应,哎,那我就连续按住两颗,还没有?那我连按住三…,刹那间,可以感觉明显有一股电流从手流向脚部,幸好当时穿着拖鞋,估计电压也不高,及时的抽离的了手指,有惊无险。
再往后到放暑假到广州表哥家玩时,表哥送了一套自己的电学积木给我,这算是更加正式的接触电学,让我对电路构成有了初步的认识,特别是电压带来的更直观感受。
0x02 电脑
家里在很早的时候就配上了台式电脑,依稀记得应该还处于奔腾处理器时代,用着Windows 2000系统,有那么一段时间里,晚上老爸老妈就经常出门约会,留我自己玩电脑,这样的时机下我就接触了人生第一款游戏:红警2 共和国之辉,虽然后来知道这是国人做的红警2 MOD,但确实是许多人的童年记忆,彼时的我并没有策略运营意识,所以基本属于瞎打瞎建阶段,见到磁能坦克就觉得好牛批,算是我关于游戏的启蒙之作吧。
在此之后,家人开了一家小型洗车店,店中的办公室放了一台台式机,存放了不少流行的Flash游戏,2021年被各大浏览器集体抛弃的Adobe Flash Player当时是很火爆的,属于只要有电脑必装的插件,主要是因为网页大量使用Flash动画并且涌现了许多制作精良的Flash游戏,当年HTML5、CSS3相关标准还没出生,在这样一片蓝海之上Flash凭借着可嵌入网页的精美动画与游戏、应用迅速打下了属于自己的半壁江山,比如大家以前都在玩的QQ空间皮肤、腾讯家游戏(农场、牧场、停车场等)、4399、2144等等都是基于Flash。有些爱好者会把Flash游戏整理打包并下载到本地运行,其中就包含了一款名为“24层魔塔”的游戏,魔塔是一种策略类的固定数值RPG游戏,而这款游戏对我意义非凡,对我此后的经历也产生了极其深远的影响,这款游戏并非是魔塔系列游戏的首作,魔塔最开始是由两位日本人创作,后面胖老鼠工作室才由他们的作品借鉴并制作了这款游戏。在洗车店中有一个员工阿叔,35岁左右,左手拥有6支手指,我称他为6指叔叔,这也许是我第一个崇拜的偶像,他能够在不看攻略的情况下将魔塔打通关,我坐在旁边看他玩,虽然不是很懂,但我大受震撼,在他的手把手指导下,我也成功通关了人生第一款游戏:24层魔塔,让我懂得什么叫策略。
0x03 静态网站
上网在以前是一件昂贵又麻烦的事,需要接入电话线进行拨号上网,网速奇慢不说,费用还巨贵,速率只有每秒一两百kb左右,属于打开网页都是比较费劲的,而且如果拔掉电话线用来上网家里电话就打不进来了,属于典型妈见打行为,所以尽管有台式机也是不敢随意上网的,但却有个搭建网站的梦想,那时哪懂得什么服务器、域名、IP地址、动静态页面、Web引擎等等,不过机缘巧合下,我发现微软Office的Word程序中有一个导出选项是将Word文档内容发布为网络站点内容,尝试之后惊奇的发现,居然真的生成了网页HTML文件和一些图片资源,虽然自动生成的代码十分杂乱,却并不妨碍IE6轻松打开它且保持了与Word中相同的格式,我也很快明白这终究只是个本地的网站,无法在公网上被大家所访问,但这让我对一个最基本的静态网站有了些许认识。
0x04 图形界面
不知何时开始,我对于各种电脑上程序所显示图形化界面产生了浓厚的兴趣,甚至魔怔得开始使用画图软件画出各种程序窗体,甚至拿一部没有什么功能的学习机中的画图软件,逐帧做出一些界面,通过切换图片展现一些交互效果,大脑中幻想它真正的交互逻辑,虽然没有任何卵用,这十分的傻缺做法却曾让我乐在其中。
0x05 书
我是一个很内向的人,和家人也是很少的交流,甚至有要求想法也不会说出口,但初二那年的某一天突然跑去书城想亲自买本入门C语言编程的书,在向工作人员说明书名后,他在书架和仓库中翻找了一大圈,最终只找到了一本《轻松学C++》,也许因为是四线外城市的原因,书城里的技术书籍少得可怜,甚至这个书城也仅仅占地不到600平。
我非神童,当时自然是完全看不懂这堆概念名词与代码是什么意思,如今倒是可以确定这本书内容质量并不高,并且书名实在过于浮夸。虽然以前并没有学习到什么实质的知识,但依稀摸到了编程的尾巴,至少知道了编译型语言是需要经过编译的。
除此之外,还曾购买过一本家电维修宝典,想着能不能够通过自学学会维修电子产品,但实际上以当时的能力还是无法理解很多技术名词和知识,只是提前认识了许多电子器件,了解到他们分别用来做什么。
0x06 J2ME时代
在Android与iOS系统还未二分天下之前,像塞班、黑莓、MTK平台等等操作系统上都搭载了J2ME平台,这是搭载于各种手机或小型设备中的Java虚拟机和标准化Java API,由于Java的平台无关性,使得任何使用Java开发的程序都能跨平台运行,这无疑进一步的促进了移动平台技术的发展。当时手里的不管是品牌机还是山寨机均搭载了一款“咖啡杯”图标的程序,这就是J2ME本体了,你可以轻松的从各种软件商城和论坛等地方下载和安装后缀为.jar格式的安装包,手机软件生态在这样的环境下逐渐成长了起来,与此同时成长的当然还有盗版、破解游戏的生态。作为处于时代潮流之中的一员,我自然也加入了进去,至今依然怀念当时玩过的各种游戏以及使用过的软件,国产游戏成为了内购重灾区,有些内购真的是太离谱了,尝试过破解短信内购,通过反编译绕过内购代码再编译打包。流量在当时也是非常昂贵的,10元就30M,所以免流也是各种玩机党的香饽饽,基本就是利用运营商的一些免流入口,免流的感觉是真的爽。
0x07 曙光
如上文所说,魔塔给我带来了深远的影响,魔怔的我甚至开始在白纸上,绘制地图、怪物、道具,我堂哥相较我更早的接触网络,也对魔塔有兴趣,某天他跟我说在百度贴吧上有个叫魔塔吧的吧,他们都在使用一款名为 RPG Maker XP 的工具来制作魔塔,抱着试试的心态,我去尝试下载安装了这个工具,令我大受震撼,世间竟有无需编写代码就能做出RPG游戏的工具!哪怕只单用条件分歧就能实现许多逻辑响应,虽然更深入DIY的功能还是需要去更改一些Ruby源码的,但仅工具所提供的功能就已经足够了,在深入魔塔吧后,发现他们为使用此工具开发魔塔的吧友们开发了魔塔样板,通过导入这个工程,就可以使用样板中的相关资源,非常方便,我也使用样板尝试做了一款自己的魔塔,玩着自己成品的感觉十分有成就感,这种无代码体验进一步激发了我对编程的兴趣。
0x08 岔路
大家的肯定不止对一样事情感兴趣过,除了编程,我还曾经对写小说感兴趣,初中在学校寄宿的那段时间里,经常大晚上熄灯的时候拿着一本笔记本和笔,架上床桌,放上小台灯偷偷写恐怖小说,为什么是恐怖小说呢?因为我的梦太奇怪了,只要白天睡着必定做噩梦,而且梦境都是身处一个城市之中,在里面我仿佛陷入了一种无限的循环中,在城市的各种场景中发生着诡异的故事,这激发了许多关于恐怖元素的灵感。最后由于我的文笔实在烂的出奇,字也难看得没眼看,最终放弃了,哪怕有那么一点潜力,也许真的就走上另一条道路。
0x09 你真幼稚
“你能不能别那么幼稚。”,这句话是我小学的班长对我说的话,他是班里最优秀的人,虽然忘记是几年级了,但这句话如同魔咒一般,一直把我困在其中,当时的我想不通什么叫幼稚,我只知道我需要摆脱它。老家和小学离得很近,几乎5、6分钟就能走到,一直保持这样两点一线的生活,尽量不与其它人打交道,按时上学,按时回家,性格内向,同龄人交流的缺失,让我的思维与他们已经开始脱节。我当时恨我的班长,也许是因为我喜欢的女生就是他旁边的副班长。
这样的阴影似乎伴随了我很久,到初中时因为我各种奇怪的行为被大家称为囧宾,我知道他们在嘲笑捉弄我,他们学习好能力强,老师们自然不会认为好学生会有什么问题,这些让我在很长一段时间里都是处于半抑郁状态,直到有一天我蚌埠住了,直接跟家人说我想去死,不想活在这个世界上,感觉自己就是个弱智不配活着。好在最后还是平息了情绪。
让我有脱胎换骨感觉是始于初中我玩的一款名为QQ降龙的手机游戏,最开始是表哥带我入坑的,在里面我是梵天门派的玩家,在各种帮派中和来自五湖四海的玩家交流,一起战斗等等,我听到了许多他人的故事经历,在初三的暑假里,我在玩这个游戏的过程中仿佛体验了一把人生的酸甜苦辣,也氪过金,我的想法仿佛在这潜移默化的影响中,逐渐摆脱了不少稚气,这也许是成长?
0x0A 高中
我曾说我要去读中专,不想上高中了,当时我是读书无用论的信徒,被劝去尝试考一下我们县城里比较好的一所高中:彭湃中学。老爸跟我说,“你要是考不上彭中,你就不用上高中了”,最后还是争点气,上了高中,现在回想起来,这一步他们并没有做错。
我一直在寻求一些能够让我与众不同的东西来满足自己,又一次拿出了编程,也许是时机已到,这次一拿出来就一发不可收拾了,我又前往图书馆借阅了两本书,分别是《21天学通Java》和《Flash8动画设计制作入门与提高》,这标题很明显都是标题党,但在当时线上商城还未普及,本地图书馆确实只能拿到质量不高的书籍。
0x0B 纸上写码
由于没有电脑能够实践,只能先在纸上写着看看,当时写了一段C语言代码,没有编译器的情况下也没法判断是否写错,被无情的嘲笑了一波。
0x0C 编程小组
我们高中那一届涌进过一部分年轻老师,其中一位是我的数学老师,他叫刘畅,人比较瘦小,但脑洞非常的大,思维也很跳跃,在一次课堂上,他突然提到编程,然后问了一个相关的问题,我回答了,他眼睛仿佛瞬间放光了,马上开始商量组建编程小组的事情,同时任命我为组长,于是在这么一个小城镇,第一个中学生编程队伍组建起来了。
最初,这个小组就是定期分享一些技术知识,虽然大家都一知半解,但都在尝试学习,我在想,如果能让更多的人学会编程该有多好,未来的某一天也许人人都需要学编程呢?
接下来就是刘老师的脑洞鉴赏:
“你要好好努力,把编程社发展壮大起来,然后有财力支持后,大力要求学校进行教学改革,一些枯燥的科目都应该删掉,一起来学编程吧”
“以后社团发展成公司了一定要把彭中买下来,当编程教学用地”
“去努力把学校电脑室拿下,每周六对社团开放”
“等我去华中师范海丰附属中学的时候我要在那里实现我的教学改革”
“神会保佑你的”
“你手的侧面有三条线啊,你这辈子要经历三次婚姻”
虽然他讲的大部分话都不靠谱,但如果没有他,也许我会更晚的入坑编程。
0x0D 编程社
我将我的想法告诉了数学老师,他很支持,于是很快就开始了筹划工作,设计出了编程社的Logo,用当时从家里拿的旧安卓机起草了社团建立申请书,然后在网上订购印制了1000份社团宣传单以及上百颗印有社团Logo的可佩戴徽章。
传单到位后我马上趁着午休时间把传单发到高一和高二年级学生的课桌上了,很快,整个下午就陆续有人进入社团的QQ群中,也陆续有人到我的班级门口递交报名回执,到了晚上群里已经有120多人了。
其中有比较积极的我就拉上作为管理员,商谈下一步计划,其中一部分人至今还保持联系,之后还产生把编程社的活动范围扩大到整个市区的想法。
但好景不长,大部分人进来群里主要是来凑个热闹,或者遇到难度后直接放弃,最后群里就乱了起来,于是我们决定进行初筛和复筛,建立过两个群用来筛选出最终合适的社员,经过一波筛查,最终只留下来二十几人,之后还制定了相应的社团规章制度用来规范风气。然后给他们发放了社团的徽章,刚开始的有些大,挂衣服不便又订做了一批小徽章,于是大徽章就成了各位的书包挂饰。
0x0E 赌徒
都到了这时,我却依然在抱怨应试教育,还在认为自己不高考进入大学,光靠自己拼也能闯出一片天地,想要跟命运赌一把大的。但现在已经认清,应试教育是有问题,可这是在我国基本国情下筛选人才的最好办法了,只有考入更好的学校才能有更多的资源支持你去完成目标,我们不能为了抱怨而抱怨。
0x0F 免费空间
我结识了一名好友,他向我推荐了免费空间并为编程社搭建了一个官方网站,同时自己也在运营一个名为“海丰萌客网”的网站,后来成为编程社的前端部部长,免费空间其实就是一种共享虚拟机,和如今vps有一些区别,首先它是免费的,因此通常和其它站点共享同一个IP地址,带宽也是共享的,处理器、内存、存储资源也比较有限,不提供shell,只提供最基本的控制面板,可以进行ftp上传,提供基础的动态页面解释服务(如PHP),这种主机一般只能用来搭建一些个人的小站点,而当年的这批免费空间运营商早已不存在了,用爱发电还是太难,站点管理,DDOS防御等等都得面临巨大开销。
0x10 申请驳回
编程社的建立申请被驳回了,校长表示,你们现在这个阶段应该好好学习,高考比什么都重要,这些社团等到大学再去搞吧。
这让我很沮丧,明明学校里的文学社、天文社、雅言社、吉他社等等都能光明正大的运营,为什么我们就不能建立呢?我决定不顾反对,先隐蔽点做社团活动,能带多点人入坑就多带点。
第一次被拒后还曾写了一篇长篇报告由我们几个主要成员去交给校长,但并没有带来什么改变,这篇报告由我一位社员代笔,。
后来我所接触的某中学的编程社社长在申请建立社团时也遭遇着同样的问题。
0x11 社团开课
我们专挑周六日或放学后的时间集结社员在教室里开会和教学,由于学校的反对,自然是无法申请到微机室作为教室的,我抽空制作了每节课的PPT,只开成了三节教学课,后面保安大叔发现我们在偷开课就把教室锁了。
第一节,主要是讲述计算机的发展史、计算机的基础常识、计算机的分类、微控制器基础知识、数据表示基础知识。
第二节,主要是讲述计算机组成和工作原理、什么是编程、什么是编程语言、什么是编译。
第三节,主要是讲述软件的基础知识,常用软件功能的使用方法,认识一些工具。
之后还举办过一次社内的笔试答题比赛,自费了买一些东西作为奖品发放了。
0x12 社团作品
在编程社中不乏有基础有水平的成员,比较典型有:
副社长使用RPG Maker开发的萌宠成长记和手机版音游Sparkling,他的作品更讲究审美,对设计有要求,因此它后来成为了一名优秀的设计师。
前端部长使用易语言实现了一个成绩查询工具,可以通过学号和姓名直接查询到成绩而不用登录缓慢的教务系统,其中最骚的操作放到如今也十分亮眼:通过请求新浪博客博文获得的内容判断是否需要更新工具的版本,并且将数学必修三的所有编程题目都使用易语言实现了一遍,现在他已经进入绿盟工作。
还有许多作品没有留存截图,但这些让我发现中学生是完全有能力学习并应用编程的,让我对编程社存在的必要性更加肯定。
0x13 电脑自由
在高中的暑假里,我被批准使用家里的笔记本电脑,品牌是宏碁(Acer)的,据说它是家人在药店抽奖抽中的(我不太相信)。
3D游戏在当时也算是越来越火,我打算体验开发一款恐怖的3D小游戏看看,果断下载了Unity3D,建模软件我从3dsMax和Maya选择了更容易入门的3dsMax,不过门槛稍微有点高,当时也就是图一乐,毕竟对材质贴图都还没理解透彻,还为此去学校操场一块废弃的场地实景拍摄了一些素材,准备建模来着,之后还去试了下刚出新的虚幻UDK引擎,实实在在的给那次时代的光影效果震撼到了。
0x14 初试Java
与所有Java初学者一样,下载了JDK,接着查询文章把环境变量配置好,不一样的是第一份代码并不是HelloWorld而是用记事本编写好一个加法计算代码,第一次使用javac编译出了字节码文件并运行,这象征着我正式踏入编程世界了。
我学习一样新东西的方法很奇葩,如果给我一本书,我不会把它完整看完,而是从目录中挑选出我感兴趣或者我现在就需要用的章节来阅读,像学Java这里,我直接跳到了Java Swing的部分学习窗口程序的开发,由于当时还没学习文件IO相关知识,只配合Windows批处理bat文件实现了一个清理垃圾文件的功能。
0x15 Winform与PhotoShop初接触
在此之前学习Unity3D时发现里面可以使用的脚本语言中包含C# Script,为此我误打误撞购买了本《C#从入门到精通》,之后才发现原来C# Script和书中提到的C# Winform不是一类东西,前面的书名大家可能见得不多,但是这个《XXX从入门到精通》系列肯定很熟了,出了名的智商税书标题,后面还买过实战类的书籍,既然入了Winform的坑那就入到底吧。
当时安装的开发环境是Visual Studio 2010,这是一个十分笨重的版本,如果没记错,单安装包就接近4GB,启动速度慢且占用资源高,最后为了流畅的开发,甚至不得不把Windows的效果调整为性能优先,硬生生把Window7的界面拉回到了Windows2000的模样。
使用C# Winform做了个巨丑无比的界面,估计请外星人来看都觉得不正常,不过在这个过程中对Windows的空间和COM组件有了一些了解,印象比较深刻的是异形窗体存在镂空的时候在某些系统无法显示为透明,动用了GUI绘制才解决。
作为一个程序当然需要有各种图标,当时有免抠图标的网站特别少,所以把PhotoShop的抠图给学会了,就开始各种奇葩抠图,不过PS在以后的工作中已经是经常使用的工具了,没有UI的时候,自己就可以干完活。
0x16 刷机吧
这是一部只有几百块的语信T31,第一次尝试给Android手机刷机,见识到了ROOT权限也了解到了Recovery,通过线刷方式刷上了MIUI开发版,当年的MIUI就是香啊。
0x17 神经病
下面是一个注册登录逻辑,当时我认为数据库应该很难吧,就还不敢碰,所以想出过一个十分变态的方法:上FTP!注册时往一个文件写入密码,账号作为文件名,上传到FTP服务器,登录时就判断FTP服务器是否存在名为此账号的文件即得知是否已注册,已存在的话则下载文件并读取文件内密码比对。以现在角度回去看,我会当场敲死自己,安全性为0,可用性为0,我真有毒。
0x18 低代码来了?
那时有许多低代码或零代码建站平台开始如雨后春笋般涌现,其中我所了解到的就有凡科建站,其实就是提供许多现成模板可以实现整合加载,对于想快速建站但又没有Web基础的人也许勉强算是个好选择。低代码让我想起了失败的Dreamweaver,就是那个DW,生成的代码基本无法维护、代码提示能力一般、无法接触前端生态,还很笨重。
0x19 重装系统
作为一名程序员,应该要会重装系统吗?许多人认为不需要,但我觉得很有必要,重装过程中会让你对系统和硬件有更深入的了解。当时有位同学拿来一台很老旧的笔记本,让我救救它,不我没有任何经验,所以我答应他了,我真是个负责任的三好青年呢~,马上从MDSN下载了原版Windows7系统镜像iso,直接把镜像烧录在U盘上无法完成安装,也许是硬盘分区问题,所以下载了PE镜像烧录进U盘并放进了一个个ghost镜像,这回总算使用ghost直接完成系统重装了,几乎没有什么Windows系统是无法通过ghost还原到硬盘上的。
0x1A 51单片机
也许是受重装系统的影响,让我对硬件的兴趣更抬升的一个档次,斥巨资几十元从某宝购入一块STC 51开发板,跟着案例使用C语言编写基础的流水灯、数码管、矩阵按键、红外遥控等小功能,C语言的直接上手和之后学习的一点汇编给我最大的冲击是:性能优化很重要。
0x1B 越权漏洞
学校的网站有查询成绩系统,某天发现更改一些信息并提交表单即可下载到其它学生的成绩文档,实际上这个漏洞和上面介绍社团作品时前端部长所利用的漏洞是同一个,于是利用该漏洞也实现过一个网页,提供给别人查询自己的成绩。
0x1C Android开发初探
随着Android手机逐渐占领国产机的主流市场,相关的应用生态也发展了起来,Android开发进入了我的视野,当时Android版本还处于4.X 时代,Android Studio还没有被大部分开发者所接纳,许多人都还是采用比价原始的Eclipse + ADT插件这种方式搭建开发环境,我也照葫芦画瓢的整了这么一套,但我当时还不会科学上网,所以一直卡在下载SDK的相关组件上,后面通过修改hosts勉强解决,也遇到过ADT版本不兼容的问题,好在最后都解决了,就是这虚拟机吃内存就跟大胃王似的,搭好环境后就写了一个极丑的界面。这一波折腾让我认识了ADB调试桥的使用,这在以后也将发挥重要作用。
0x1D 揭开面纱
在之前刷机的过程中了解到了BusyBox,BusyBox集成了大量的常用Linux命令和工具,它就像一个工具箱,让你能够在手机上运行一些只有在Linux中才有的命令,不过大部分命令需要root权限才能够正常执行,Android底层其实就是裁剪和定制过的Linux系统,而BusyBox这些命令应该都是把工具源码编译成ARM平台可执行的文件再注入系统bin的,之后尝试下载了可以在ARM平台运行的jdk并配置环境变量,第一次成功在手机上完成了Java代码编译和执行。这次让我印象十分深刻,让我对源码、编译、目标平台有了全新的认识,也知道了移植是怎么实现的。
0x1E 人生第一个域名
之前编程社的官网都是挂在别人的三级域名上,为了后续发展决定在万网买下一个域名,当时万网还没有被并入阿里云,想着是在国内的网站,第一次买为了方便以后备案和含金量选了个cn作为顶域,域名叫做:aidoukj.cn,意思是AiDou科技,不过之后编程社改名后就不再续费,现在已经被释放掉了。
0x1F 正式建站
既然域名到位了,服务器当然不能再用免费空间,为了先不备案找到一家名叫恒创科技的主机商买了个香港的共享主机,共享主机和免费空间原理也差不多,都是从物理服务器上分割出多态虚拟主机,IP依然是共享的,不过配置相较免空有一些优势,也不怕跑路稳定些,主要对于资金紧缺的我来说270一年的服务器实在比较实惠。为什么不备案呢?当时国内像阿里云、腾讯云、华为云等等服务器商还没发展起来,备案是一件很费时间精力的事情,要寄东西要跑路,不像现在顶多服务器商给你寄个幕布自己拍张照片,APP里操作一波上传一些信息,服务器商帮你去处理备案,基本半个月后就通过了。这个主机自带PHP解释服务和MySQL数据库,我下载了WordPress源码并上传上去,这是当时最流行的博客平台,只需要进行一些基本配置,这个网站就可以运行了,支持许多插件和主题。接着给域名添加A记录把 www.aidoukj.cn 解析到服务器的IP地址上,由于这个服务器的带宽也是共享的比较有限,就把图片传到图床上了,至此完成基本的建站工作。
这一次经历让我认识到了PHP语言在快速建站上的闪光时刻,也对服务器有了更深的理解。
编程社官网建设好后,就在思考如何能够在百度能够搜索到这个网站,之后就了解到了爬虫和一些SEO知识并针对做了一些SEO优化,终于有一天,百度的爬虫爬进了这个网站爬了一遍,不得不吐槽百度爬虫永远比谷歌爬虫慢一步,不过没有白爬,过些天在百度搜索搜索AiDou科技真的出现了官网入口,那一瞬间成就感是爆棚的。
0x20 神奇脑洞
那时候突然想做一个游戏,让玩家自己在电脑创建一个文件,然后使用这个文件的数据与其它文件数据战斗,根据某种文件特有属性来定义游戏对手属性,如果成功打败一个文件就获取到该文件的数据再作为自己的特性数据再销毁这个文件,这样就相当于复制了对手的属性,让自己的文件数据更完善,战斗力更强,甚至游戏对象的造型也可以根据文件的编码来做,将电脑分区作为整个游戏的世界,游戏剧情根据由所有文件个体数据随意构造,当然需要一个庞大数据库来定义某些数据能触发哪些剧情。所有都通过数据组合变异而来,如果自己被打败,就需要重新编写自己的特性数据来与其它数据战斗,感觉不错,既是游戏又是能销毁数据的病毒。
0x21 企业邮箱
刚好碰上腾讯企业邮箱的试用开放期,申请试用是免费的,这个邮箱至今还在使用:vinlic@vinlic.com,使用企业邮箱的一个原因是它能够绑定自己的域名,只需要绑定时在域名解析添加MX记录即可,这样就可以拥有一个独一无二后缀的邮箱地址,并且还能为别人开设同域名的邮箱,不过当时还在用 aidoukj.cn 这个域名,直到后面因社团改名才更改域名的。
0x22 班级管理系统
脑洞一开,想给班里搞个班级管理系统,把一些常用的功能放进去,刚好高中教室都是有多媒体教学的所有都有电脑,我用C# Winform做了个有统计班级财务状况、播放日常听力以及投票功能的小工具,为了实现这些第一次接触了数据库和文件IO,不过用的是Access数据库,这个数据库只能用于存储小体量的数据,但也足够使用了,成功消除了我对数据库的恐惧,文件IO主要是需要遍历文件夹以及读取文件播放。
0x23 冲数据库
在接触过Access数据库后让我放下了对数据库的恐惧,于是开始尝试学习微软家的SQL Server,在实际编写了一些增删改查的SQL语句后,突然发现,咦?数据库真的是完全没想象中那么恐怖嘛,写了个连接小Demo玩↓。
0x24 毕设外包
“有人会Winform吗?”,这是C#群里的一个群员询问的,我就和他私聊起来了,了解到他想要别人帮忙做毕设。正好我想要锻炼锻炼自己,竟然答应免费帮他做了,在之前这么长一段时间的锻炼下,已经具备了基础的查错能力以及优化意识,不再像之前写代码那样完全不考虑性能,花了三天时间给这位老哥做好了基本的功能,为了方便他演示,决定使用Access这种可以离线访问的数据库来存储图书数据。这个项目搞完后有种头上飘Level UP的感觉。
0x25 入群狂魔
在编程学习渐入佳境时,我渴望接触更多的大牛、接触更多的新知识,但又懒得看书看视频于是开始了疯狂加群模式,把各类编程语言以及嵌入式等等相关的QQ群都申请了一遍,比如PHP、C#、Java、前端、嵌入式、Android、数据库、SEO,那个聊天列表得拉个十秒左右才能见底。进群后还统一使用了一个神奇的身份:性别改为女并化名卢雪霑,群里昵称就叫:富贵险中求,大家都叫我:富贵,这么做是觉得大佬们更愿意为女生解答技术问题,在此我要向当时为我提供帮助的大佬们道歉,希望你们能原谅我的这种行为,有机会我会去找你们请客赔罪。进群后看着大佬给萌新们耐心的解答问题,我有问问题也给别人解答问题,这一来二去的,算是对能力的一次综合提升,随着和大家逐渐熟络,还在一些群里混上管理员,看着这么多不同技术,逐渐明白,技术都是融会贯通的,没有最好也没有最坏,所以当有人争“某某语言/技术才是最好”时,我不会去争论,在技术领域里都是工具,只有适合和不适合之分,选择什么技术应当由需求决定,而不是以主观定论。
0x26 Github
作为全世界最大的同性交友源码托管平台,自然是每个程序员必去的圣地,但是国内的高墙经常导致网站时常无法访问,对于国内的刚入门的程序员来说是一件相当难受的事情,这其中就包括我,没能用上梯子就临时通过修改系统hosts的方式勉强访问到了,国内后期虽然也涌现除了一批如gitee这类较好的代码托管平台,但开源生态这环实在过于薄弱,很容易被当做单纯存放源码的工具,开源还未成功,同志仍需努力。
0x27 工控主板
在一个我经常活跃的技术群里,有位朋友给我送了一套工控主板,很感谢它,让我能够直接摸到电脑的主板,最开始时我以为只是普通的电脑主板,直到看到这个供电接口才知道不一般,不过并没有配硬盘和内存条,我就上闲鱼捡了块笔记本硬盘和内存条回来,在教室开上投影仪给装上了Ubuntu系统,这让我进一步理解了计算机的组成。
0x28 买书狂魔
有那么一段时间里我开始了奇怪的买书欲,在当当和京东买些书回来,不过我承认我基本没把任何一本书完整的看完,因为我觉得精髓就是你需要的时候它里面刚好有,其中有几本明显的智商税书,比较有帮助的大概是C#开发实战和犀牛书,还顺带学过一段时间的Python。
0x29 贪吃蛇
我的数学逻辑从小到大一如既往的差,甚至最低时还考过8分,数学老师恨不得一巴掌把我扇在墙上,就算随便选对几道选择题也不至如此,我害怕以后深入复杂的算法逻辑会把我绕晕,先用JavaScript写了个贪吃蛇验证一下我是不是脑子有点大病。
0x2A NAITA联盟
在编程社之后我在思考能不能创建一个组织,集结国内各个高中的编程、计算机社团一起,形成一个联盟,实现资源共享、统一决策,一起研究如何提高高中生的编程能力以及计算机基础知识水平,也可以一起编制教材、做项目、探讨问题。现在看来这种想法也太中二了吧!甚至还做过一些实际行动,连域名都买好了,logo也由其中一个编程社社长设计好了,联盟名字就叫NAITA,域名叫naita.org,不过后期没有续费应该已经被释放了。
0x2B 树莓派
在和往常一样在网上找一些新奇的玩意时我看到了名为树莓派的开发板,觉得很神奇,体型只有银行卡大小,却五脏俱全像一台电脑,CPU、GPU、内存、网卡以及各种各样的接口一应俱全,当时树莓派才出到2B版本,现在已经出到4B了,而且树莓派相对于其它标称性能更强的开发板生态要更好,树莓派基金会号称所有树莓派版本的硬件都是定价35美元(当时折算人民币约238元),还算是一个比较亲民的价格,就是不知道如今是否更贵了。树莓派采用TF卡作为硬盘,官方提供了基于Debian定制的Raspbian系统镜像供你烧录到TF卡,插上卡后,它就是一台ARM平台的Linux主机。当然,不可能拿它跟我们的手机或电脑的性能相比较,因为它的工作场景和它们完全不同,它可以用于各种嵌入式开发中,也可以作为上位机控制下位机,机身上丰富的接口也为它的扩展性提供了更多的可能,甚至可以将它作为Web服务器使用,自己玩的话基本性能是够的,配合上路由器的端口转发,可以将内网的树莓派端口转发到公网,这样就可以在外面访问他啦。
0x2C 第一个教程
在当时关于树莓派的教程实在有点稀缺,我就用糟糕的描述写了一篇关于通过手机OTG连接树莓派的教程,主要是方便在外面或者不具备内网条件的人可以通过一条数据线连接树莓派,我就是这类人,通过USB共享网络给树莓派,这样就可以和它处于同一个网络了。
教程链接:http://tieba.baidu.com/p/4064959646
0x2D 内网映射
某天放假回到家时想拿树莓派作为服务器搭建一个WordPress博客网站,这也是我第一次正式在Linux搭建PHP运行环境,在此之前,在Windows上一直在用PHPStudy,我在树莓派上搭建了一个LAMP(Linux+Apache+MySQL+PHP)环境,Apache在树莓派上运行属实有点太重了,后面换成了Nginx,当时我还不懂得如何在Linux上编译源码,所以搭建环境主要还是靠apt-get命令来安装相应的包。一整套环境折腾起来后开始运行,但是问题来了,怎么让别人访问到我家内网的服务器呢?尝试过使用端口转发,但是运营商似乎封掉了民用的80端口,为了网站能够正常通过80端口访问,我找到了Ngrox这个代理隧道,换做现在的话我可能就直接写个隧道服务到自己的服务器来实现了,但是当时水平是在有限。
了解路由器的小伙伴们应该都知道路由器通常都具有端口转发功能,内网映射和它有些类似,端口转发是将内网的某个端口转发到公网的某个端口,是一个挺Nice的功能,不过既然把端口暴露在公网自然会存在一些安全问题,所以现在民用网很多端口都被禁用掉了,比如80、21这类常用服务端口早就禁得差不多了。回到正题,内网映射不一样的是,它是内网机器主动与服务器创建一条代理隧道,服务器方为你提供域名,通过域名即可通过他们的服务器访问到你的内网机器,这个和我后面说到的SSH隧道原理很接近。
0x2E 禁止套娃
自从把手机从ROOT过之后,就对机子进行了一系列的折腾,就想到能不能在Android上也运行adb工具通过OTG功能去操控其它Android机?手机上是ARM平台,上github一找还真有编译好的ARM平台adb工具包,下载下来后跟同学借了个手机过来,开启调试模式,用转接头和数据线将两台机器连接起来,成功通过adb devices找到它的设备,adb shell也能够正常执行命令,执行reboot对方手机就重启了,这波经历,已经让我彻底认识到世界上所有设备其实都是一样的,不论电脑、手机、微控制器,都是一家人,不一样的只是CPU架构、算力资源和外设接口。
0x2F 安卓手机助手
在进一步深入学习C# Winform后,想着Windows窗体程序+Android会碰出什么样的火花呢?是不是可以借助Winform+ADB做一个安卓手机助手?当时觉得把手机通过数据线插入电脑挂载进行文件操作不太方便,于是开发了一个用于Android手机的文件管理工具,不同类型的文件拥有独立的图标,并且能够预览文件内容。
0x30 Python单片机
一位在嵌入式群的朋友给我寄来了一片可以运行Python的单片机,第一次颠覆了我对单片机开发的看法,原来不是底层语言也能够在单片机执行,这个单片机支持挂载内置Flash的文件系统,可以直接把Python文件放入里面用于执行,不过执行效率和资源占用肯定是没法和C/C++比肩的,如果作为小玩具来用还是非常实用的。
0x31 资金支持
在编程社的发展路途上也有一些支持者提供了很多的帮助,其中也有一些资金支持用于服务器的运转,很感谢各位的资助,虽然最后编程社没能坚持下去,辜负了大家的期望。
0x32 CodeIgniter
编程社的官网一直是运行于WordPress的,由于这套博客平台实在过于庞大,导致响应速度经常不理想,在结识另一个编程社的社长后他向我推荐了CodeIgniter框架,这是一个轻量优雅的MVC模式PHP框架,这个框架的源码给了我后续的各种开发都带来了灵感启发,使用它重建了官网并做了后台系统,不得不说MVC在前后端还未彻底分离的时代真是个伟大的设计。
0x33 流浪社团
编程社在学校内的活动开始被校方阻止,尽管已经多次前往校长室沟通,但均未得到正面的答复。最终决定不在校园里运营社团了,改为在校外的流浪模式,干脆吸收当地各个学校的中学生作为社员,入社依然是完全免费,社团的运营资金就全靠热心支持者的捐款和我自费了,很感谢当年捐款支持我们的人,虽然最后没能运营下去,但是我会把社团的精神继续传下去。既然出校园,干脆不破不立,聚集了主要成员在一家冷饮店商讨新的社团名称,每头脑风暴出一个名称我就马上在万网查一下这个名字的.com域名是否被占用,经过半小时后我们终于试出了Vinlic这个名称,域名注册为vinlic.com,这个名字的含义是未来客。这个名字是我现在常用的昵称,然后还制作了一些卡片发放出去,它曾经代表着一群追寻梦想的人,最后只有我留了下来,不过我近期已经成功联系上了几位前成员,希望有一天能够再聚一起共谋大业。
0x34 MobaXterm
使用Linux系统自然避免不了使用SSH,所以一直在寻找一款好用的SSH客户端,最开始时接触到的是Putty和XShell,直到我找到了一款名为MobaXterm的神器,在大致摸索了以下功能后,发现在功能整合、命令行显示兼容上等各方面都直接秒杀其它工具,比如它支持侧边栏连接SFTP进行文件管理,于是决定将它作为主要的SSH客户端。
0x35 花生棒
在之前使用Ngrok进行内网穿透时就关注到了花生壳Oray出的花生棒,据描述是能够实现内网穿透,出于好奇在他们官网下单买了回来,实测后发现虽然能够实现内网穿透,但只能使用固定的域名和端口号,如果想更换端口号还需要购买,每个月的流量也是有限额的,体验比较差。
0x36 纸板VR眼镜
Google开源了一个名为Cardboard的硬纸板虚拟现实眼镜,几片硬纸板、一根橡皮筋、两片透镜、两片魔术贴、两块磁铁,再配合手机通过极低的成本就可以让我们拼装体验一个丐版VR眼镜,没见识过VR的我就买了一款纸板眼镜来体验体验,实测戴上耳机玩手机上的VR游戏和视频效果还算不错,至于沉浸感当然是没法和专业的VR套装相比较。
0x37 开发论坛
在被CodeIgniter框架的思想开过光后,想要自己使用PHP开发一个MVC模式框架,花了一周大概入门了PHP,发现PHP其实就是函数多,入门的门槛是比较低的,说干就干,在看了几遍CodeIgniter和WordPress的部分源码后就开工了,当时能力有限,仅实现了Controller与View并没有写Model,不过总体思想还是没有变,照着撸出了一个简易的论坛系统:Vbbs,于此同时顺便学了当时比较火的Bootstrap(一个样式库)和Jquery,很快我就发现整个设计十分的不成熟,而且对安全性考虑不足,比如没有对提交内容进行xss过滤。
0x38 双系统
随着我对Linux的入门,开始希望在真机上安装一个Ubuntu系统试试,毕竟虚拟机对于只有2GB内存的笔记本来说还是有些吃力的,但又不希望直接卸掉笔记本上的Windows7,稍微了解了一下后准备安装双系统,由Grub做启动引导。先在Windows的磁盘管理工具中为Ubuntu腾出一块容量为80GB的无分区空闲空间,接着把Ubuntu镜像写入U盘,插入U盘电脑引导进入Ubuntu的系统安装程序,这在上面对空闲的空间进行手动分区后开始了安装流程,完成后重启进入了Grub,这样就可以选择进入Ubuntu或者Windows7了,在后续使用Ubuntu的过程中学习了一些常用命令以及如何编译源代码安装程序。
0x39 FREESCALE
依然是嵌入式群里一位好友送给我了一款开发板,这块开发板是飞思卡尔的MKE02Z64VQH4,第一次见到包装这么精致的开发板,实际上机开发测试了一下,感觉一时半会驾驭不住就先放着了。
0x3A 阿里云ECS
国内在很长一段时间里,都没有面向个人比较大型的云服务器的服务商出现,直到阿里云、腾讯云出现,终于填补了这个空白,让个人主体都可以很方便的租用服务器,而且价格并不算很高,腾讯云还提供过一段时间的试用名额,抢过一台腾讯云的服务器用了一段时间。当时阿里云已经支持自己拍幕布照片+APP的方式进行备案材料提交,所以买了阿里云的服务器,这次直接选择了CentOS镜像作为服务器的系统,并没有选择Windows Server,一个是同价位下配置比较低,而且相对Linux来说更加耗费资源。在上面搭建了一个LNMP(Linux+Nginx+MySQL+PHP)服务用来继续学习开发PHP。
0x3B 迟来的开悟
临近高三年级毕业,我一个人坐在操场的台阶上,看着学长学姐们在度过学校的最后时光,不知道哪来的一激灵,突然想明白了,也许我不应该再对应试教育开炮。大学会给我成长的机会,会给我更高的起飞点,可惜一切已经晚了,因为我也即将面临高考,以前的从初中到现在的知识链条早就七分八裂、残缺不全,临时抱佛脚并不现实,本届高考也将面临改革为全国卷,难度也将上一个档次。
0x3C 4KB程序
这是一个参加97年世界编程大赛并获得第一名获得者的作品,使用机器码实现,生成的可运行程序仅有4KB大小,所有的3D迷宫画面都是采用实时渲染,全程时长2分钟,还包含了配音,这给我带来了不少的震撼。
0x3D 开发魔塔 ★
简介
先放上成品链接:https://blog.vinlic.com/mota
开发流程的记录贴:https://tieba.baidu.com/p/4397526540
魔塔吧发布贴:https://tieba.baidu.com/p/4545234500
两位神触的攻略贴:https://tieba.baidu.com/p/4553189514
码云仓库地址:https://gitee.com/Vinlic/Mota
我是一个并不善于玩游戏的人,周边同龄人在玩的游戏,我基本都不玩,我喜欢的也仅仅是策略类游戏,而魔塔如之前我说描述的,是我很喜欢的一类游戏,我玩的次数最多的还是24层魔塔,它的配乐也很吸引我。在之前学习JavaScript的过程中免不了学了HTML5相关的一些内容,刚好还了解一些canvas的使用API,在这样的契机下我觉得多年未完成的造塔梦想可以开工了,开发一个HTML5魔塔!在此之前国内还没有正式发布的HTML5魔塔,大部分都还是使用RPG Marker或者Flash制作的魔塔,我就来开了这个先河,让大家都可以无需下载即可在任何支持HTML5标准的浏览器运行魔塔。整个开发流程是比较坎坷的,也十分感谢百度魔塔吧几位元老和测试组的建议与支持,最终这个魔塔取名为:纪元魔塔前传。
开发工具
开发时最麻烦的其实还是开发工具的极度落后,作为一名临近高考的高中生,自然是不可能摸到电脑的,但是我有手机呀!于是我祭出我的伙伴:红米2A,这个机器我现在还保留着,在这个项目过后,它对我意义非凡,在手机上写代码,不管是开发还是测试都无疑是一件十分困难的事情,甚至由于没有开发地图生成工具连地图数据都是手动编的,为了实现这些,我给手机安装了DroidEdit、KSWEB、UC浏览器。
DroidEdit是一款当时在手机上表现很不错的代码编辑器,自带语法高亮等功能,不过由于这次单文件的代码量比较巨大,写到2000+行时语法高亮就变得十分卡顿,写起来很难受,迫不得已只好关闭高亮继续敲代码,所以基本是对着黄底黑字在写代码。
KSWEB是一款能够在手机上开启Web服务器的软件,它提供了Nginx引擎、PHP解释环境和MySQL,之前是通过玩PHP时认识了它,而现在我正需要它的Nginx引擎为我提供本地的Web服务,因为这个项目需要动态加载本地文件,只能采用localhost去访问避免跨域等问题。
UC浏览器是曾经手机端浏览器的王者,当时除了Chrome就它在手机端对HTML5的标准兼容最完全,它的功能比较多所以没有选择Chrome,用UC浏览器作为测试工具时就面临许多极为难受的事情,当时对于浏览器的缓存机制不熟悉,所以每次修改完代码返回浏览器测试时都会去清除一遍缓存再刷新,确保代码是最新的状态,整趟开发下来至少清除了几百次缓存,有一次还把UC清挂了,再起不能只好重装,并且由于是手机端的浏览器不会提供Console控制台,在没有log配合调试的情况下只能用alert替代,也是一顿难受。
还遇到一次文件丢失的问题,可能是写入时出现了问题,还稍微重构了一下,好在坚持完成了这个游戏,可以说是一段很奇葩的历史了,用手机敲出一个小游戏,比较遗憾的是没有来得及制作战斗动画和配乐。
开发过程
具体的开发过程可以看上面简介中的开发流程记录贴。在开始开发前收集了一些现成的素材,这里要感谢魔塔吧吧友整理的素材包,里面的素材都是雪碧图模样的,这样可以提高加载的效率,对于浏览器来说更是能够减少并发的图片请求数,下面是一小部分素材的模样,绘制到画布时就需要截取其中一部分来绘制。
最开始的想法是使用三层canvas,背景层+前景层+主角层,但当时还没精力去实现单canvas的多图层绘制,所以强行拆出了六层画布作为六个图层,分别是状态栏层、背景层、事件层、前景层、界面层、数据层,是有点暴力的实现了。
第一个试作版本很快就出现了,十分的简单,就只是实现勇士走动和出现画面。
接着就实现了第二个的像素风的版本,但觉得没那味,后面又改了一个版本。
上面版本的都太丑逻辑太烂,进行了重构并且实现了在PC横屏、手机上竖屏的效果,于是就实现出了现在的终极版本。
到此为止,这持续3个月在手机上敲代码开发的魔塔小游戏终于完工了,我在高考的前一个晚上再魔塔吧和安卓魔塔吧发布了纪元魔塔前传,引起了一波小轰动,这意味着第一个正式发布的HTML5魔塔出现了。接着第二天就去参加高考了,其实结果已经很好预料了,高考成绩非常的惨,只有196分,瞎考可能都不止这个分数,不幸中的万幸是碰上第一志愿的3B大专刚好扩招,我碰巧就补录上了。
还在贴吧碰到过一个小奇葩事,他们所谓的“黑技术”也就是只需要下载前端源码即可,甚至源码我都没有混淆过。我尊重魔塔美术资源的原创版权不会用于盈利。
联系魔塔作者
在这之后还通过邮件联系了在日本的原始魔塔的开发作者,我向它们推荐了这款H5魔塔,他们也很友好的回复了我并把访问该魔塔的链接放入了他们自己的网站 http://wwajp.com 里,十分的感谢!
码云推荐
这个项目由于是放在码云Gitee上面开源的,后面被设为推荐项目,还被邀请去参加深圳源创会分享,让我有点受宠若惊,毕竟这个项目源码水平实在很差。
自动寻路
在纪元魔塔前传上线后一直在想着重构内核的事情,前传版本由于是少数能够在手机上游玩的魔塔游戏,部分体验者表示手机操控方向键有点难受,希望能够点击屏幕自动寻路,为此我潜心去研究了A*寻路算法,我在算法方面的功底其实是很差的,花了一天多的时间去理解和写代码验证,不过终于使用JavaScript实现了寻路算法,并且这次还加入了背景音乐以及增强了屏幕适配,但第三版内核因为时间关系并没有开发完成烂尾了。
源码传承
就在重构内核工作放下后不久,有一位名为小艾的C++开发者在QQ上联系我,希望我能够提供纪元魔塔的相关源码作为参考,他想要开发一款在HTML5上的魔塔样板,我将前传的源码和第三版内核未完成的源码都发给了他,他很快就二次开发出了新版本的魔塔,这在后来演变为了HTML5魔塔开发引擎,让普通人都可以轻松开发HTML5魔塔游戏。
源码样板仓库地址:https://github.com/ckcz123/mota-js
我很敬佩他,因为任何人几乎都可以通过浏览器直接获得游戏的源码,而他却大费周章的询问,并在他源码的作者栏加上我的名字,而且他与一众开发者们共同将HTML5魔塔发扬光大,建立了一个在线游玩HTML5魔塔的网站 h5mota.com ,这可以说是把魔塔游戏拉入了一个新时代。
他还在B站发布过HTML5魔塔样板的使用教程:https://www.bilibili.com/video/BV17W411m7ww
看到自己的源码有了这种形式的传承很感动也感到很荣幸,也算是第一次为开源出了一点力量。
除此之外也有些开发者Fork的源码改造成更优秀的作品:https://gitee.com/lp9906/ts-mota
0x3E 开发插件
在学会科学上网后,终于可以在Chrome在线安装一些插件了,,有些好奇这些插件是怎么开发出来的,在大概了解了一下之后明白所谓插件其实就是源代码加了配置文件的压缩包,于是拿出魔塔源码并配置了manifest.json后打包完成了小插件,在之后上大学时经常需要我们在线看视频和刷题,这对于学习效果其实是没有什么价值的还很浪费时间,所以也开发了一个刷视频和刷题的插件,代替本人去自动完成所有流程,虽然这些插件没有发布,只能本地加载文件夹,但几个人分享一下用是没问题的。
0x3F VCMINI脚手架
在准备正式跨入大学阶段之前,我产生了一个不太实际的想法:自己实现一个PHP脚手架,又是一次说干就干,大概花了三个星期的世界终于把这个“框架”完成了,现在看来这根本不能称为框架,它实在过于简陋,后面还花了一些时间整理出开发文档,算是一个黑历史吧,源码我也干脆放出来供大家嘲笑了:https://gitee.com/vblog/VCMINI
0x40 新毕设外包
在进大学前我提前潜入了这所学院的各种新生群,甚至还混上了管理员,并设置自己的群昵称叫:拿起我的40米大刀,简称大刀,所以我在这所学校的大部分时间里都被叫做大刀,有一天一个计算机应用专业的师兄找上了我,问能不能帮忙有偿用PHP实现一个论坛系统来完成他的毕业设计,我依然没有收费,摆着经验比钱重要的想法直接开干,反正上次不刚实现了一个“框架”么,直接拿来操练,花了大概三天左右的时间,这个论坛系统新鲜出炉了,包含了论坛用户端应该有的基本功能,后台倒是来不及做,不过已经达到标准了。
0x41 个人博客
一如既往,我不是一个喜欢看书和视频的人,但是对于搜索引擎倒是情有独钟,经常能在搜索结果看到各位大佬的个人博客,甚是羡慕。想着我自己也搞个博客玩玩吧,当时Hexo这类优秀的轻量级静态博客框架还未出现,又不想使用笨重的WordPress,索性继续拿之前的“框架”继续用吧,页面上用上了CSS3的媒体查询做好适配,经过两三周的努力后,终于把基于VCMINI的博客站撸好了,可以自适应PC和手机端。
0x42 图片自动压缩器
在写博客时发现收集大量图片时部分图片大小过大,但是图片在网页中经过缩放后并不需要过高的图片质量,因此将每张图片进行压缩是件比较麻烦的事情,当时还没用上OSS自动图片瘦身就用C# Winform写了个监听文件夹自动压缩图片并存储的工具,可以通过图片后缀或体积对文件进行过滤并进行有损或无损压缩,本质上是调用了jpegoptim。
0x43 科创工作室
我进入了大学,在军训开始之前有位15级师兄见我在群里经常科普一些编程知识就来问我要不要进入科创工作室,我一听那可来劲,工作室才刚成立不久,来得早不如来得巧,于是在经历惨烈的军训后我这个16级的新生就和15级的师兄们一起进入了工作室,能够在一个3B大专获得这样的机会是不容易的,这里的空间虽然比较大,但由于刚建立许多设备并不齐全,甚至网络都还是从楼下办公室通过窗台接网线拉上来的,不过后面加上了终于接入了学校网络并新增了交换机,座位方面也只有从指导老师那边搬来的6张办公桌,桌子面对面排成了两列,刚来时发现师兄们已经坐满了这些位置,而我就直接坐到了这两列的夹缝之间,在这个位置还能和师兄们高效的吹水,实乃风水宝地,有了工作室这样的环境和氛围,让我成长的更快了,这些师兄们都很棒,后续随着工作室成员的增加后续也安排上了统一的工位,我也荣幸的在工作室15级师兄换届时成为工作室的负责人,很感谢工作室的指导老师曾昭江老师,他为我们工作室成员做了很多事。在这里我仿佛看到了一个编程社团应当有的样子。
0x44 蓝桥杯
蓝桥杯是全国性的信息技术专业大赛,作为整个院校里比较具有竞争力的工作室成员们自然会被优先推荐去参加此类比赛给学校争点面子,我很早就有了解过这个比赛,参加以前更多的老印象是算法题为主,参加之后发现原来不全是算法题,也就是多练多刷题是可以获得比较好的结果的,就是考场提供的编译环境属实有点落伍。对算法的恐惧依然让我至今都不想再次参加此类非项目应用类的比赛。
0x45 打卡系统
科创工作室的人员并不是固定的,随着进入工作室的成员越来越多,为了能够了解大家的考勤情况,需要有一个打卡系统,于是我拿出自己的树莓派作为Web服务器并接入工作室内网,基于VCMINI搓出了一个打卡系统,这个系统只能在工作室的内网访问,并且账号与每个人的静态IP地址绑定,因此在不动用小聪明的情况下,是无法在人未到达工作室的时候完成打卡的,这个系统会记录每个人的在线时间,这在后面改为采用iBeacon基站签到让方案更加周密。
0x46 机械键盘
有很长的一段时间,机械键盘突然火了起来,敲打多年薄膜键盘的我正好也想换一把机械键盘试试,先仔细了解了各类关于键盘轴的评测,最后我选择了不会太吵但手感也不会太硬的的茶轴,很多人都表示茶轴用起来和薄膜键盘差不多,但我在实际体验久了之后发现区别还是很大的。购买的是Varmilo阿米洛va87m,这把键盘至今已经接近6年了,目前还在用,没有出啥问题,还是挺对得起六百多的价格的,刚到手时第一感觉就是很重,外壳是很厚实的金属材质,键帽是侧刻的PBT,后面实在用不习惯侧刻键帽还是买了一套正刻的键帽换上去了。在他之后也曾试过青轴的IKBC Poker2和NiZ的静电容的键盘,可是最后还是觉得茶轴最适合我的手。
0x47 Intel电脑棒
大概是看一些奇怪的评测视频发现了Intel的Win10电脑棒,脑子一热居然真的在某宝买了一支回来,CPU是凌动Z3735F,存储空间只有32GB,内存有2GB,体验上是非常的平庸,几乎只能用来应付Office全家桶或看看一些视频,拿来正式办公还是打消想法吧。
0x48 内存条
我在用的电脑一直都是高中时最开始摸的那台宏碁笔记本,它2GB的内存在奋斗多年后已经完全不够用了,内存经常都是100%占用,整机性能被配置的水桶效应拖慢,虽然内存不够可以拿硬盘空间作为虚拟内存来凑,但硬盘的读写速度相比内存简直惨不忍睹,作为最短的这块木板,自然是需要被优先处理的,幸好这笔记本还留了一个内存插槽,直接在某宝买了条同品牌的4GB内存条,拔掉电池然后插进内存槽,开机后内存就是6GB了,这是第一次升级内存的经历,内存升级后在体验上获得非常大的提升,电脑上的i3-2312M处理器仿佛还在说爷可以再战十年。
0x49 游戏本
虽然之前为老笔记本升级了内存,但为了能够更畅快的编码体验,家人打算斥巨资给我换台电脑,这次我进了“革命军”,机械革命x6ti,这是我比较后悔的选择,虽然配置方面性价比是比较高的,处理器i7-7700HQ、显卡GTX1050显存4GB、DDR4-2133运行内存8GB,磁盘是128GB固态+1TB机械,但是重量和续航方面离谱得惨不忍睹,重量是我原本笔记本的2倍还多,续航也只能坚持1个多小时,再往后查询该机器甚至已经停止销售,官方还透露此款机器电源设计存在问题,这让我对游戏本失去了信心,发誓以后绝对不买游戏本。
0x4A 锐捷交换机
工作室在运行很久之后才终于有人过来把网络正式接入学校内网,然后给机柜放了两台锐捷交换机,我给每条线的机位进行了标记和接入,看到交换机上有个Console口,很好奇,但当时对交换机并不是很了解,尝试过拿普通网线接Console口和电脑并不能通信,经过一番探索后才发现需要用专门的Console调试线,在某宝上购买后拿回来一顿折腾,大概了解了一些关于锐捷交换机的配置并且尝试了以下,可惜这个交换机似乎并非网管型交换机,无法实现太多的功能,这段经历让我对交换机有了更深入的理解。
0x4B 微信小程序
微信在17年1月9号正式发布了微信小程序,距此不到一周时间就有人在QQ里找到我,是一家老家本地的公司老板,直接问我能不能做微信小程序?在这之前我没看好小程序的发展前景,认为它不可能替代APP,直到后面才想明白,小程序的出现本来就不是为了代替APP。这个老板像做一款点餐平台小程序,不是专门为某个商户定制的点餐程序而是所有商户都可以加入平台,像美团那样,当时的美团在四线城市还未铺开。这个公司很小,没有任何技术人员,我答应了他,放长假时回老家时就到公司办公,平时就线上兼职办公,任职开发工程师,薪资方面全职4k兼职2k,其实当时就基本是抱着积累经验的想法去的,所以对薪资没啥要求。老板给这个小程序命名为:粿团点餐,为了开发这个小程序花费了大量的时间去跳各种奇奇怪怪的坑,如果说现在微信小程序的坑是一座大山那当时就是整座太阳系。后端方面我也花了大量时间精力去研究,并且从PHP+MySQL的组合逐渐转向尝试Node.js+Redis+MongoDB的组合,因为发现PHP的单线程阻塞在处理实时通信上有点捉急,比如WebSocket,虽然可以使用swoole框架,但我也想尝试一下更新的东西。这是我从以前到当前为止能力全面提升最快的一次,基于koa2框架实现了API服务,在实践中不断的改进代码,对缓存层的重要性也有了深刻的认识,接触了更多类型的数据库,尝试了接口压测,了解了许多语言特性,在Node.js上也用上了ES7的部分语法,当时的Promise还不是原生的需要通过Q模块实现的、还有研究过Electron、系统驱动等等。微信小程序这边的库和界面就全部由自己设计和编写了,这个界面确实丑爆了,在审核上线方面也有面临着巨大麻烦,由于涉及餐饮服务,审核是对经营范围有要求且是需要许可证的,所以给小程序做了和隐藏后门,审核时给审核人员看的就是个菜单,上线后其实就是具有点餐功能的,这种方式前期还是挺奏效的,越往后微信团队的审核就越来越严格了。不过最后项目是失败的,很明显,我和老板都犯了几个严重错误,首先不应该把一个小程序做得跟APP那样功能齐全、也不应该选择一个过于难以记忆的名称:粿团点餐、甚至没有好好规划开发计划,全程都是我或者他想到什么就做什么,也没有进行足够的市场调查、最核心的还是资金不足,老板做这个的资金只有20万。虽然抢占了小程序市场先机,但各方面的资源、战略、计划、技术、人员全部条件都不成熟,直接导致这个项目崩掉。之后老板还想换个方向做,可惜资金已经花完,我做到后面也有气无力的撑了两个月,不想再做了。虽然最终结果是失败的,但不失为一次里程碑式的经历。
0x4C 微信支付
在上面提到公司就职的时候,因为涉及在线点餐支付,就第一次接触了微信支付的API,这也是第一次面对各种数据签名、加密解密的场景,这让我在数据安全方面有了不错的成长,对以后尝试的各种安全加密有很大的帮助,老板还在客服那了解到服务商主体的话可以有更低的手续费,而服务商和普通商户的API又是不一样的,这一波折腾过后算是锻炼了一把看文档的能力,最后成功在小程序接入了微信支付。
0x4D Electron
依然是在以上这家公司的经历,老板希望不仅实现用户和商家端的微信小程序,还想要有PC端的商家系统,原本是想吃老本用C# Winform开发,但在发现Node.js无限的潜力后我决定使用Electron实现这个桌面程序,Node.js的实现能力当时就可以涵盖到前端、后端、桌面应用、安卓应用、iOS应用、嵌入式应用,而Electron就是Node.js在桌面应用方面的应用典型,它的成功典型案例就是大名鼎鼎的Electron,不过在开发过程中也会面临各种坑,比如打包大小过大,因为它是运行在Chrome的V8内核的,所以会依赖浏览器导致打包时会把内核也打包进去,后面通过裁剪解决了。但是最印象深刻的还是一个硬件相关的需求,老板希望这个程序能够控制接入电脑的小票打印机打印点餐单或结账单,如果是C# Winform我肯定能够实现,毕竟存在API可以直接调用,但Electron可不一样,为了实现这个需求,在github各种查找之下,终于通过安装zadig这个通用的USB驱动实现Electron调用小票打印机打印内容了,可是内容却是乱码,但以往N次的调试经验,马上意识到是字符编码问题,在改为兼容的GBK编码后就打印出了正常字符了。
0x4E iBeacon
在看微信小程序文档时偶然发现有iBeacon信标相关API,这促使我去了解它,发现它通过蓝牙BLE实现信号发射和定位,它可以广播自己的蓝牙ID,设备可以感知iBeacon基站与自己的距离,多个基站还能实现设备位置定位,那样就可以有很多应用场景了,比如活动出席手机签到,能够提供场馆导游、室内定位等功能。
0x4F Markdown
在上家公司任职时由于需要写接口文档,在挑选了一些文档工具后,最后决定使用Markdown来写,事实证明它确实很适合编写文档,可以通过特定的符号组合解析出不同的效果,还可以内嵌HTML、图片、表格、列表等等,十分方便,而编辑Markdown的编辑器使用过马克飞象和MarkdownPad2。包括这个博客的所有文章都是使用Markdown编写的。
0x50 Nginx
在尝试过众多Web引擎之后,发现Nginx是非常能打的,特别是在静态文件请求处理、请求代理等方面性能都很出色,在之前Node.js写的API服务上就成功使用Nginx代理了SSL实现HTTPS,还可以实现负载均衡减轻单机压力、分离Vhost,甚至还能通过插件实现许多神奇的功能,比如还能够通过插件对直播流进行hls分片,实现能够在网页上访问m3u8索引播放直播内容,几乎没有什么流量是它无法作为中间层处理的,Nginx从某种程度上就像一把瑞士军刀。
0x51 电台故事
我曾经很喜欢听网易云上的一个电台节目,节目名称为:伦敦华语电台,还有真名称是叫:鱼乐七天,节目主播是一位非常乐观向上的小姐姐,她叫子涵,听众们称之为“子涵姐姐”,在英国伦敦工作,拥有着十分甜美的声线,以搞笑幽默的风格主持节目,经常谈各种人生哲理和话题吐槽也会分享一些在伦敦的生活状况,三观也是非常的正,因此得到了大批听众的喜爱,她创建的后宫群已经能够排到3号群了,可见粉丝量并不少,我向她提出帮他无偿开发一款鱼乐七天的微信小程序,这样大家就能在微信上直接听她的节目了,然后我就去创建了一个个人主体的小程序,命名为“鱼乐七天lite”,当时没有了解清楚电台类小程序只需要视听许可证才能过审的就直接开发了,整合了子涵的所有线上节目和平时在群里发的经典语音,后端API服务继续用Node.js开发,大概花了一星期左右成品就出来了,审核时自然是直接被打了回来,只能发了个体验版给子涵看看,虽然没能发布上线挺遗憾的,就当练手了吧。
在这不久后,偶然间看到一篇新闻,标题是:中国游客大巴冰岛车祸,大巴为避让前方车辆侧翻,一名中国公民死亡,新闻时间是2017年12月25日,后面得知此人就是子涵,她和妈妈坐在冰岛的大巴上,她没有系安全带,这是最致命的原因。我感觉整个心都震颤了,第一次发觉原来生死就是一瞬间的事,那天我感到心脏很痛,一晚上没能睡着。如今每一次打开她的电台鱼乐七天还是会忍不住流泪,这么一场意外事故带走了一位这么好的才女,实在是天妒英才,她还很年轻,甚至都还没有过男朋友,她的妈妈还曾经在节目里帮她打征婚广告,她的人生还没开始就结束了。网易官方在得知这件事后还在她的节目下和她的粉丝们一起主持发布了最后一期节目,这让我感受到网易也有温暖的一面,子涵在用她年轻的生命告诫大家,坐车一定要系好安全带!为了自己和家人、朋友请注意安全。
0x52 3D打印机
3D打印在刚普及的时候,是非常热门的词语,除了中高端的工业级3D打印机外,低端市场的家用级3D打印机也在逐渐增多,在众多打印机中就有一款创想三维出的入门级3D打印机:三角洲,买它是因为比较便宜,精度方面自然是不能奢求,不过还是忍痛花了八百大洋买下了,买的是线轨版,会比滑轮版高点精度。到货后马上就开始拆箱装机,光装机就花了一下午,零件太多了。
组装完成后研究了一波Crua,拿下载下来的模型在Curd切片后就开始打印了,开始时没有啥调平经验,精度可以说是十分的感人。
0x53 Server酱
谁不想拥有一个自动推送报警的功能呢,Server酱是一个实现公众号和开发者绑定,然后平台提供一个密钥,开发者就可以使用该密钥调用Server酱的发送接口,就可以把消息推送到开发者绑定的公众号了,在没有自己实现监控报警功能时,这个功能还是十分实用的,并且此功能是免费的,但如今公众号为了避免骚扰用户,对消息推送做了极大的限制,Server酱逐渐将服务转为在企业微信上的推送,感谢作者坚持用爱发电这么多年。
0x54 实现直播
当时前公司老板虽然没怎么联系了,但有一天它发来了个求助,他是在老家当地电视台工作的,电视台向他提了个需求,要求实现一个小程序用来播放电视直播,我询问了是否有推流机,他回答有的,在研究了一番过后,决定让电视台的推流机推送RTMP流到服务器的Nginx,再由服务器的FFmpeg从Nginx中拉流转码后再推流给Nginx HLS切片,HLS将流分解成ts片段并生成m3u8索引,将这一套流程帮他在服务器上实现后,终于可以在网页和小程序上播放电视台直播了,虽然存在一定的延迟。
在工作室的时,我使用端口扫描工具对网络进行了扫描,发现工作室的网络摄像头工作在554端口,查了一下发现是RTSP协议的默认端口,接着查了下此品牌摄像头连接地址的默认用户名和密码,并使用VLC这个万能的播放器打开这个流居然真的可以播放监控,这些网络摄像头的安全性属实堪忧,不过根据之前的经验,将RTSP流通过树莓派拉给FFmpeg解码然后推给Nginx,成功的在网页上播放了工作室的实时监控。
0x55 讲师
作为一个内向自卑的人,站在讲台上是一件相当困难的事情,更别说还要给大家讲明白一些概念和知识,但不知何来的勇气,我第一次真正的站在了讲台上给工作室成员们讲解git的入门与应用,在没有进入工作室前大家顶多就是单打独斗,很少有协作的时候,现在就不一样了,大家现在是一个团队,面对项目时将是多人的协作关系,而git作为代码的分布式版本控制系统,可以很好的解决多人参与的项目管理问题,可以说是每个程序员必备的技能。精心准备了PPT,为大家讲解git是什么样的工具以及各大git源码托管平台,并手把手的教学一波基本操作。意想不到的是,从来不教git工具的老师们,纷纷在这之后将git列入了教学与考试的范围。
0x56 DELL屏幕
笔记本的屏幕实在比较小,写代码时分割两框时就有点不够显示了,这回下重本买回来人生的第一个显示器:Dell SP2318H,虽然亮度、色域等表现并不好,分辨率是1080P,但是用来写代码还是足够的,比较钟意的一点是支持升降和旋转,重点是狗东上这个显示器活动价只要998,这个显示器至今还在用,只不过已经变成副屏了,显示器对于效率的提升是不言而喻的。
0x57 投票系统
学校举办了一次金点子大赛,每个参赛团队需要写出一项可行的idea去参加比赛,举办比赛的老师找到我表示需要一个扫码投票系统,于是临时花了40分钟用Node.js撸出了这个功能,由于是校内并没有做太多的防刷票机制,只通过限制IP地址和投票数量,学生可以通过扫描idea展示海报的二维码为它投票,最后尝试用Python统计了一下票数提供给了举办比赛的老师。
0x58 图片密码记事本
某天突发奇想,能不能做一个加密记事本的微信小程序,使用指纹来加密,可惜当时小程序对指纹API的兼容并不好,就先放弃了,改由使用图片的md5作为密码来加密记事本,没啥技术含量,也就是可以用一张照片将自己想存储的信息加密和解密,如果照片弄丢了,“钥匙”也就没了。
0x59 Chromebook
很早以前就听说过Chromebook的大名,令我好奇的是这么已达基于云的系统会有多6,仿佛这就是未来操作系统的发展方向,所有数据基于云进行同步,电脑上只提供运算资源。开始时在亚马逊看Chromebook价位在1-3K左右,想买但看到巨额的运费直接打消想法。之后在闲鱼上淘了个二手的惠普代工Chromebook14,卖家挺良心的,提醒我这个系统需要翻墙才能正常使用,想着当初虽然没有自建的科学上网,但借助其它工具实现还是可以用的,所以又脑子一热下单了,到手后登录上了自己的Google账号,看着它把我在Chrome上的各种插件和配置、记录全给同步了过来,玩着发现真的没科学上网几乎没法好好用,于是研究怎么给它装上Ubuntu,发现提供了crouton可以用来安装其它Linux系统,装上Ubuntu后用了一段时间,性能还不错,内存有4GB,续航倒是比较令我惊奇,一次充电可以用上六个小时。
后面玩腻了,想着干脆重装成Windows系统吧,但没想到这货有个硬件锁定,没法像其它电脑上直接进入PE安装系统,于是一顿搜索折腾,发现这个硬件锁定可以通过打开笔记本D面底盖把一颗螺丝去掉即可解锁,这是第一次敢拆这种轻薄笔记本的外壳,好在小心翼翼的一波折腾后成功的把螺丝去除,并且成功解锁进入U盘的PE安装了Windows10,性能在ChromeOS还绰绰有余的配置,在Windows上就十分的吃力了,只能完成一些基础的任务,并且只有32GB的SSD更是被系统吃了大半,续航也大大折扣。
0x5A SSH隧道
SSH是每个接触Linux的同学必学的命令之一,在研究这个命令时发现它竟然能够搭建正向或反向的TCP隧道,那就意味着能够直接与服务器建立一条安全隧道直接通信,就像VPN那样,于是神奇的应用就出现了,假设我希望在我的电脑上连接服务器的MySQL,按理说为了安全是不允许将数据库端口暴露在公网的,也就意味着常规方法是无法连接了,那如何相对安全的建立连接呢?这时SSH的正向隧道就发挥作用了,我们可以通过 ssh -fNL 3306:localhost:3306 user@ip
这样一条命令将服务器的MySQL端口安全的代理到本地的3306端口,这样就可以在自己电脑上直接连接本地3306端口实现连接到服务器的MySQL数据库了,本地的端口也可以是其它端口号。
既然有正向自然也有反向隧道,它比较神奇的地方是:能够实现内网穿透。就像之前介绍的Ngrok那样,我能够把自己电脑的某个端口代理到服务器或其它机器的某个端口上,这样在服务器或其它机器上就可以通过它们本地的端口直接访问到我电脑上的端口了,这就让事情变得有趣起来,假设我想在公司访问自己家里电脑的文件,只需要保持一条从自家电脑到公司电脑的反向隧道即可。
不过不管是正向还是反向我认为都是有一定安全风险的,毕竟都是在防火墙打个洞出去,但这个风险可以通过不使用常用端口号等降低,在实用和风险之间考量下,我觉得SSH隧道还是很有用的。
在工作室里放了一台我的电脑,当时还没有了解到TeamViewer,国内的向日葵也是后面才出的,所以如何在外网访问到工作室的电脑就成问题了,想到SSH隧道可以解决这个问题,使用反向隧道命令: ssh -fNR 3389:localhost:3389 user@ip
,将笔记本的3389端口代理到服务器的3389端口,这个端口的Windows远程桌面的默认端口,服务器再将3389端口暴露在外网,然后就可以随时随地通过外网连接我的内网电脑了,不过传输速度就受服务器带宽影响了,并且实现这个得有一台公网服务器。
0x5B 跨年代码
眨眼间就到了元旦,彼时作为工作室的室长还是得搞点内部小活动的,就给大伙宣布了跨年代码活动,主要目标就是自己编写代码实现任意和跨年有关的功能,很快大家就纷纷完成了作品提交了上来:
虽然代码都很简易,但起码证明各位都精通输出Hello World。
0x5C 洗脑
在之前的练胆后莫名有了站上台面的勇气,这一次,我站上的是一个可以容纳两百人的大教室,作为已经上大二的师兄,趁着大一学弟学妹刚刚接触这个专业的契机,赶紧洗脑,通过一连串只有四个字和一段话的PPT,引导他们如何走入编程这个深坑,如何少走一些弯路,希望对他们能有一些帮助。
在正式上台的前天晚上,熬夜花了三、四个小时实现了一个纯静态的资源站,文件就挂在对象存储和CDN上,同时还写了一篇一万字的问题解答文档,当做送给他们的小礼物。
0x5D ITX主机
游戏本的电池续航能力实在有限,就干脆把它放在工作室里当不移动的主机使用,平常上课有电脑就直接从内网远程桌面连接过去没电脑就带上Chromebook通过服务器隧道连接过去。
某天突然想着组台台式机试试,正好手上存了一点钱,但已临近毕业如果还组一台常规尺寸的主机到时不好搬运,所以打算组一台ITX主机这样用一个泡沫箱就可以直接放行李箱上带走,这是我第一次真正组一台主机,由于是小型机箱,因此对散热、电源模组化、布线等等都有了更高的要求,稍微研究后才开始在狗东选配硬件,资金有限决定不配显卡,选择了带有核显的R5 2400GCPU+主板套装,这颗处理器的核显比较强劲,双通道内存的核显性能已经可以追上入门级的GT1030,内存条受资金所限买了两条4GB组双通道杂牌(实际体验是千万不要买杂牌,偶尔遭遇显示输出绿屏,开始怀疑是核显品控问题之后才确定是内存问题),硬盘就出血点买了256G的M.2 NVMe协议SSD再加上一块希捷酷鱼1TB硬盘(这块硬盘说实话震动有点大,容易和机箱发生共振),电源考虑到小机箱难理线的问题就选了长城全模组的550W电源,散热想着盒装CPU有自带也省笔钱,机箱就选了酷冷至尊的ITX小魔方,总体装下来价格大概在3800左右,没有碰上降价节日配件价格还是略贵的,组好后就放在工作室使用,这台主机最后陪伴我走了1年多。
0x5E “黑”
2018年6月20日下午,经过5个小时的苦苦挣扎,在围观者的尖叫声(还有欢呼声)中,消防人员劝导无效后,年仅19岁的女孩李奕奕从公寓楼跳下,自杀身亡。在此前,李奕奕在庆阳六中内多次受到班主任吴永厚的性骚扰且学校毫无无所作为后,她被诊断为创伤后应激障碍,对于吴永厚的疑似性侵猥亵,庆阳市西峰区人民检察院给出了《不起诉决定书》的判决,面对质问时,罗永厚说:“我是在帮她量体温。”。
这个事件令我和广大网友非常震惊和气愤,在继续深入了解这个事件时,我偶然进入了庆阳六中的官网,发现右上角有一个管理登录入口,尝试了以下后发现存在弱口令漏洞,接着进入了此cms的后台系统,把主页“稍微”更改了一下,希望能够帮助舆论出一份力让这件事尽快得到解决。
0x5F 工作室网站
已经记不起是第几次建站了,这次为科创工作室买了一个域名:cx-tidc.com,在之前普及Git知识之后,大家都统一使用Git仓库来保管工作室的代码了,官网也是工作室项目中的其中一个,基于Vue.js由几位成员合力完善并部署上线,很快也获得搜索引擎的收录。不过这个域名后续也因续费问题没能继续续下去。
0x60 混合加密与防伪造重放
加密与防重放作为请求安全性的重要环节是必须要了解的,在此之前已经有接触过AES加密,这是一种对称加密算法,加密与解密将使用同一个密钥,如果密钥泄露那数据就裸奔了,后面才了解到非对称加密的RSA算法,加密使用公钥,解密使用私钥,而私钥还可以用于签名,公钥用于验证签名,看上去RSA比AES拥有了更高的安全性,它可以确保A传递给B的消息不会被它人解开,哪怕是获得了A的公钥也不行,而B可以在回复A的消息上签名,如果中途有人篡改消息,那到达A手上时公钥将验签失败拒绝处理该消息,既有了保密性又能防篡改,但RSA算法的缺点也很明显,它加解密数据的速度比较慢,在面临大数据量处理时就很吃力了,但刚刚提到的AES算法的加解密速度相对来说就很快,那我们完全可以将RSA和AES的优缺点进行互补,传输数据前先生成一对RSA密钥对,公钥放置于你这,私钥放置于对方那,接着生成一个AES密钥,使用该密钥对数据进行AES加密,然后在用公钥加密AES密钥,再将AES加密过的数据和公钥加密过的AES密钥一起传输给对方,对方使用私钥解密出AES密钥,再使用AES密钥解密AES加密过的数据得到原数据,这样就完成了一次既安全又快速的数据混合加解密。
而在实际使用中我们还会面临一个新状况,如果在所描述的传输过程中有人截获数据包,虽然数据是加密过的,但它不篡改也不想获知内容而是将这个数据包给对方多发了几份,对方接收后也照常解密处理,假设这次传输是向某门锁发起一次开门请求,那对方是否可以在截获数据包的情况下趁夜深人静的时候,将这个数据包重新发送,门就这样开了,显然我们还缺失了防重放这一环,回到混合加密之前,我们应该给这个数据留下点“标记”,就像拍照片时给照片右下角加上时间一样,我们需要对方明白本次发送的数据是什么时候发的?是否已发过一次?Unix时间戳所代表的是1970年1月1日至今所经过的秒数,通过时间戳我们可以让对方明白这条数据是什么时候发出去的,如果当前时间戳减去数据时间戳大于了某个阈值(如60秒)就判定为过期数据应当抛弃,另外还应该生成一串简短的随机字符串用于标记该数据的唯一ID,接收方在数据过期前的阈值内应当保留数据的唯一ID,比如60秒内发来了多条同样ID的数据则除第一条外其余的均抛弃,60秒后由于过期抛弃机制也就没必要存储唯一ID了。
其实这里的防重放仅适用于加密的情况,如果在无加密的情况下防重放应当还需要另外实现防篡改,这种手段就是签名,这一般仅限于服务器与服务器间的通信,由于服务器存储密钥的安全性较高,A服务器与B服务器中存储有相同的密钥,那么就可以用这样的流程实现防篡改:A服务器首先将数据附加上时间戳与随机值的标记,然后将密钥拼接入其中,再使用MD5或SHA1等哈希算法获得签名值,再将数据+标记+签名一起传输,B服务器接收后需要用同样的方法用同一把密钥拼入数据计算一遍签名值,并将签名值与传输过来的签名值比对是否一致,不一致则代表被篡改拒绝处理。
0x61 Pages服务
github上的仓库有一项服务是Pages,它可以用于将仓库的内容作为Web站点进行部署并绑定在域名上,码云之后也开放了此项服务,不过如今在码云上使用Pages服务是需要实名认证的,毕竟是在国内,该服务除了提供一个属于你的三级域名还支持绑定自己的域名并且帮助你申请SSL证书用于HTTPS访问,有大量的博客是通过Pages服务对外开放的,比如以github.io为后缀的域名均在此列。之前你所阅读的这个博客也是放在此项服务上面,初期是放置于github,后面墙得厉害就搬到了码云,但码云有时候限制繁多也有限速干脆搬到了自有的七牛云空间并开启解析首页服务,毕竟和其它文件一样静态网站也是文件嘛,都一样可以通过网络访问,在七牛云CDN的加速下使得我的博客可以快速的被加载出来,当时还给博客加上了Live2D的看板猫,十分有趣,不过后面觉得这玩意太吸引注意力就撤走了。
0x62 树莓派3B
以前买的都是树莓派2B,碰上新出了3B版本,价格依然还是遵守原来的35美元承诺,这一版本相较之前有诸多亮点,以前WIFI和蓝牙都是需要外接USB网卡或蓝牙才能实现的,现在直接集成到了主板上,处理器和内存都进行了升级,使用起来很满意。购买的另一个原因是我在一个国内比较大的树莓派QQ群里是担任管理员,经常需要解答一些树莓派的问题,手上有个真机可以方便实测。
0x63 服务器集群
工作室每隔一段时间可以向学校申请一些资金用于补贴耗材支出或新增设备,我想着是否让工作室成员也尝试一下树莓派,不仅能够提前认识Linux系统还能为嵌入式开发奠定基础,所以这次的申请我还添加了几台树莓派,其中临时闲置的两台加上我自己的一台就放在工作室交换机箱顶上,组成了一个三机集群,在这上面还顺便实践了一把Docker。
0x64 斐讯k2
在斐讯翻车之前,这趟车是很香的,吸引了一大波的羊毛党,斐讯k2路由器是其中一款香饽饽,许多拿到返还的购买款后就将路由器挂到闲鱼上卖,刚好宿舍的破小米3C路由实在不行,趁着宿舍网络提速到50M,我就在上面收了一个k2,50包邮,这款路由器的特色是可以刷其它固件使用,按照教程对着路由器开刷,先是下了Breed、华硕老毛子固件,然后刷了个Breed防止刷成砖头,接着使用Breed刷老毛子固件,完成后这台廉价的路由器发挥了它的作用,老毛子固件也可以实现许多神奇的功能,比如挂上小飞机就可以全宿舍科学上网了。
0x65 Arduino
这是一款很流行的开源硬件,它相比树莓派更多的是直接参与硬件控制与传感,购买了UNO款的Arduino成功实现了将树莓派作为上位机,Arduino作为下位机,实现控制舵机旋转开门。
0x66 React-Native
前任老板又跑过来找我说打算开发一款像美篇那样的APP,就这样连React都没碰过的我,强行上了React-Native,然而他仿佛在说:“你被强化了,快送!”。整个过程不算很吃力,但是这玩意坑就是多,由于技术比较新,网上分享的文章也是少得可怜,许多问题还得自己查文档一点点解决,只能说如果要接触必须要对原生有一定了解,否则当遇上一些奇怪的问题时光有前端知识是没有用的。
在实现完初步的界面后老板又开始改主意,工资也没发了,我决定还是放弃吧,毕竟自己还有很多事情需要做。
0x67 无聊网站
无聊的时候,用了一天做了个情人节表白小网站,实现自动化的播放流程和动画、音频,可以用来备用。
0x68 开放平台
也许是受到了一些开放平台理念的影响,突然冒出了奇怪的想法:如果在学校内部署一些传感器,通过传感器获得一些实时数据,存入时序数据库,然后提供对外的API接口服务,校内的开发者能通过APPID和密钥认证获得AccessToken访问这些接口获得一些实时数据,比如食堂在某个时段的人流量进行一些自动化的操作,还能建立大数据图表,数据甚至能够用于AI模型训练。想法很美好,使用Vue.js实现了界面,在开始做后端部分时,突然想到在这样一个3B大专里会有几个人去当这样的开发者呢?最后还是放弃了。
0x69 新脚手架
这已经是这个脚手架第五次改动了,依然是选择基于koa2做的,因为koa2足够的轻量纯净,这个脚手架其实就是包了一层封装让它更适合实现RESTful API,独立出了路由件和处理件,不断积累公共类库common,并对MySQL、Redis、RabbitMQ的API进行了二次封装和改进。
路由件采用HTTP动词作为key,嵌套了接口URI与方法的映射,当请求与某个URI匹配时就调被映射的方法,这里主要进行鉴权和数据预处理以及结果返回。
处理件作为一个类暴露给路由件,路由方法被调用时可根据需要调用对应的处理件方法,完成处理后再返回路由件,这里主要就是核心的处理逻辑。
但依旧缺失DAO层,当时不知为什么并没有意识到。
0x6A 白嫖奖品
恰逢华南医疗信息网络大会,学校出资让工作室的几位成员一起去学习参观,这个大会有多个展区,吸引了来自各地优秀人才的参观,同时也开放了一些有趣的活动,其中一项就是积分抽奖,积分需要通过扫描每个展位的二维码获得,积分达到一定额度后即可参与线上抽奖,在扫描展位二维码时我将链接复制了下来一看,似乎是有规律递增的数值而不是随机值,瞬间就想到了白嫖的绝佳方案,先是尝试更改链接尾部参数验证是否存在这个漏洞,确认这个数值基本是递增的,于是写了个爬虫,现场把某个范围内的页面全部走了一遍,积分顺利到手,连抽了几次白嫖了三个奖品后就停下了,奖品是由部分参展商提供的。
0x6B 创新盒子 ★
简介
这是除魔塔外对我人生意义重大的另一个项目,也是第二个真正完整并上线的项目,最重要的是这次有了一定量的用户,有用户就意味着你的程序功能需要经受大家的测试考验,并且有最真实的建议和需求。也是他们使我在运营时不敢轻易弃坑。
创新盒子,这是一个提供优质校园服务的微信小程序,截至停止运营的最后一次统计,拥有用户量8200+,整个学校学生有12000+人,意味着当时全校至少有68%以上的学生曾使用过它。
起初它的名字叫做创新校园汇,开发它的原因是当时校内出现一款名为“校城汇”的小程序,在学校内部关系的推动下要求所有学生使用该小程序,学生用它签到老师用它点名,整体体验也是十分糟糕,在这种情况下激发了我想做一个真正能为大家带来方便的小程序,在完成第一版本上线后获得了一些好评并且与校内关注人数最高的公众号“掌上创新”关联并改名为创新盒子还更改了LOGO。我所在的大学里,查课表、查成绩、查饭卡余额、查图书馆藏书和借阅记录、抢课、评教等等在此之前都是需要登录极为笨重且古老的正方教务系统或者藏在学校内网的饭卡系统以及图书馆系统,人多的时候更是基本503 Service Unavailable,这一切都是创新盒子需要解决的痛点。
整体的架构如下所示,很糟糕的图,可以忽略集群这个词,因为最终只在单机实现
开发过程
首先,先对正方教务系统的核心功能进行一个全方位的了解,这个系统是使用ASP.NET开发的,整个系统的源码混乱不堪,命名更是惨不忍睹,大量的默认控件名比如Form1、TextBox1,谁维护谁吐血,在对登录、成绩、课程表、抢课等功能进行了初步了解后,就进入了下一步。
很明显,需要接触到学生的个人数据必然是需要登录的,那么如何实现模拟登录就是需要重点解决的一个大问题,先是研究了登录请求并用Node.js实现爬虫进行模拟登录,爬虫需要在整个过程中记住Cookie,模拟登录一个最大障碍是验证码,这个系统的登录认证本身就十分缓慢,而系统提供的token有效时间又是有限的,如果每次拉取同步最新的数据都要用户输一遍验证码那体验很不好,于是我优先开始处理破解验证码。
在确认这个系统没有可以直接绕过验证码登录的漏洞后,决定通过OCR识别数字与字母来获得验证码结果,但是经过费了九牛二虎之力都没能让OCR的识别正确率达到可用的标准,因为这个验证码虽然很低级,但是有些干扰确实对OCR来说有不少难度,比如字符旋转后叠在了一起或者干扰点影响到了效果,最终我决定拼一次命,直接接触我从来不敢碰的AI训练,在电脑上安装了TensorFlow和Keras,Keras可以使用TensorFlow作为后端实现了更人性化的API,先是直接爬一万张教务系统上生成的二维码,分出八千张作为训练集,两千张作为测试集,然后配合Node.js写的本地服务,实现在网页上对训练集的每张二维码进行标记,被标记后的二维码文件就会被Node.js重命名,在花了一天半时间标记后,还花了半天时间校验了一遍,毕竟是很可能打错字符的,终于结束了这个艰苦的流程,眼睛看验证码都快看花了,感觉脑子里就只剩0-9 A-Z这些字符了,得到这批经过标记的二维码文件,但距离它成为训练集还需要进行预处理,因为它现在还是彩色的而且干扰点还很明显,这对于训练来说无疑是巨大的干扰,先用Python对训练集所有二维码进行二值化,将所有图片处理为字符形状较为清晰同时噪点也尽量少的状态,下一步就是找出训练集中尽量贴近字符四个框位,将每个图片的四个字符按照框位裁剪出四张图片,并分别放入他们所属的字符文件夹,比如字符a就放入字符a的文件夹,以此类推对训练集所有的图片都进行拆分归类,最终得到包含所有字母和数字的文件夹。之后继续使用Python编写训练代码,配置512个神经元,进行一波训练收敛后,测试集跑出来的准确率达到99%,至此训练结束得到了模型文件,后面的事就好办了,在python写了一个验证码识别服务,Node.js通过IPC与它通信,将图片以二进制流形式传输给识别服务,识别服务会返回四个字符组成的字符串。
通过以上的流程终于是解决验证码这个难题了,用户进入小程序只需要进行一次的学号与密码授权,后续的登录都由后端自动完成,并且也会记录每个用户在教务系统的token,只要没失效都可以继续使用。
查课表时,如果用户第一次同步课表就直接从教务系统同步此用户的最新课表,如果不是则优先返回缓存,先返回本地缓存课表,本地没有就返回服务器的Redis缓存课表,再没有就获取服务器数据库的缓存课表,缓存层在这里面发挥了重要的作用。如果需要同步最新课表也就是强制同步时爬虫再登录一次教务系统爬取。
查成绩也是与上面同理,主要麻烦是,我自己只能看到自己的成绩和课表,而这个教务系统的数据展现方式又是千七百怪,特别是课程表,为了正则能够尽量匹配到所有的课程内容,可谓是煞费苦心,写正则写到头秃,还跟不同专业、年级的学生们借用账号来查课表调试正则,并且还会遇到课程冲突情况还得额外提醒处理,幸好最终没有白费精力,还是成功完成了各种课程和成绩数据的爬取。
而抢课这个就比较特殊,当时想过一个解决方案,但因为成本和时间问题并来不及实现它,抢课就相当于大量的并发请求打在服务器上,变相的DDoS,但这个量级的流量,服务器的QPS应该不至于那么差,主要还是这套教务系统的问题,我的思路是先爬取教务系统的待抢课程,放入Redis中等待扣除存量,抢课请求打过来,首先将请求队列化,然后扣减Redis里对应课程的存量,并将该用户的抢课申请记录入数据库,并且需要实现一个应用级的事务,如果申请记录入库失败应当补回存量,由于已经队列化请求就可以不用锁了,这里就是预抢课阶段,在这个阶段进行的过程中就需要有一条线程去负责把抢课申请真正在教务系统完成报名,这样既公平又高效。但如果要这么实现意味着得向校方申请阻断从教务系统抢课的入口,不太实际。
上面提到饭卡平台是在学校内网的,而创新盒子的服务器是在阿里云的,公网没法直接访问内网,这回以前用的SSH隧道就又一次发挥了它的作用,这次使用树莓派作为学校内网里的“内鬼”跳板机,它接入的刚好是连接学校内网的工作室网络,树莓派采用反向隧道将饭卡平台的80端口代理到了服务器的6000端口,这样服务器就成功通过6000端口访问到内网饭卡平台的80端口了,这次为了避免隧道因为临时断网而直接断开还采用了autossh,如果断开autossh就会尝试重连,饭卡平台由于密码形同虚设,因此只需要有学号就能够查询到对应饭卡余额,所有用户的密码都是同一个,验证码也可以轻松绕过,天时地利人和,用户通过小程序查询饭卡时,爬虫模拟登录、爬取充值和消费记录以及余额并返回和缓存,也可以发起请求挂失饭卡。
然后就是查询图书,学校有一个图书馆系统,比较简陋,但至少还能够查询到书籍以及摆放的位置,也能够获知借阅是否逾期,因此还是老一套,这套系统的权限验证也是和饭卡平台一样可以轻松的绕过,爬虫可以请求书籍详情和逾期情况在小程序上展示出来。
之后还实现了一样比较有趣的功能:关联课表,可以关联你所在意人的课表,对方同意后就可以完成关联了,关联后可以在课表列表中点击查看对方的课表,情侣必备工具+1,这里还接入了WebSocket做实时消息推送。
评教一直是学生特别讨厌的一件事,不仅要登录缓慢的教务系统,还得一个个课程一项项点评点进行手动勾选,所以我顺势也推出了速评教功能,借助之前打下的系统基础,可以轻松通过爬虫自动的对每个课程的每个表单请求进行逐一提交,实现整个流程的自动化,不过所有选项都是默认评为优的,也可以单独点击不同课程手动评价。
后续也加入了失物招领等实用功能,随着小程序流量的逐渐增多还开启过小程序流量主,分别在主页底部和课程表底部不影响使用的位置放置广告栏位,在广告栏位上线后,在后台查看流量主数据,发现原来流量真的赚钱,一天只有很低的广告点击量也能够收入50-70,多的时候一个月下来差不多也有一两千元,对于还在大学的我来说不算低了。
这个项目的代码在学校内部是开源的,在形成一定影响力后,开始不断有人前来询问或学习,这让我感到很有成就感。
项目后续
后面拿着这款作品参加了不少校内外比赛也拿了一些不错的奖项,第一次接触这么多用户的使用也让我想要好好的做这个产品,为他们负责,为新生们提供最好的校园服务,可惜好景不长,创新盒子最终停止运营了,原因是学校有很长一段时间里干脆关闭了教务系统,已经无法线上访问了,在这种情况下,创新盒子大部分需要同步的功能就无法照常使用了,我曾经认为只要我继续耗着,学校肯定会恢复教务系统的,结果一等再等,服务器我已经白续了几个月,这个服务器开始时由于大学生认证一年也就一百多,耗到我出来工作学生认证失效,服务器的成本就陡然上升了,最终考虑到我个人的经济情况决定关停服务器。
在创新盒子关停一段时间后,科创工作室开始涌入新鲜的血液,开始有新的人接替我去实现这样一个工具,在原本理念的基础上实现了一款名为“We智慧创新”的小程序,这大概是学习了“We重邮”的命名方式,总体功能与创新盒子比较接近,还包含了一些创新,很棒。
0x6C 云账宝
闲来无事就想给自己做一个精简的云记账工具,平常接触的一些记账工具都太花里胡哨一大堆广告也不太方便,用上微信小程序云开发完成了基本的记账功能,方便平时记录一些自己的花销情况。
0x6D 查题助手
学校定期有组织专升本的考试,而考试的题目大多也都是线上测验的原题,所以为了方便大家能够在平时背题时能够马上查到题目和答案就制作了个查题工具,题库是爬虫从线上测验系统自动爬取的,通过查询题目关键字即可得到搜索结果。
0x6E 微科创
微科创是一个专门为科创工作室服务的微信小程序,是属于工作室项目计划的一部分,至于工作室项目计划是与几位核心成员在某天深夜在宵夜街一起吃关东煮时讨论出来的一系列支持工作室与学校技术发展的项目计划,而微科创能够实现工作室内部的成员考勤签到、日常招新、问题管理与解答、管理其它项目配置、其它项目登录授权等功能,其中的考勤签到是采用之前提到的扫描iBeacon基站判断是否处于工作室内完成打卡。
0x6F 外聘工程师
学校每年会承接一些考试监考工作,比如全国会计专业技术初级资格无纸化考试,考试是使用无纸化系统的,考试前夕系统供应商会安排一位工程师到学校驻场,主要负责在校内计算机相关专业招募可以辅助给考场机房安装维护无纸化系统和应急处理的人员以及对被招募人员进行基础培训和分组,工作室成员自然也是被优先考虑,当然也不是白干是有报酬的,我就拉上几位朋友一起赚钱去了,培训时内容十分简单,每个考场的机房都会占用两台电脑用于监考机和备用监考机,其余的机器均作为考生机接入,考试前需要进行考生签到,签到需要刷身份证并且拍照与报考照片比对,到达时间时需要下载授权码用于开启试卷数据,考试时所有考场机房都会切断外网访问同时屏蔽器也会开启,考生机的所有作答都是实时同步到监考机的,监考机都专门配备了UPS电源,确保在断电时仍能够将考试数据备份出来,它和备用监考机并不是双机热备,仅是在监考机崩掉的时候代替监考机重新收集各考生机答案,考试结束时需要将监考机的考试数据备份文件放入U盘上交。培训时的模拟操作很难复现现场可能会发生的各种状况,所以也提前做了许多预案,学校机房的电脑平时维护情况并不好,设备也比较老旧。考试前一天我们每人获得了一张初级工程师考试技术服务资格上岗证,考试的时间里我们就在自己负责的楼层四处巡查,如果出现问题监考老师就会招呼我们过去处理,尽管我们开考前已经仿佛确认了可用的电脑也冗余了一些机器,但还是避免不了各种奇怪的问题:比如网卡时好时坏、显示器VGA接口接触不良、机箱电源接口接触不良、键盘或鼠标失灵、硬盘坏道导致丢失库文件、内存条存在问题时常蓝屏等等,唯一一次大点的问题就是监考机系统假死,不过在备用监考机上恢复了考试,由于处理及时没有发生申请考试延时的情况。
0x70 修复上古编辑器
朋友给我发来了一张截图,里面是04年用asp写的网站,他问我能不能有偿帮忙修复一下,我接了下来,然后在有空的时候开始研究,发现这里面的大部分代码对现代浏览器的兼容性很差,进行了一篓子的兼容改造,让编辑器终于恢复了正常的显示样式,本以为一切正常了却发现在上传文件时报错,调查后发现服务器方面虽然是只有控制面板的主机内部却还带有360的主机防护,由于这个版本的cms太老,上传接口的脚本存在漏洞,主机防护识别到漏洞特征就直接把脚本文件给自动删除了,后续花了点时间更改了脚本终于修复了。
0x71 SMP音频解密
学校放假待在老家时,爷爷拿过来一个类似MP3的音频播放器,说是想把里面的歌曲放到自己的手机里,我一想这多简单,接过播放器和手机,在电脑访问播放器存储时发现文件是被加密过的SMP文件,这是我完全没接触过的领域,幸好在吾爱破解论坛发现有人尝试解密SMP文件,了解了以下后知道这个加密只是简单的异或加密。并不涉及硬件层面的解密,那就好办了,下载了WinHex工具打开文件内容,从文件中找到密钥十六进制值,尝试单字节异或,发现本质就是mp3格式,接着写了个工具批量将SMP文件内的十六进制值异或密钥运算得到可播放的文件并重命名后缀为mp3格式,这样处理过后将所有文件拷贝到手机内部存储就结束了。
0x72 人肉Debugger
在多年的不断跳坑下,练就了一身Debug本领,基本遇到的大部分问题都能解决,所以也开始经常解答和帮助别人,当顺利帮助别人解决问题时除了获得感谢后的成就感之外,还能帮助自己加强经验记忆,而且有些BUG有自己的特色,能在解决后让自己有不一样的收获。
遇见的问题八成是低级错误,比如语法错误、逻辑没搞对、API调错、报错信息不会看等等,剩下的错误一般就是涉及平台兼容、代码设计问题、库源码bug、锁问题、线程调度、数据一致性等等更深一些的问题,但事出必有妖,所有BUG必定都有其根源,练就Debug思路很重要,而且需要具备最基础的计算机英语知识(本人英语水平只能过英语B级,所以学计算机英语不难的),所谓久病成良医,Debug经验越充足越能顺藤摸瓜找到问题根源并提供解决方案,还有出问题的第一反应应该优先怀疑自己的问题,并且先自己思考,软件硬件都一样。
帮助别人的时候也讲究望闻问切,所以希望对方都能提供代码和报错截图,并且能快速的配合解决,当遇到一些很难以配合的情况时就很难提供帮助了,比如上来就问 某某情况该怎么解决?谁会啥啥?也不提供任何截图和相关信息,大家的时间都是有限的,有心想帮助你但害怕你无法配合处理耽误了自己的时间。或者也经常会遇上问问题却还带着架子的,相当于直接先一桶冷水泼大家脸上,这样谁还愿意提供帮助呢?
0x73 交叉编译
第一次听到交叉编译这个词汇应该还是在Android上使用别人编译好的ARM平台adb工具,理论上只要有源码,都可以编译出目标平台可运行的程序,当编译平台和目标平台不是同样时这就是交叉编译了,交叉编译可以使用编译机完成对性能资源要求较高的编译过程获得可在低端平台执行的程序,当时是一位朋友找到我说它下载了在Android上使用的tcpdump工具,但它在Android模拟器的Shell中无法运行该命令,我询问后得知它模拟器中运行的Android是x86平台的,x86平台的Android相比ARM可以更高效的在电脑中运行,其内核其实就是32位的Linux,之前接触过的一款名为Genymotion的Android模拟器就是采用的x86内核,很明显我朋友所下载的tcpdump工具只适用于ARM平台,根据能够找到的资料,我在服务器的CentOS7环境中先安装了开发工具包以及glibc静态库接着去下载了tcpdump与libpcap的源码包并解压,配置两个包的编译参数,目标平台均为i686的Linux,配置完后就开始make编译了,编译结束得到了Android x86可用的tcpdump工具,然后只需要把该工具push到模拟器中运行即可。
0x74 代理服务器
一位朋友给我发来的个投票,想要帮忙召集多些人来投,我测试了一下投票的接口,除了限制IP地址外似乎没有其它限制了,然后就找了一个提供大量免费代理服务器的网站,先用爬虫从该网站爬取出代理服务器的列表,然后再通过代理服务器向投票接口发起投票请求,效果刚开始比较显著,但免费的代理终究不实用,有大量代理其实已经失效。
0x75 面试
大学的时光过得太快了,就读的大专是三年学制,但两年半时就该出去找实习,当然,校内招聘会是少不了的,但是3B大专是无法吸引来大厂招聘的,大多都是外包公司或小型公司,尽管如此,我还是精心准备了以下简历,风格以最简约的白纸黑字为主,采用基本的排版,一心想着把会的全往上面堆,最终整个简历密密麻麻,一页纸差点装不下,按理应该根据岗位要求缩减的,但想着就是朝全栈去的,干脆不改了,校内招聘会时把简历给到面试官,面试官的表情大概是从愣住-震惊-不信,只有两三位面试官问了问题也都答上了,其它的基本都是收个简历,这些也就是走个流程看看,没有选择去就职。
我将简历传到了BOSS直聘去就放着了,当时还不着急找工作,所以基本都在等别的公司找上门,四天之后再打开APP发现已经有十几家公司在询问情况了,在排除了外包后看了剩下的几家都不太满意,这样的状况持续到准备正式出去找工作的时候,我工作目标地点基本锁定在了深圳,知道深圳生活节奏很快,但定有更多可以学习的东西,在准备前往深圳的前两天我确定了四家待面试的公司,两天后我踏上了我的深漂旅途。
到达深圳后已经是下午,去的第一家是经营金融业务的公司,在约定的时间到那时面试官不在场,只和前台的姐姐坐下来聊了几句就离开了。第二家就是我后面正式入职的公司,坐标福田上梅林,是做钢琴培训教育的,主营一款名为“琴小站智能琴房”的产品,具体面试情况等会再讲吧,第三家公司主营小游戏业务,由于时间关系只能拖到第二天再过去面试,但由于路途遥远,中午到达时负责人表示出去了下午人不在,好呗又打消了一个,接着转移目标到第四家公司,这是家在福田保税区主营工艺礼品定制的集团公司,和面试官进行了一些交谈后,给我展示了他们的系统,我也展示了一些自己的代码和作品,聊得还算愉快,但觉得项目没有什么挑战性后面决定拒掉。
0x76 琴小站 ★
Offer
在到达第二家公司面试之前,我和女友拖着行李箱在附近兜兜转转都没能找到公司入口,最后仔细询问后终于找到了图中那条巷道,图是全景地图里截的,走进去后看到一栋比较老旧的厂房楼,当时已经是下午六点多,由于是冬季天色很快就暗了下来,加上那个奇怪装饰的货梯入口,货梯内大片的红色油漆以及已经损坏一闪一闪的照明灯,给这趟面试添上了几分诡异气氛。
老旧货梯运行速度很慢,到达四楼转个弯看见走廊两旁各放置一列钢琴,红地毯从走廊入口一直延伸到了公司的入口玻璃门,产品经理何哥过来接待了我,进入公司后引入眼帘的就是一间琴小站琴房,何哥向我介绍这是他们的第一代琴房产品,目前已经改进了一个版本并且投放在了三个小区内。这块区域几乎堆满了钢琴,往里还有一个空间很大的音乐厅,办公室只是在琴房旁边隔了两个小玻璃隔间,每个隔间可容纳5人办公,人事、市场、财务、研发混在一起没有区分部门,实打实的小公司,公司是为琴小站这个项目于2018年5月刚成立的,在此之前,这块场地是主营钢琴销售与二手钢琴回收翻新业务的钢琴厂,其中一位股东也就是现在这家公司的CEO刘总。目前这个阶段相当于两家公司共用一块地方,直到年后才在隔壁装修了新的办公区。
何哥把我带我到了音乐厅里坐下来正式面试,我先将自己的一些信息介绍后,他给我展示由外包开发的系统,据说花费五六十万,前端是微信小程序,总体效果挺丑的,交互体验更是难以言说,后端方面全部采用PHP开发,接入硬件部分用到了swoole,展示结束后,我取出带过来的笔记本将我的作品和技术栈也展示了一遍,何哥点头表示十分满意,然后提出了一个想法:重构整个琴小站项目。
我在之后深入了解后发现这不是一件简单的事情,这个项目刚起步几个月不到,除了设计师没有招聘其它技术人员,而且现有项目从软件到硬件均存在很多问题,这时重构会花费大量的时间精力,理论上不应该进行如此冒险的行为,但初生牛犊不怕虎,正想找个有点难度的项目挑战一下,刚好还是我比较喜欢的软硬通吃项目,所以在一天后接到Offer通知时就直接答应了,试用期薪资只有8K,3个月转正后加到9K,转正后才有五险,薪资在一年后涨到10K,在第二年提离职时涨到18K,全年单休,朝九晚六(然而回到家里还是在赶项目进度),满一年起步才可以有5天年假,虽然薪资一直低于我的期望还时常拖发工资但还是坚持到第三年底才辞职。
入职
入职前一天我把生活用品和屏幕、机箱等等收拾好,出发前往深圳的亲戚家寄住,小时候就经常去那里玩,他们也是几乎一路看着我长大的,对于一个初入社会的人有这么个港湾瞬间就没有了异乡漂泊感,也算是有了一点先发优势,毕竟前期不需要考虑租房压力甚至晚饭都解决了,说实话一直白嫖吃住我自己是非常不好意思的,随着工作收入逐渐稳定下来,已经寄住一年左右后的我决定搬出去和女友一起租房住,虽然后面出去住了他们也经常叫我过去吃饭过节,很感恩。
2018年12月3日那天早上我准时的到达了公司,没想到来得有点太早,公司门都还没开,在楼道等半小时左右人事终于来开门了,我推着装了主机和屏幕的行李箱走进了我的工位,考虑公司起步阶段需要省资金就没有要求提供资金给我配台主机也不要求给机补,就自带之前配的ITX主机过来了,怕电源插口不够用还把排插也带上,一顿折腾算是把工位搞定。
当时我的左边是财务,对面是设计(后面为了聊产品方便换到了我左边),左斜对面是市场,我们在一张四连桌上,右侧是产品独立工位,目前为止还没能见到老板一面。
产品分解
既然想要重构,自然是先需要把现有项目的功能进行分解研究,跟何哥要来了所有的源代码的相关平台账号,由于是外包所开发,前后端源代码都比较混乱,甚至还混杂了用于其它项目的代码和注释没有删除,看样子是批量定制的外包方案,下面是大概先描述一下接手时的项目状态,这个项目由于起步时各项基建都极度缺失,导致后面重构时面临水桶效应,使得重构进入一种近乎无底洞的状态,最后迫不得已软硬两手抓把水桶的木板尽量补齐,这样项目的技术水平才能够上得来,这一系列经历在后面都会有涉及到。
C端
产品的C端部分是一个微信小程序,由于这一版本设计也是外包的所以整体设计粗糙、交互糟糕,存在多个Bug且时段选择比较死板,后台维护功能也是放在这个小程序中,最奇葩的莫过于这个Logo在圆框内的比例也太奇怪了吧,然后给改成右边这个样子,我是一个有完美主义倾向性格的人,否则可能不会轻易答应重构
C端主要逻辑就是用户扫描琴房屏幕显示的二维码,引导公众号关注后再进入小程序的对应琴房选择时段预约琴房,到达使用时间时用户就可以点击开门按钮控制琴房玻璃门解锁进入琴房并且空调与灯会自动开启,当使用时间结束时琴房的空调和灯会自动关闭,以下是它的部分截图。
B端
产品的B端部分是一个基于FastAdmin(ThinkPHP5+Bootstrap)框架的后台系统,体验上整体中规中矩,包含各种常规CURD操作,作为一个只给内部人员使用的系统确实是没问题的,但最核心的琴房控制功能却没有提供,并且依然存在一些BUG,依然需要在C端小程序中授权进入,从这到之后准备重构的后台系统来看,公司内部几乎所有人员是不愿意一直待在电脑前面的,所以在后期我直接把B端定位在快速易用的小程序上,这样不管处于何时何地都能管理琴房和订单,框架没啥大问题,糟糕的地方还是在外包写的代码中:函数命名混杂混入了其它项目的命名但却实在在为现在这个项目运行,也自然少不了英文拼音混合无驼峰或无下划线命名等、代码注释大量缺失或混杂,导致在修改功能时找代码10分钟修改10秒钟,只能不得不补充一些注释插眼方便查找。
机器云
机器云是负责接入控制板硬件和服务器通信的部分,依然是使用PHP编写,PHP本身是单线程的,为了应对这种实时通信场景这个部分就用到了Swoole(支持多种协议的异步、并行、高性能网络通信引擎),硬件方面为了在弱网环境下仍能维持较好的通信采用了UDP协议,毕竟TCP协议还需要三次握手才能完成连接,而UDP并不需要建立连接即可发送数据包,虽然存在丢包的可能,这时候重试机制就十分重要,但在机器云的代码中并未发现重试部分的代码,当控制板处于弱网环境时,机器云发出指令数据后就会一直等待响应直到无响应超时,这也导致后续的指令无法处理被阻塞,等待指令响应是通过不断检查是否存在响应的Redis记录值却不是使用回调函数这也让性能大打折扣,因此我们维护琴房时也不敢同时控制琴房还得控制手速,尽量确保一条指令下发完再进入下一条,除了这些问题外就还是代码混乱、请求参数无检查就发给硬件等等。
琴房硬件
接着就是琴房硬件部分,这位选手更是重量级,当我了解到这时震惊的发现此方案原始得不像智能琴房,从某种程度上就是一只缝合怪,能做成一套产品确实不易,最开始应该也是外包的方案,但该方案基本是为室内环境而打造的,除琴房本体结构和钢琴外主要由控制板、电插锁、门锁开关、插排、电梯空调、排气扇、安卓盒子、32寸显示屏、“工业级”4G路由器、杂牌网络摄像头、照明灯、USB插座构成。琴房结构上也存在问题,第一代琴房如上面的图片是有钢制顶棚的,但后续生产的琴房都取消这个顶棚了,原因是它非常笨重,至少需要三个人才能勉强抬升不利于维护,取消掉还能降低点成本,室外琴房就改用不锈钢架上有色半透PVC顶棚,为了维护方便拆顶棚还空出一条大缝隙,其它在架空层或有点遮掩的琴房是没有顶棚的,这就导致顶部会大量积灰,遇到大暴雨或台风天就会有雨水通过缝隙瓢泼进琴房顶,雨水和灰尘混合后变成了良导体,加上布线混乱还采用插排接线,容易引发漏电甚至短路,漏保跳闸几乎是家常便饭,也幸好能跳闸不然对用户来说是十分危险的。
控制板采用12V直流电源供电,主控是一颗STM32F103RBT6,它旁边是一颗SIM800C的2G通信模组以及SIM卡插座、天线SMA接口,还有一片EEPROM用于存储配置信息,黑色圆柱状的是一颗蜂鸣器用于产生刺耳的“嘀”声来提醒用户,有两路继电器分别是用于控制照明灯和电梯空调的通电或断电,还有用于控制12V电插锁电源通断的MOS管以及判断电插锁状态的接口,最后就是用于判断房内门锁开关是否按下的接口。整体用料不太给力,不过考虑到需要节省成本倒也没啥,但是一块控制板要价60多,当时芯片价格还不像现在这样直线疯涨,批量生产的成本是很低的,利润空间属实大了。功能方面,只有两路继电器但实际需要控制的还有房内的几个插座和播放广告的盒子和显示屏等的电源,因为缺失插座控制就经常会有人插用电器在使用时间结束后还在插座上白嫖电源,而且为了防蚊还配上了电子蚊香液,蚊香液是消耗品,无人使用时也在24小时工作蚊香液一下子就消耗光了,所以至少用户插座这一路的缺失是比较严重的,继电器这一侧的强电接口也是容易变形松动且较危险的,直接将电源线裸露在外,碰上上面所描述的暴雨那就是妥妥的漏电跳闸。PCB布线方面也相对随意,电源地和数字地没有进行隔离,容易串入干扰,在某些情况下会出现误动作。另外2018年联通就已经发布公告准备清退2G网络后续移动和电信也相继发出相同信号,也就是说这批控制板在未来会面临信号逐渐变差直到无法联网的问题,这是一个比较急待解决的问题,固件方面的主要缺陷还是在发生临时断电然后来电的情况时控制板无法主动恢复使用状态,需要用户主动自己重新开启。
电插锁也是12V直流电源输入,由控制板控制它的电源通断来驱动锁舌的伸出或回缩来实现锁定或解锁功能,但这种锁存在一些问题,特别在一些品控不佳的锁上尤为明显,在锁使用了较长时间后,锁舌磁化容易导致锁舌无力,自动回缩或伸出一半不动或不回缩甚至锁舌直接掉出,而且室外琴房经常面临潮湿环境,锁舌也出现锈蚀影响锁舌伸缩性能,并且锁工作时发热量高要求电流大,整体寿命偏低,孔位需要比较精准否则难以锁定,经常会有用户反馈门关不上或者门锁不住或者门锁不开均是因为这些问题导致。它的主要优点:锁上怎么用力也无法拉开,在玻璃门上也无效了,玻璃门使用这类锁需要一个门夹,虽然锁舌扛住了一切,门夹却没能扛住大力出奇迹。
插排这部分其实从考虑放在室外的时候就应该彻底摒弃了,也许是电工为了接线方便不愿意使用接线盒,在这样的恶劣环境下实在不适合使用插排作为接线手段,更不用说还混装过勒令停产的万用插孔插排,因此引发的跳闸也不在少数。
琴房在室外肯定避免不了闷热,所以配备了电梯空调,但正是因为这个空调导致前期投入了大量维护精力,其一是它在烈日炎炎下工作时制冷效果很差,特别是在安装了顶棚导致气流难以流通的琴房上制冷更是不尽人意,其二是它对通风管的保温有很高要求,如果保温棉没有把管道包装严实就会导致管道内凝结水珠通过出风口滴到用户头上,其三是它压缩机电路损坏率较高,也许是杂牌的原因又碰上频繁的开关,出现过有三台空调压缩机不能正常工作的问题,其四是外包公司并没有将控制板和空调协议进行对接,这导致除了开关空调没有其它功能,空调的功能控制只能通过对着天花板按遥控器控制,天花板上的对应位置装着一块空调自带的遥控板,每个用户对温度的敏感程度又不一样,公司不得不给每个琴房放置一个空调遥控器,这样就又冒出的新的问题,空调通电时是按照上次断电时的状态进行工作的,假设上个用户觉得冷极了用遥控把空调关了或者把温度调高,下个用户过来热极了由于上次断电时是关机状态那空调就不会通电启动或者保持着上个用户调的高温度,如果用户不懂得用遥控器自然就来投诉了,更奇葩的是有的遥控器干脆给小孩子偷走了,所以这一箩筐也是亟待解决的问题。
下图中是空调遥控板和电梯空调拆开的状态:
广告屏部分是由安卓盒子和带驱动板的32寸显示器组成,安卓盒子型号是MX3和MXQ似乎有区别,但都是低端盒子,主控是一颗晶晨S802,配备1GB运行内存和4GB存储空间,播放的广告内容都是通过读取插入的U盘文件,为此公司在某宝低价定制了一批刻有琴小站8GB存储空间的U盘,这样的U盘自然是存在问题的,文件传输速度极慢、容量虚标超出实际容量部分的数据会损坏或丢失、寿命短发热大,因此放在琴房里一起24小时工作后,经常会出现盒子因为无法正常读取U盘而播起了内部存储默认广告的情况。就像下面右边这样:
为什么要使用U盘而不把文件直接拷贝到内部存储播放呢?当我得知他们需要定期去手动更换U盘来更换播放的广告时我是震惊的,这里最核心的问题已经不是在于U盘是否好坏,而是这种手段存在问题,广告难道不应该是在线上推送线下自动更新吗?而且发现U盘里需要放置的文件也比较奇怪,上下的图片并不是分开播放的,只有视频是单独播放的,这就导致上图无法和下图分开播放,还会导致图片文件大小偏大,每个广告还得过一波PS,命名也有要求,如下图这样,这可好又多了一个需要解决的问题。
烈日的炙烤之下,不仅U盘会挂,连安卓盒子也挂了,经常会出现直接黑屏的情况,估计是因为只能采用5V供电,电压越低电流需求就越大,电流越大工作发热量就比较高,加上散热条件差就容易宕机,需要过去重启盒子才能恢复,于是就有了如下各种“自拍”了,在没有彻底解决前一些“惯犯”盒子的琴房先贴上了过胶的纸质二维码,这也是一大麻烦,当时听说这个盒子采购需要200多但实际在华强北逛的时候看到MXQ Pro这款的盒子也才百来块,又被坑一把唉。
显示器的问题在开始的一年还未显现出来,但一过保修期迅速进入报废期,开始出现多个显示屏损坏,一部分是被晒坏液晶,一部分是电源板损坏和电容鼓包滤波变差,电源板损坏的案例倒是大部分因为进了壁虎导致短路,一拆开就看到一只碳化的壁虎尸体,不过这类显示器毕竟不是户外专用屏,长期工作在恶劣环境下确实不易,何况价格就700一块,陆续因为屏幕无法正常显示换了一块又一块。
标注着“工业级”的4G路由器实属有点让人蚌埠住了,就像是试验机型一样,只提供一个LAN口和12V电源输入口,打开顶盖后除了主板部分就是两片贴片天线贴在外壳内侧,用料方面也很一般,实在远远低于工业级的标准,一个LAN口意味着就只能接个监控其它设备都只能通过Wifi连接,因这些不完善,监控网络连接问题将在此后很长一段时间里不断困扰着维护人员。
摄像头是和路由器、物联卡一起的外包方案,品牌是vsmahome,是一款云台摄像头,但塑料感十分重,提供以太网口和Wifi的两种接入网络方式,可以插TF卡本地存储录像,采用5V供电,只能通过支架简单固定在琴房顶上,最直接面临的就是物理和网络的不安全,物理方面这个云台可以用手把摄像头角度直接拨到其它位置,而且可以很容易将摄像头从支架上取下来,或者可以直接拔掉电源线,甚至可以把TF卡直接偷走就没录像存储了,网络方面经过我测试和大多数杂牌网络摄像头都一样存在可以直接通过RTSP协议默认账户和密码访问554端口直接获取监控画面,另外这个品牌没有提供云存储手段,因此本地无TF卡就无法回放过去的录像,查看监控需要下载他们官网提供的APP或者访问网页版,官网很难找并且也没有提供任何开放API,所以此产品基本不适用于共享琴房的场景,待解决问题再次+1。
这些就是我最初接手时整个项目的产品状态,接下来的所有关于这个项目的经历就是我改善这一切的过程记录。后续关于前中后期的描述均是以琴小站发展过程的时间为基准。
铺设琴房
在我正式入职之前,公司已经投放了三个琴房,接下来就是快速铺设琴房阶段,琴房正常收费是8元30分钟|12元45分钟|16元60分钟|24元90分钟,如果光靠练琴费用是不可能短期收回成本盈利的,公司前期主要战略是与机构和工作室合作,通过租赁共享琴房的方式为机构将教学场地分布式化,把琴房放在有生源的小区内,机构的老师去琴房上课,非上课时间其它用户过来练琴收取的费用也归给租赁方,琴房租赁费用大概是每年2W6。
理论上,假设琴房产品硬件和系统都很完善体验很好、公司有足够资源能够谈下物业铺设琴房、老师上课时间不会和用户时间产生太大的冲突,如果满足以上条件,这个走法是有较大盈利机会的,但现实是很骨感的,第一道坎就是琴房产品各方面状态还处于种子阶段,用户都表示体验差更不用提报名课程来学习的学生了,而且也没有为合作加盟专门定制系统,导致出现一种我租了但又没完全租的状态,第二道坎是公司的资源一直是不太充足的,琴房本身又是一个成本较高的设备加上物业费电费维护费是一大笔钱,对于一个创业公司前期不够省钱是致命的,第三道坎就是实际上老师和学生总会因为各种情况发生临时调课但用户却也是可以预约的,这就经常出现老师想调课时对应时间已经被其它练琴用户占掉的情况,这时候就又要费大量口舌跟用户解释和提供补偿,遇到强硬用户只能放弃调课,一来二去用户体验下降、老师学生体验全体下降。
基于上面这种情况,这套战略自然是以失败告终的,机构陆续都拒绝续约,幸运的是CEO很快意识到问题并调转船头让无机构运营空闲下来的琴房重新盈利,在此之前公司全员包括CEO都很辛苦不顾炎热风雨在线下安装和维护琴房,我也开始从办公室走出时常去现场维护和排查问题,依稀记得第一次爬到琴房顶上的那种慌张感,在无数次爬顶上后现在已经彻底习惯了在上面作业。
竞品分析
在整段经历中陆续发现了各种竞品,就先拿出来讲吧,比如雨果智慧琴吧、弹司令、巴巴杨共享琴房、微琴行、艺等仓、E家琴房、琴小练、天天共享钢琴、共享钢琴室等等一大筐,并且对这些竞品进行了基本的解析,最终确定三家在市场上存在竞争关系的产品,其实在这个比烂的行业里,后期产品优化好了这些威胁就不算事了。而且发现此类产品虽然很多,但生产厂家也就那三、四个,工厂基本坐落于东莞、惠州、广州。
三家竞品只有雨果智慧琴吧是在深圳本地运营的,也是公司最早盯上的竞争对手,他们的产品走的是和琴小站前期同样的战略,琴房整体成本可能达到琴小站的两倍,但他们的设备相对完善,门锁是无需联网的密码门锁,这种门锁内部和服务器采用了同一种算法,在一定时间内只会有一组有效密码,服务器提供该时段的密码即可在对应时间使用密码打开门锁,而无需联网控制,缺陷是不够便捷、成本偏高、时钟无自动校准、无法远程控制开门,优点是无需联网、无需携带手机。高配版外部有三面屏幕,利用率较低成本过高,内部空调功能相对完善但也只能在室内控制,放置了智能钢琴,用户端方面也采用微信小程序,整体效果很一般,琴房预约上可选时段很少且固定时长,收费也较高,当不同用户同时预约同个时段时会发生重单。他们的琴房铺设速度十分缓慢,从最开始到现在几乎没有新增琴房,网络方面由于他们的门锁不联网所以不存在离线可能。雨果还曾有内部人员想跳槽过来。
第二家是弹司令,坐标广州,也是早期发现的竞品,中间和公司打过一次外观专利官司,我们都持有外观专利但它比我们早两个月申请所以败诉了,因此我们不得不给所有第一二代琴房加装了黄色外框,弹司令琴房各方面硬件和琴小站都比较相似,他们几乎不把琴房放置于室外,这确实让维护省点心,但曝光率也降低了,他们前期也是同样的机构加盟战略,很快也遇到了瓶颈,中后期开始转向与各大音乐学院合作,将共享琴房放入学校中免费开放,用户端方面依然是微信小程序,整体效果很差,几乎没有用户体验,连基本的琴房图片都没拍标准,并且用户无法远程开门,必须要扫描琴房二维码才能开门,像大人给小孩开门的需求就无法满足,时段选择相对雨果多了一点但自由度还是很低,也存在重单问题。前期的铺设速度比较快,但很快就停了下来甚至不增反减,大量琴房开始离线,2021年的情况是35台琴房离线了19台,初步判断可能是2G网络无信号、停止维护或者断电。
第三家是巴巴杨共享琴房,坐标珠海,是中期突然出现的,他们主要战略是将琴房大量投放到各种商业区、广场、社区等人流量较大的区域,争取提高曝光量并依靠较高的练琴收费回收成本盈利,虽然也有尝试机构合作加盟和自营教师线下教学战略但似乎只持续了一小段时间,硬件方面就和其它产品大为不同,前后是两面落地玻璃,整个琴房变得十分通透加上整体浅色系配色增添了不少高级感(除了Logo实在太丑),但缺陷自然是隐私感不足,只有一面玻璃配备了窗帘,人流量大的区域新手完全不敢去练琴,简直大型社死现场,同时这个设计并没有考虑隔音效果,未贴吸音棉,这对于附近有住户的地方来说,免不了口诛笔伐,空调方面是最下血本的,采用的是格力的分体式空调(像我们美的分体空调都不敢买全新的,二手的都还嫌贵,没办法公司缺钱),内部放置了遥控器,用户端方面又又又是微信小程序,体验一样很差,水平基本处于雨果和弹司令之间,依然存在重单问题。琴房前期铺设速度也很快,但疫情之后就停止扩张了,2021年的情况是32台琴房离线了22台,离线的原因估计和弹司令比较接近。
这三家的情况分析下来,疫情过后基本都奄奄一息,都尝试过共享琴房的种种战略可能,每种战略都有成功的可能性,但在此之前是有诸多条件的,哪怕哪一环没走对都是致命的,资金不足、无自研能力、天不时地不利人不和等等都会随时卡脖子。琴小站有决胜希望的可能,但这是一个非常悠久的过程,我加入也许就是加快这个过程而已。
万金油
产品经理还在画原型图,设计师也还在设计新版小程序的页面,距离重构开始还有一段时间,这段时间里就不断的根据新增的需求更改老系统和页面以及修复现有的各种BUG。
比如发现经常有用户反馈支付了但订单没有生效,第一反应就是后台只做了支付回调处理但没有主动查单,当支付回调请求因为网络问题未能及时到达服务器或者处理失败,就会导致订单状态一直处于未支付状态,为解决这个问题用Node.js先写了个查单队列,确保订单状态能够及时更新。
或是发生了上面竞品分析所描述过的不同用户重单问题,两个用户都成功预订了同个时段,这时必然引发用户投诉,前期比较少发生是因为用户量少所以很难同时抢占同时段,为了解决这个问题就加入了应用锁,将预约请求串行化,并发时需要等待先入用户下完单,才能到自己,这时检查到已经存在该时段订单就返回已被预约。
顺便解决各种琴房硬件问题,比如各种设备的电源适配器应该用什么规格、控制板出现了奇怪的行为应该怎么判断和解决、门锁锁不上或者锁住不开该怎么解决、监控离线是什么情况、线路接完后无法开闸持续跳闸是什么原因等等,或者干脆去一趟现场调试,瞬间就兼职了电工,妥妥的万金油,哪里有问题放过去就能见效。
预言家
公司来了一位客人,在隔间外面的茶具桌上和老板聊得很欢,隔间门没有关上,我眼神较好看得出对方着装应该是一名风水大师,也许刚建立的公司都需要请大师过来琢磨一下风水,我个人是不咋信风水的,大师聊罢遍离开了,这之后老板跟我重述了一句大师的话:“这房间里那个小伙看面相就是对公司发展非常重要的人才”,我当时也就听听作罢,不过之后的经历确实或多或少的帮助着公司的发展,我有时在思考,是否这句话给潜意识里种入了帮助公司发展的信念而导致了后面的果,不然我为何还愿意坚持留下来这么久,我想不通,如果是我自己的信念让我坚持那未免显得有点傻。
网络铺设
很快就迎来了2019年,这一年新年和往常一样,谁也还想不到会有一场新冠疫情席卷全球,年后回到公司时新办公区也开始装修,拉网络自然是少不了的,但老板说不想重新办宽带继续共用原来办公室的宽带省点费用,也就是说原来的光猫还不能迁过去,那这难度就很大了,新旧办公室相隔接近三十米,新办公区分为四个房间和一个中央办公区以及一个卫生间,四个房间分别是研发部、财务室、接待室、总裁室,办公室所有网线最后都集合捆扎到了接待室的窗边,于是我到五金店先买了三十五米的超五类网线,然后上京东买了几个五口百兆迷你交换机和一台TP的双频路由器、网线测试仪、一盒水晶头、压接钳,公司的宽带速率只有百兆对交换机就没有太高要求,准备搭条跨空大桥,先将网线两端按照T568B线序(橙白橙绿白蓝蓝白绿棕白棕,之前在工作室压接网线时背的顺口溜)压接,然后用测试仪确认压接正确,接着前往屋顶把网线一端下放到旧办公室窗口让同事接上旧路由器的LAN口,为了掌握主控权所以把这台旧路由的DHCP分配关掉变成一台交换机和AP,光猫的DHCP和拨号也是关闭的,准备由新办公区的路由器来负责分配和管理IP地址以及拨号,然后用绳子吊着网线另一端拉到新办公区的接待室窗口,让同事将网线插入到交换机上,并一一用标签纸标明每根网线对应的网口位置然后插入到交换机中,中央办公区只有两个网口,其中一个就接入的路由器的WAN口,并从LAN口扩展出了两条六米网线分别接到了两台交换机上,后面就只需要给各自的设备接入网线即可,但是至关重要的宽带账号和密码谁都不记得了,只知道肯定存在旧路由内,我从其它同事的电脑的浏览器密码记录中找到登入该路由器的管理密码,登录后通过备份路由器配置的功能得到了备份文件,成功从备份文件中获得了宽带账号和密码,接着让新路由器负责拨号,至此新旧办公区就完成联网了,直到很久以后宽带升级时才将光猫迁移过去新办公区。
装修完毕后我也搬过去那边,最开始时工位就在老板办公室旁边,下图是一年半后的样子,研发部的房间原本是公司副总的位置,后面由于公司市场部增员,外面中央办公区就全部给了市场部门,我和设计师就转进了研发部。
电磁锁
随着琴房的铺设数量增多,琴房使用的电插锁存在的问题也逐渐暴露了出来,出现开门时锁舌被卡住缩不回去要推拉一下才能开启或者锁舌未卡进门夹槽等问题,曾出现有用户被关在里面按开门开关虽然控制板有反应但锁舌无法被缩回,尝试了很多次才成功出来,为了解决这些问题我提出更换为电磁锁,电磁锁无需物理锁舌,仅依靠通电获得巨大的磁力,通过吸附安装在门上的铁板达到锁定目的。
最主要缺点自然是受到磁力量限制如果外部拉力超过负荷依然可以被开启,所以才会经常看见壮一点的小伙单手就能把使用电磁锁的门直接拉开,但这种情况一般是锁体本身可承受的力量太低,市面上可以看见常见的有180KG、280KG、380KG等规格的磁力锁,或是因为铁板未和磁力锁大面积接触,这样是无法获得锁标称规格吸力的,很容易被拉开,还有可能是磁力锁供电电压不足,也不排除真是大力出奇迹。磁力锁普遍都有一颗LED灯由于显示锁状态,比如红灯代表未吸合或未完全吸合铁板,绿灯代表完全吸合铁板获得标称吸力,不亮代表未通电解锁。
在大概估量后,决定全采购280KG吸力的带反馈的磁力锁,实测用双手是完全无法拉开门的,甚至用肩膀从内往外冲撞也是分文不动,就是怕钢化玻璃给撞碎了,这个规格的锁在之后的应用中均未出现可以被人为拉开的情况。由于是玻璃门所以还得买配套的玻璃门夹,这种门夹的长度一个顶电插锁门夹三个,所以稳固程度也进一步提升,磁力锁与电插锁一样断电后会自动解锁,虽然磁力锁会导致铁板短暂磁化导致还存在残余吸力,但铁板上存在一个小个圆形白色凸起物,里面是弹簧,确保在存在残余磁力时门依然可以很容易推拉开。
在确定磁力锁可代替电插锁后就要处理控制板上的接入问题了,发现两类锁体都采用同样的工作电压,那也就是可以通用了,门锁信号方面电插锁带反馈是四线的电磁锁带反馈是五线的,除了电源线正负极外,电插锁有常闭端和公共端两条线,电磁锁有常闭端、常开端、公共端三条线,也就是说需要门锁信号方面电磁锁只需要接四根线就可以了,不过可以确定的是这块控制板上并没有实现门锁信号上报,不明意义所在,但还是照样接上信号线吧,先在办公室先测试没问题就可以准备全面取代电插锁了。
临时方案
众所周知,广东只存在两个季节:夏季和秋季,随着年后气温迅速回升,空调无法调控的问题日益明显,放置遥控器的方案已不靠谱,决定将空调的遥控板从顶上拉到琴房内墙面固定,但也并非长久之计,因为这样依然无法在线上完成空调的调控,也无法确定空调是否已开启,房间室温也是无法在线上获知的,但还是暂时解决了燃眉之急,后面肯定还是重点解决的关键问题。
应急方案虽好但不是最好的,打补丁式的处理方法迟早会暴露弊端,不过现实总有一些特殊情况,比如固定屏幕的角铁用光了,工厂定制还需要一段时间才能到货,这时只要想解决大家还是会有各种办法的,比如找其它铁片作为固定支架↓。
或是在配送钢琴进不去电梯时,方法总比困难多:
日报生成器
老板要求大家特别是市场部每天要在群里发日报汇报一下今日工作情况,大家都照做了,但总会有打错时间、复制别人时忘改部分信息、排版错乱等问题,一天晚上闲来无事就在手机上写代码做了个日报生成器,无需填写时间和相关词汇自动生成,支持换行自动排序号、自动保存上次填写内容等,使用这个工具可以确保发出标准的日报,做好后放到了服务器上并提供了对应链接的二维码发到了公司群里。
新外观
我们都明白,现有的琴房外观与其它竞品或K歌房过于相似,放在公共场所不够吸引人,加上与弹司令打外观专利官司等综合原因之下我们很早就开始着手重新设计琴房外观,在兼具美观的同时还要尽量压低成本,最初还没有一个特定的方向,最搞笑的莫过于工厂做出了一个像保安亭的样品,当场把我们一众人丑到了。
不过很快设计师就找到了些许灵感,出了几个效果图,经过大家筛选确定下来外观造型,但建模和实际生产是有很大区别的,某些造型是工厂的折弯机做不出来或是对工艺有较高要求的,比如圆弧框架、圆弧玻璃,这些如果实现将会导致成本(如开模费用)大幅提高,因此最终生产稿还是做了很多权衡调整的,比如圆弧部位改为折角,不过从出效果图到实际投产中间隔了很长一段时间,因为一个产品当然不能止有空壳,旧琴房的那套设备很明显已经不能直接照搬过来使用,在无借鉴方案的情况下需要重新规划整个琴房产品,这就是后话了。
服务器磁盘扩容
在周日的清晨,刚醒来刷完牙洗完脸,就看见公司群里有人在问怎么C端小程序进不去了,我先是脑袋一懵,把所有导致服务宕机的的可能都过了一遍,同时赶紧把笔记本电脑拿了出来,在电脑上打开了MobaXterm开始登录服务器查看情况,起初我没有察觉到任何问题,看了下服务进程都有在运行,然后去看了一眼日志,惊奇的发现日志文件已经把50GB的系统磁盘挤满了,旧系统光日志文件就积累了二十多GB,赶紧将日志文件清除并将PHP-FPM重启一遍后终于是恢复了正常,尽管写工具定期清理日志文件,但长期以往也不是办法,增加数据盘成本也是比较高的,所以决定先扩容系统盘。
本来以为在控制台对系统盘进行扩容是立即就能生效的,结果扩容30GB后发现磁盘实际容量并没有扩容成功,重启也是无效的,过了一会想明白控制台操作的扩容只是扩大磁盘容量,但文件系统还未完成扩容,这让我联想起在重装Windows系统时对磁盘进行分区管理与这个也是同个原理。
通过 fdisk -l
命令可以看到系统盘 /dev/vda
确实是扩容了,根据阿里云的文档文件系统扩容需要先卸载主分区,但很明显这上面跑着一堆服务自然是没法直接卸除的而且当时不知道 /dev/mapper/vgxxx
分区逻辑卷以为跟 /dev/vda1
这类一样,各种卸载无效。
1 | [root@host ~]# umount /dev/mapper/vgxxx |
然后仔细去了解了 /dev/mapper 和常见的 /dev/vda 这类文件系统的区别,才知道数据盘是使用LVM,接着就开始研究LVM扩容并在服务器安装LVM工具
首先在系统盘 /dev/vda
上创建一个新分区,由于已经存在vda1所以新建分区号应该为2,执行 fdisk /dev/vda
并依次执行:
1 | [root@host ~]# fdisk /dev/vdb |
这里报了一个设备繁忙的WANING,使用 partprobe 重读分区表即可(partprobe可以修改kernel中分区表,使kernel重新读取分区表。 因此,使用该命令就可以创建分区并且在不重新启动机器的情况下系统能够识别这些分区),接着只需要使用 mkfs -t ext3 /dev/vda2
格式化新建的分区 /dev/vda2
,不过这只是创建了一个新增容量的分区,还没有完成原分区的扩容。
使用 pvcreate
命令创建PV并使用 vgextend
命令扩容VG vgxxx
,接着可以使用 lvdisplay
查看已存在的LV信息获得LV Name,之后就可以用 lvextend
将100%的空闲空间全部用于扩容。
1 | [root@host ~]# pvcreate /dev/vda2 |
最后一步再使用 resize2fs
重设文件系统大小即可完成LVM扩容,通过 df -h
也可以看到已经扩容成功了。
1 | [root@host ~]# resize2fs /dev/mapper/vgxxx-lvxxx |
现在想起来整个过程也还是有点胆战心惊,生怕因为操作失误导致宕机,这也深度的反映了许多后端都说自己会运维,但实际运维需要面临的事情和压力比他们想象中的要多得多,也算给我上了一堂课。
手机就是电脑
很久以来,手机在我这的角色一直都不只是一台手机,它在需要的时候完全可以像电脑那样参与办公,当我不在电脑前的时候,一旦有什么需要处理的事情,我都会用手机通过远程桌面连接到公司电脑或通过JuiceSSH工具登录服务器,绝大部分小问题都可以通过这种方式获得解决,或者刚上线一个功能后就下班了,在公交车上时就会习惯的登上服务器看实时日志,一旦发现不对劲的地方赶紧在线vim改完,这样虽然很随意但只有我一个人实在没有测试和上线流程,还可以通过RemoteADB工具进入同内网开放5555端口的安卓设备运行命令等等,在我离职以前,带着手机一直是24小时oncall状态,群里和私聊消息也是第一时间处理,正常情况下,接听和回复最长不会超过6秒,如果遇上项目线上的紧急问题,没有电脑时手机就是第一战场。
重构产品
在开会确定下产品原型后就开始重构了,产品共经历了两次大重构,这是首次,本次重构主要目标是重构C端小程序、重构后端API服务并接入现有硬件云,所谓重构是彻底从零开始开发,并且不能干扰现有业务,也就意味着先要分批迭代上线是不允许的,必须一次成型且不能存在重大BUG,同时还涉及旧数据迁移与接入,目前为止依然是独自一人,未招聘其它开发,因此进度是比较缓慢的,不过经常忙着就有其它事需要我去帮忙处理,等回到工位又需要时间回到状态,中间催得也比较急,为了赶工期经常熬夜或者干脆通宵,早上再晚些去公司,黑眼圈日益严重,女友已经想掐死老板,甚至过来公司谈业务的客户看到我的黑眼圈都在向老板提出担忧,本次重构工期大概持续接近3个月。
好在努力并没有白费,6月份上线时各项数据相比之前翻了两倍,用户体验有所提升。
C端小程序方面根据原型和设计图并且结合自己总结的体验优化进行原生开发,在小程序这种两天一小改三天一大改的环境下,使用框架反而是一种阻碍,凭借着之前翻得烂熟的小程序文档基本没有遇到难题,唯一花了些时间与心思的就是自由的时段选择机制,后台可以以M分钟为步进生成N个T时长时段,比如以5分钟为步进以当前时间为基准生成今日0点之前的所有可用的30/45/60/90分钟时长时段,这将提供给用户最大的选择自由,比如它可以选择在12:05-12:35使用也可以选择在12:10-12:40使用而非单纯的以30分钟为步进,选择时如果当前选择时段与前后的部分时段重合也会将该部分时段置灰,支持现在使用和预约未来时间使用,现在使用将以当前时间推算,未来预约则是根据下个整5分钟时段推算,如果距离下个被预约时段还有充足时长依然需要提供选择,或者不足时长将会裁剪时长直到某个阈值但依然按照原时长收费,通过这些规则让时段选择相较竞品体验上升了一个档次。
另外印象比较深的是微信官方发布公告要求新上线小程序均不能打开小程序直接索取用户信息,而需要先让用户体验部分功能在需要时才索取,个人观点认为这对于用户体验无疑是一项巨大的提升,也在一定程度上减轻了小程序劣币驱逐良币的趋势,体验太差内容不是自己想要的干脆就不给授权,因此我将授权关口放置在了需要访问个人信息和琴房预约的位置。手机号绑定方面与之前有所不同,之前旧程序采用的是外包公司所使用的第三方短信平台,该平台短信服务质量堪忧,到达率低延迟久,导致错失了许多用户,刚好小程序开放了获取手机号码的API,用户可以直接授权手机号码或绑定新的手机号码,用户体验与成功率都提高了,运营还要求绑定时赠送100元余额促进绑定。发现大部分小程序开发者没有处理好二次进入的自动登录的问题,经常都是token失效后要求用户再次点击登录或是每次进入页面都先完成登录再继续提供服务,其实真正的自动登录应当做到用户无感知,我决定将自动登录融入到请求中,不是所有接口都需要鉴权的,而需要鉴权的接口在访问时如果服务器发现token失效则返回失效,这时小程序端应当采用Promise等待自动登录完成后无感知的自动重试登录之前的请求,在用户角度看来,就只是这项操作稍微慢了一点而已,并不会意识到刚刚发生了一次登录行为。
后端方面小程序API和后台系统几乎是耦合在一起的,存在许多共用接口,小程序中与硬件相关交互更是绕过主系统直接调用机器云,我打算将两部分小程序与后台业务分离开来,先采用Node.js基于Koa2开发专用于RESTful API的框架,采用路由件、处理件、数据件三层分离的方式处理接口数据,路由件负责过滤、校验、预处理请求参数并调用处理件方法和返回响应,处理件负责对数据进行相应处理并调用数据件进行具体数据操作和返回结果,数据件负责进行数据在Redis和MySQL间的CURD,由于当时时间关系并没来得及封装数据实体对象,所以数据件比较简易,并且给小程序端和接口都套上之前所说的RSA+AES混合加密,实际上这给调试带来了不少麻烦,其实微信小程序强制使用HTTPS协议已经是相对安全的了,接着把鉴权机制做好,统一响应格式以及响应错误码和对应信息,再把业务接口陆续补充完整,将原子业务如支付与扣款做好锁和事务封装,对接原来的硬件云让小程序端所有的硬件操作都需要通过本服务处理,支付方面彻底解决重单、漏单的问题,整体模块设计方面均预留了充足的扩展余地以便应对经常变更的需求,老板很容易一拍脑袋就下决定,所以后路还是要留充足一点,并且实现了模块热更新,可以在不重启服务的情况下直接替换模块缓存,这样可以实现无感更新,pm2虽然提供了watch模式但会导致服务重启,虽然很快但还是存在无服务间隙。架构上就没啥好说了,用户量预计几年内都很难有较大增长加上节省成本,就在CentOS系统的服务器上大概搭了下环境,使用Nginx主要负责服务与SSL代理以及一般静态文件访问,连负载均衡都用不上,静态文件方面再结合上CDN和OSS可以彻底搞定,然后就是Redis负责缓存用户session和各种缓存数据、热点数据后期也用到发布订阅通道,自然也是用不上集群单机足矣,并且考虑到存取逻辑较为简单也很少涉及原子操作就没有用到lua脚本,持久层则继续采用MySQL。
不过遗憾的是,当时着急上线C端后台系统却已来不及重构,因为之前的后台系统与API服务是完全耦合的,重构后端就当于直接放弃原有后台系统,这直接导致的是我将在很长时间里负担起大量人工后台操作,比如订单取消退款、新增或修改琴房信息、查订单信息等等,浪费了许多时间。
自从碰了这个项目开始,时间戳就如鬼魅一般一直伴随在我左右,太多涉及时间戳的处理与判断的逻辑了,导致对于时间的敏感性大大提高,比如看到3600会自然想到60分钟,看到900会自然想到15分钟
一元弹琴
运营提出了新的需求想要实现一个“一元弹琴”的活动,可以只花1元就能预约琴房30分钟还允许叠加,并且这个活动只有在每天的某个时段内有效,而且工作日与双休日的限制时段也不同,活动未来还会随时停止,其实当时想着还不如出一个活动和卡券系统,这样以减免的方式会合适一点,但一想到后台系统还没重构就头大,干脆先在现有服务硬编码了,逻辑上没啥难度主要是这个活动实在太BUG了,可以叠加意味着花很低的价格就可以承包整个优惠时段,也由于缺乏一些指引,导致部分用户并不清楚规则,主要的规则描述也只是屏幕上的一元弹琴轮播图片,等用户们都搞明白也适应规则后活动戛然而止时引发了不少用户投诉。
智能钢琴
老板也许是看上了竞品雨果琴房里的智能钢琴,找到了研发这款钢琴外设的公司,并叫上我和何哥一起过去瞧瞧看看有什么可以学习借鉴的地方,其实在此之前已经有接触过与之相似做钢琴外设和配套软件的公司,但他们提供的外设比较落后,那是一根黑色带有一排凸起的长条状物体,每个凸起物是对应钢琴弦槌的红外测距器,整根可以卡在钢琴顶盖内击弦机上方的位置,在弹琴击弦时弦槌会移动到对应位置的红外测距器前,这时就可以捕捉到按键信号,不过这还得配合上驱动和软件,配套软件是偏卡通化的,对方提供的软件是只能在iOS系统运行的,因此如果采用那设备成本肯定不低,于是谢绝了,而且红外测距的方式其实存在比较大的问题,比如灵敏度不高、无法判断击键的力度,就算采用它这套外设,我们还得做驱动移植和配套软件开发,种种难度之下就放弃与他们的合作了。
这次过来看的这款智能钢琴的外设就要好很多,采用的是键盘下光电传感器,这种方式不仅可以获知琴键是否被按下也能够推算出按键力度,但缺点是需要对钢琴进行改装,除去传感器还有一项外设是一条屏幕,之所以称作一条是因为它是一个横跨所有琴键条形屏安装在原本应是琴盖的位置,稍微试了下配套软件,可以确定是一台运行Android系统的设备,将配套软件作为桌面程序直接开机启动了,包含了几个钢琴游戏、曲库、曲谱库等,功能比较简单界面简约,适合的年龄层范围更大,目前一切还算比较美好,但是价格确实难以接受,这套外设和配套软件一起需要两万多,并且还得考虑安装和对接自家程序问题,价格都要达到一个琴房的成本了,在初步商量后决定放弃,老板还在考虑自研,我当时在想这自研个锤子,步子跨大了会扯裤裆的,当即表示如果要做必须还得招聘个嵌入式Android开发,工资还不能低。
产品离职
产品经理何哥由于一些原因被老板开源节流了,据老板说产品的工资达到我的两倍以上,我不知道是否是因为老板在找我谈到何哥时我对他的目前工作状况描述得不够好,在谈话之前何哥也似乎与老板在总裁室里吵过一次架,最后他还是离开了公司,在公司没有及时发下工资知道我生活困难时他给我转过500,虽然工资发下来后马上还回去了,但还是很感谢他,后面还多少有点联系,结婚时还邀请了公司的老成员包括老板去参加婚礼,只是产品走了老板一拍脑袋的主意多半要直接砸到我和设计师头上了,毕竟许多想法主意是需要技术论证的,还要考虑成本可行性等等,老板是不愿意听见不行二字的,虽然对于我老板不会大声苛责,但也往往都是能实现的尽量实现难以实现的会折中委婉处理并告知可能面临的问题和风险,产品在许多时候不是给程序员添乱,也许是一堵防火墙,用于隔离开天马行空和不切实际的想法,尽量提供可行的方案。
重构广告机
线下琴房开始出现越来越多因U盘过热无法读取、安卓盒子过热宕机导致的屏幕广告无法显示黑屏的问题,并且随着各种运营活动的上下线,对于广告机所播放广告的时效性有了更高的要求,琴房也比只多不少,分布地区更是好几个,让人跑去换U盘已经不实际了,急需一个可以在线上发布广告的广告机,在这样的背景下,虽然我已经很早就要求招聘Android嵌入式开发,但给的薪资实属寒碜:5-8K,好不容易有过来面试的结果还都是培训机构出来的,应届生经验也是完全不足,一狠心算了,我自己做,智能钢琴我是没精力做,但是这么个广告程序还是没问题的。
脑子里开始回想起以前写Android的记忆,不过Eclipse+ADT插件的时代已经彻底过去,Android Studio这款IDE才是主流,所以马上就开始下载IDE并安装SDK和相关组件以及镜像,就这样在几乎没有经验的情况下开始了广告机的开发,Android Studio当时已经支持使用Kotlin语言,虽然彼时Google还没有将Kotlin推举为Android开发官方语言,但也是风头正盛的状态,对于Kotlin我不能说不太了解,只能说是一无所知,为了保险我还是先选择了Java,直到后期广告机二次重构时才选择了Kotlin,使用Android Studio开发的感觉是Eclipse所达不到的,丰富而准确的语法提示,代码补全也相对更好,在调试方面更加方便。
想着公司现在搬来的这台机子性能有限,内存还给核显吃掉1GB,怕跑不动,之前那台惨遭嫌弃的游戏本正放在出租屋里用,游戏本配置还是很可以的,所以跟老板申请一周不来公司在家办公完成广告机程序顺便还能省下来回公司的时间,老板同意了。
这一周自然也是完全没偷懒,旧广告机程序源码是没有的,但该程序确实十分粗糙,它只读取包含上下轮播图拼合的图片和中间的视频文件,我决定将广告播放的资源切为顶中底三类,分为顶部轮播图、中部轮播视频、底部轮播图,这样播放上下轮播的逻辑就可以完全错开了,上部轮播图往往都比下部轮播图多,所以分离很有必要,除此之外二维码也是单独分离显示的,这样就不用为了不同琴房制作不同的底部轮播图,大大降低人工成本,接下来的挑战就是与服务器的连接,采用的是主动注册的方式,广告程序首次启动时会等待联网,联网后会向服务器发起注册请求,服务器允许注册后程序将进入轮询广告数据状态,当服务器存在与它绑定的广告数据时它就会解析数据并下载对应资源到存储目录中,存储完成后将自动开始播放,顶部和底部轮播图的切换间隔是由广告数据决定的,视频则是播放完毕时自动切换到下一个,另外还会定时向服务器发送心跳请求和获取新广告请求,心跳用于保活让服务器知道广告机是否在线,当存在新广告时广告机会下载新的广告文件并存储与当前广告ID的目录中不会与旧广告文件发生冲突,下载完毕后程序则切换到最新广告播放,旧的广告数据将被移除,其中比较核心的是耗时处理不能放在UI线程需要另起线程或使用协程,否则会导致画面渲染卡顿甚至ANR,很快就完成了开发工作,但在测试时发现运行了几个小时后崩溃挂掉了,使用Profiler检查后发现是一个请求对象没有释放导致内存泄露,修复后就解决了。刚好手上还有一台山寨平板,虽然屏幕有点短,拿来测试还是不错的,打开USB调试连上了它,在经过模拟器+实机连续一天半的测试后确认没有出现问题。
第二天就拿着成品前往公司测试打包,命名为琴小站广告组件,至此终于摆脱了以往线下广告更换难、广告图制作麻烦、广告机在线状态未知等问题,并且开始给安卓盒子安装替换原有广告程序,同时为了监控播放状态还安装了TeamViewer,针对安装流程顺便做了个CLI。
但正如上面所说实际上这是第一次重构广告机,意味着后续还出现了一些问题,我自知这次开发得过于赶进度了,仅花了三天半,有很多优化点没有做,比如安全性是比较低的,连请求防篡改的机制也没有,并且使用了实时性比较差的轮询请求,按理应该使用WebSocket或TCP等其它实时传输连接协议,并且注册机制是比较简陋的,暂时也没有后台系统可以用于广告机的管理和上传广告文件,还有一项很重要的文件有效性和格式校验没有做,以及轮播图的切换部分没有开协程处理,在切换大图时会对UI线程造成短暂阻塞,看上去就是视频卡了几十ms。
这些问题附带着比之前更多的问题压到我身上,比如在我重构出后台系统之前所有的广告机信息都需要手动管理,广告的图片或视频也还得我手动上传和检验,给到我的图片经常会出现过大或尺寸不符,视频也是经常过大,这时如果设计师忙我就得自己压缩一遍,通过网络下载广告文件到广告机意味着对琴房的路由器网络有较高要求,如果文件资源过大,下载耗时就会更长,偏偏许多琴房的所用的“工业级”路由器网络性能并不佳或是碰上财务没有及时给流量卡续费的情况就加剧了这种情况,在没有写自己用的自动化上传工具之前,文件上传下载无校验这块吃了亏,因为失误错把图片链接作为视频链接一起推送给了广告机,广告机也不校验文件类型直接下载并且播放,自然是无法正常播放的,或是链接缺失一部分被推送过去,直接返回下载更新失败,但却不知道是哪个文件有问题,这就是缺失管理系统和终端验证的巨大危害,后面还出现了更奇葩的问题,我们发现部分广告机在长时间运行后会出现中间视频不播放的情况,表现为中间黑屏但其它的正常播放,视频采用的是VideoView组件,在办公室不论如何测试都无法复现,仅在线下琴房一段时间后突然发生,未检测到内存泄露,猜测可能是VideoView因为某些原因被回收掉了,寻找了许多资料都未能确定具体原因,幸好之前安装了TeamViewer可以远程重启广告程序恢复,不过在第二次重构时实现继承TextureView的VideoTextureView解决了该问题,这所有的经历持续了很长一段时间,像一场悠长的噩梦。
监控直播接入
之前所说的网络摄像头麻烦也不少,总有人去拨弄云台,导致拍摄方向不正确,更有甚者把内存卡或者摄像头都给拿走了,加上没有云存储,导致需要查看时往往都没法获得关键信息,属于防君子不防小人,而且没有提供开放平台,这样的话我们无法将监控直播接入到自己的平台,所有人还得另外下APP,安装时也没有插网线只连Wifi,导致传输有些不稳定。
起初是希望在不替换现有摄像头方案的情况下给摄像头价格半球型罩子,就像大家在电梯或地铁里常见的那种监控遮罩一样,主要目的就是防止直接接触摄像头,于是和设计师前往了华强北,搜寻各种摄像头遮罩,也不是没有,但是很少,就算有但也很小,不大可能遮住这么大个摄像头云台,就算把摄像头半截身子塞到天花顶上,也是很难实现的。
后面的还在更新中,敬请期待。
RK3288主板
采购了一批RK3288的安卓主板,这是用于替换原本的安卓盒子,不过如果只是为了播放广告是无需使用这个相对高配主板的,主要是为未来实现上面提到过的“天马行空”方案做了预备,毕竟要同时带起条形屏+广告屏还要负担一些软件运行对硬件是一次不小的考验,
B端小程序
电工
续费风波
重点区域
疯狂跳闸
路由器
进军海南
觅跑改琴房
停卡风波
地图爬取
动态抠绿幕
疫情来临
空调导风
误打误撞PLC
STM32
控制板初代机
逻辑分析仪
空调遥控
NB网络
4G Cat.1
设计控制板
焊接控制板
编写控制板固件
调试控制板固件
开门续期
断网重连
红外编码定义
下载器