距离上一篇博文有一个月之久了,距离上次编写代码也有一周之久了,由于疫情的全面放开,加上福建省教育厅通知的提前返乡,反而让我感到有些不适。往常这个时间点我忙于期末考试,会把代码的事情放一边,等到彻底放假后,开始闭关潜心学习。然而剩余的半个月变成了线上形式,课还是要上,考试还是要考,虽说身在家乡,但心不在焉的 😂。
12 月已过半,也是时候该写年终总结了。迄今为止,我已学习了 3 年半的编程。(还好不是两年半),当下的技术不再是当初只会易语言的小伙了。只是当下已没有当初如此强烈的热情与精力了,我称之为老了。
现在回头回顾学习编程时间,用一个成语对自己做个评价——差强人意。在这些时间段,我其实荒废过一段时间,厌倦过,贪玩过,荒废过,从我的 Github 热力图 中其实就能看得出来。就导致欠下技术的,都需要后续花时间去弥补。
要让自己保持每天都处于学习状态真的太难了 😩,生活总有源源不断的琐事打扰着你。在忙碌的时候总是感觉时间不够用,哪怕有时一天花费了数十个小时,也总感觉做的事情太少了;哪怕每天计划都规划得好好的,但总是有一半还未完成。生活中大量的碎片化时间,而编程学习最不需要的就是这些碎片化时间。
回顾整个编程生涯有太多可感慨的,整个旅途几乎是一个人走完的,期间遇到的坎坷就只得依靠搜索引擎来解决,搜索引擎是我再生父母都不为过。没有人给我指引明确的道路,只依靠心中对技术的憧憬不断前行。走过低谷,登过山峰,而如今站稳身子就足矣。
感叹的话语也就是说到这。今年主要总结我为何从逆向转 Web 开发,并明确我未来所要走的方向,也是本文的主题。仅作为个人感悟,不作为建议参考。
为什么要写年终总结
先回答一个问题,为什么要写年终总结?
我从高中开始,每年都会记录这一年所发生的比较有印象的事情并写下自己的感悟。所以写年终算是个人习惯,并且我希望能够一直坚持下去,写到不能写为止。
写年终总结是个非常好的自我总结与反思的方式,总结这一年自身的变化,有哪些精彩与满足,有哪些遗憾和不足。同时定制明年的规划,以该目标不断前行,而不是漫无目的地活着,就失去了很多人生的意义。
同时也算是自我评价与建议,很多时候我们会收到很多别人有关自己的评价与建议,可人总会对他人有莫名的排斥感,就难以虚心听从他人的建议,从而犯错许多(说的是我就对了)。年终总结还有个作用就是弥补自己对某件事情未来可能要发生的情况,要如何做到不犯错,预先有个明确的预防意识。
即便可能要花数天的周期去回顾与总结,我也很愿意去总结,我常说回顾过去,就是在仰望未来。写年终所做的也就是这个过程。
写年终总结也算是种分享,分享自己的开发经历,当他人阅读时或许有所启发。
过去的,就过去了,别将当下的遗憾留到未来,这就是年终的最大意义。
为什么是 Web 开发?而不是逆向
今年大部分的开发时间都花在 Web 开发上,在此期间也接触到许多技术,并通过博客笔记的方式记录下来。
我很庆幸我的 Web 开发从一个 Beginner 到 Intermediate,现在回忆整个学习路程,一路学得都很野很随意,从未系统学习过,总是学到一半,就自认为已经掌握了,便开始进行实战项目,可以说很多知识都是在实战探索中了解的。
虽然很多人都直称我为大佬,但我离 Advanced 还有一大段的路途要走,而这段路途是无比的艰难与漫长。不过好在路不歪,只要肯走终会到达终点 👨🦲。
而带我入门的逆向技术,在今年没有丝毫的长进,说得过分点,就是弃坑了。也正如标题所说,至于缘由,细看下文。
逆向
熟悉我的人应该知道我之前是做爬虫与逆向分析,但是为何今年的技术栈彻底转型到 Web 开发上。
我常常和别人说起我的技术栈转型(从逆向转到开发),不过比较多的都会比较好奇我为什么不继续深造下去。
在此我也回顾了我从逆向转变到 Web 开发的过程,顺带也回答这个问题。不过在这里先说说我个人对逆向的看法:
逆向需要的技术知识面比较广。
就我接触逆向的过程来说,接触了易语言,JavaScript,Python,Java,Php 等等编程语言。
使用过了一堆的逆向工具,如 Frida、IDA、JEB、jadx 等等(我目前能想到比较有名的)。此外还有一堆知识,包括但不限于以下技术:自动化脚本、TCP/HTTP 协议、抓包、爬虫、加密学、图像识别(验证码、滑块位置)、汇编、反编译、AST 反混淆。
要我说我在逆向中学到的不是如何使用这些工具或掌握某个技能,而是锻炼出一定的阅读与分析代码能力。工具与技能总是瞬息万变,但阅读与分析代码能力却是实实在在,一成不变的,也是逆向中最值得学习的。
有接触过 CTF 想必再熟悉不过逆向工程的技术面广了。
越来越多的网站或应用程序不断加强安全防护,未来只会越来越难逆向。
逆向分析,说白话就是去看别人的代码,进行一些修改手段,达到自己想要的目的。比如修改某个软件的标题或作者信息、将别人的代码“偷”过来用、爬取某些网站或软件的数据。
但是随着现在越来越多潜在的安全问题,很多框架底层,服务厂商,都会对一些可能有安全问题的代码进行警告或者底层处理。比如使用 ORM 框架能够有效防止 SQL 注入,前端框架中涉及 XSS 攻击也会有相应的错误提示与处理,再如浏览器跨域以及跨站点 cookie 不共享,都是为了用户的安全而去考虑的。这样的例子有太多了。
简单说说安卓逆向的过程:拿到一个 Apk,发现有加壳(给代码加固让逆向者不易于看到源代码),这时候就需要通过脱壳才能查看到源代码;此时就算脱完了壳,接下来可能将面对经过混淆过的代码,这份代码难以用人眼去阅读,不调试运行,单靠静态分析很难分析出东西,这时候可能就要借助 AST 对代码进行还原;还原完了配合动静分析将代码给扣出来,而在分析的时候可能又有各种检测,比如抓包,反调试以阻碍逆向进度;最后就算逆向工作都做完了,代码也扣下来了,还要尝试运行扣完的代码,这时候极大可能还不一定能运行,然后又要回头看看到底那一步做错了。
可以说逆向的工作就是不断地调试,不断分析,最终拿到想要的结果。整个过程可以说非常耗时且折磨人,心智如果不够强大,真的容易劝退(我当下耐心也早不如当初了)。但是得到最终的目的,将非常爽,成就感爆棚,相当于一个解了几小时的题,最终被攻克的感觉。
前阵子在逆向圈中,看到过一张图,大致也把我的逆向学习流程也表达了出来,最终我的逆向学习也确实止步在 Flutter 上。
上面所说到的逆向技术中,例如加壳,代码混淆,反调试,风控等等,都是阻碍逆向手段。同样对于爬虫而已,通常会采取反爬措施,包括但不限于封 IP、封账号、JS 参数加密、代码混淆、浏览器指纹、TLS 指纹、验证等。而且防护手段可以说是越来越多,逆向的难度也就越来越大。并且在服务开发那边只需要修改一点东西,逆向可能就需要从头再来一遍。
未来逆向的难度只增不减,但薪资可不一定保证这趋势。
风险
从上面也不难看出逆向常常与安全挂钩,如果一个网站或软件不是那么好被逆向,那么间接说明安全性是比较高的。可一旦涉及到安全,同时又是互联网,就免不了网络安全与法律相关的风险。
在大多数逆向的对象(网站,软件)中,多数都是他人的劳动产物,当你未经他人允许的情况下,去爬取他人的数据,或是修改一些版权信息再次发布出来,就属于非法行为。本质和未经他人允许,偷人家的东西性质是一个样的。并且在有防护措施的情况下,绕过网站防护措施获取数据属于违背权利人意愿读取、收集数据,将有较大可能被认定为对计算机信息系统的 “侵入”。
要知道在逆向的行业中,有很多都是擦边灰产,至少我所在的逆向圈是这样的,抱着【仅供学习为参考,请勿用于非法用途】的想法做逆向工程。路子极易走歪,很少能够正常去走安全岗位的。相信你应该能看到许多类似的案件,如【某某程序员因非法侵入 xx 网站,获刑 x 年】。这不是危言耸听,目前国家对网络安全以及非法数据获取的打击力度,也将决定了这些案件将会越来越多,爬虫逆向也将会越来越邢。
自身因素
简单介绍完我认为爬虫和逆向的看法后,再来说说自身因素。
更想写代码,而不是看代码
我是很享受写代码的过程,一份高质量的代码会让人赏心悦目。我为此特意学习下设计模式、重构技巧以及 TDD 测试。这些在逆向中基本难以涉及,但是这些对开发的体验和代码的健壮性都是非常重要的,也是让我个人觉得技术有所提升的技能点。
在逆向分析中,大部分时间都不是在写代码而是在看(分析)代码,而反编译出来的代码,很有可能是带有混淆过的代码,而你想要分析这一块代码的作用,只能去一步步调试,将代码啃下来,从而推断运行时某变量的值,或是某个函数的作用。
虽然说开发岗位中,有很多情况下也是在看代码的日子中度过的,但相比反编译阅读代码而言,至少不至于那么晦涩难懂。
更想碰新技术,而不是旧技术
其次,在逆向分析中,遇到的网站或软件所用的技术一般都是较为稳定成熟的技术,而这些技术往往不是很新,因此需要去了解很多旧的技术,但这些旧技术仅仅只对逆向分析有用,甚至过段时间很有可能就会遗忘。并且要了解的旧技术还不少,学得将会特别杂。
而我又是一个喜新厌旧的人,对任何新鲜事物都抱有好奇尝试的态度。我终将认为旧的技术被淘汰是迟早的问题,新技术的出现肯定不是无缘无故的出现,必然是为了解决某些问题而诞生的,如性能,开发体验,安全等等。
这里有篇我对新技术的看法,推荐阅读一番。[深谈个人对新技术的看法 - 愧怍的小站 (kuizuo.cn)](https://kuizuo.cn/talk-new-technologies-opinion'深谈个人对新技术的看法 - 愧怍的小站 (kuizuo.cn)')
更想开源,而不是闭源
在逆向开发,不,是在灰产开发中,有很多代码是别指望开源出来的,这背后会涉及到商业利益或是版权等问题。一旦代码放出来,将意味着你的代码将有很大的可能被别人利用做坏事,最终甚至祸及到自己。所以大多数情况下,你多半只能将自己的应用发布出去,而不是将源码开源,通常也就带有商业化的性质。
我想任何开发者肯定是希望自己的代码走的更远,走的正规,而不是被拿来做违背自身意愿的事情。
开源不仅能为自己提升一些技术知名度,展现自身技术的一面,同时代码被他人使用与认可,这番成就感就足够继续坚持开源下去。因为我有很多技术都是通过开源项目中学到的,所以我能感受到开源带来的魅力,也是对于前人的崇拜,想走开源的原因。
因为淋过雨,所以很想为别人撑把伞
小结
其实在今年出头我还特意复习了一波安卓逆向,为了更深入了解了更底层的知识与工具(当然现在忘得也差不多了),因一些特殊原因我的电子设备不在了,别问,问就是坏了到现在还没修好。就导致我的编程语言环境,逆向工具,虚拟机配置,代码等数据直接灰飞烟灭,也让我停滞了 1 个月的学习。
我想这才是我从逆向转 Web 开发的最重要的理由了。
逆向的学习对我开发有很大的帮助。例如开发中的安全问题,我在开发中都会时刻考虑去考虑该问题。如加壳、SQL 注入、代码混淆、接口限流、接口幂等性(Fiddle R 包)等等安全性问题。
我庆幸我学过逆向,让我学到很多在开发中比较难学到的技能,如调试,阅读源码,而这些也是绝大多数 Web 开发者都欠缺的能力。
逆向应该就暂以告终,未来会有很长的一段时间,甚至以后不再接触深入专研逆向。
每当回想,【当时那么难的加密算法都能搞得定,开发一个功能还能有多难】,保持着这种心态,也让我保持着开发。
也是逆向激起我对编程的兴趣,可以说没有接触逆向开发,我也不太可能会接触到 Web 开发。
但 Web 开发就一定好吗?
上面对逆向的看法仅个人分析而言,但是 Web 开发就一定好吗?我不敢下绝对的肯定,不同人不一定适合相同的技术,但是我特别看好 Web 技术(尤其是 JavaScript,偏前端向),以下是我看好的点。
应用性广
目前仍有很多人还停留在 JavaScript 只能编写前端页面的水平,自从 Node.js 问世,目前绝大多数的应用都可以使用 JavaScript 进行编写。
换句话说,只要你会 JavaScript 就可以编写很多应用了。有个在国外经常被应用的一条和 JavaScript 有关系的著名定律:
Atwood 定律:任何可以用 JavaScript 编写的应用程序,最终都会用 JavaScript 编写
Web 前端开发不用多说,目前还得用 JavaScript 来编写。而后端开发通过 Node.js 也有一己之力。近几年特别流行跨平台开发,也就是一份代码,多端运行。
使用 React Native 或是 Uniapp 这样的前端应用框架,顺带去了解一下相应平台的 API,就能够编写出安卓或 IOS 应用,做过小程序开发肯定知道小程序的技术栈就使用到前端开发的技术栈,如果你会前端开发,就能很轻松的上手小程序开发了。
并且越来越多的软件都是网页版优先,然后再通过 Electron 这样的跨平台解决方案,实现不同平台间的程序。诸如 Vscode,Typeorm 等等便是其中的佼佼者。
不过本质上都是在不同应用的平台上套浏览器的壳,然后接入一些该平台的接口,因此普遍应用的体积与内存都相对比较大,与原生相比自然是略逊与原生,不过这点性能上的差异在如今硬件升级如此普遍的物质生活也显得微不足道了。
但借助浏览器自带的跨平台性,你所编写的应用能够非常轻松的让他人访问,只需要用户有个浏览器,并且通过上述跨平台的解决方案,也能够有效的将你的 web 应用转成其他平台的应用,而不是在耗费时间与精力去编写另一套代码。
在一些技术文档上,会有 API/SDK 的支持,而绝大多数都支持使用 JavaScript/Node.js,也许该功能本身并不是使用 JavaScript 来编写的,但完全可以通过 JavaScript 来轻松调用该功能。并且如今 JavaScript 生态如此庞大,你不必担心库/包的问题,npm 作为世界上最大的开放源代码的生态系统(包管理器),在这里你几乎找得到你所想要的库/包。
此外有越来越多的第三方服务平台(通常称 Fass,函数即服务),专门提供数据接口与用户鉴权,如 firebase/supabase 或是国产的云开发产品(如小程序)。前端程序员只需要专注与业务代码,借助第三方开发平台,就能够编写一个高可用的应用。反而也映衬了,Web 开发好像可以没有后端,但必须要有前端的观念。
工作量将越来越多
这句话的意思可能有点加班那味道,但我所要表明的是可以做的事情多了,意味着你的工作量增加了,同时你的编码价值也就提升了,不过实际价值(工资)的话不一定提升,因为这主要看老板和地区。
怎么理解呢,我举几个例子。
现在大部分的 web 应用都采用前后端分离的形式,但在曾经则是由后端通过模板语言渲染成 HTML 直接返回,通过前后端分离的形式,前端只需要专注页面交互的编写,而后端只需要保证接口可靠性。并且前后端分离也有一个特别显著的特点,能非常有效的节省服务器的资源,原本服务器的渲染动作迁移至客户端来做。也许有人会说,那这样 SEO 优化该怎么办,这不就有了 Next.js、Nuxt.js 这样的 SSR(服务端渲染) 框架,而这些工作,也是前端要做的。
并且越到后面你越能感觉到客户端(前端)远比服务端(后端)做的东西来的多,比如开发阶段的数据 Mock,前端国际化,设计原型等等。之所以会有这种感觉,也许是因为我的大部分开发都是前端,这里你也可以回想当下的工作量与往年相比是多了还是不变。
技术更新快
前端真的是每隔一段时间,必定会出一些新的技术,也不由让不少前端学习者感叹真的学不动。但伴随着新的技术出现,必然会有新的岗位与机会,这也是我看好前端的一个点。
不过这种机会在国内不太多见,反而在国外特别普遍。 多的不说,自行体会。
忘记从哪看到的一句话:“前端工程师的一大焦虑:永远能(且必须要)看到大量前沿的技术,但自己手上的活儿跟不上,导致眼高手低。”
不只是前端,做技术这行的,必须要跟着技术发展的角度,并且要时刻关注最新,主流的技术。
有关 Web 开发的一些想法与感悟就写到这,其实还有蛮多可写的,比如选择 Vue 与 React?为什么是 JavaScript?有太多自我审问的话题了,不过由于当下时间相对紧迫,有机会的话再续写吧。
综上,也就是我看好 Web 技术的几个点,也回答了我未来的方向。希望这些能够帮助一些不知抉择方向的伙伴。
在实践中学习
回顾整个技术栈,基本都是在项目实践中不断学习。也许是因为逆向的缘故,因为逆向基本上都是靠实战出来的,导致我的学习路线也趋于实践。
不过在我看来,写项目是最直接能体现出所想学的技术。我在学习一门新技术时,我通常会用项目或者博文的形式来总结我的学习过程。我也乐意花时间在这上面,并将其分享出来。当有其他人也在学习这门技术时,看到该项目或博文,我就认为非常有意义。
我在学任何一门技术,会使用该技术写点东西;换言之是为了写点东西,而去学点不一样技术。
技术心态的变化
如今来看,确实没那么想写代码,尤其是那种工作量大,重复性强的代码,而编写这些代码,其实与搬砖无任何区别,本质也是重复性与劳动性的任务。
曾经可能是因为接触得比较少,对于很多软件背后的原理及实现一概不知,所以看到啥就都想写写看,最终很多项目都成为半成品。
而随着越深入的学习,反而自己所想实现的东西,前人都已经帮我们实现好了。完全可以借用前人的代码,在此基础上学习与使用,而不必从头再来,耗费很多不必要的时间。
到最后为了实现一开始所想实现的东西,不用再费尽心思,去开源社区搜寻一番,总能找到与自己所要实现的类似的产品,此时只需要会看,会改,总能达到自己最终要实现的东西,有时候自己也称为了别人口中的 CV 工程师。
也正因如此,写代码的欲望就不再那么强烈。很多自认为无意义的代码或者是以后都不一定用得上的代码就少写了许多。于是乎缺少了很多自我思考与专研的时间,虽说也确实节省了很多不必要的时间,加快最终功能的实现,但这就是自己想要的编程生活吗?或者说这就是绝大多数人的编程生活。
何来的自驱力
现在回想,是什么驱使我学习,我心中的答案是无能。
当你什么都不会时,或者是目前的能力还不足够将某件事情做好,你就会不断地焦虑,犹如热锅上的蚂蚁,想做但又怕做不好。
我有很多社会技能是欠缺的,比如人际交往,谈话技巧,合作行为等等,并且我本身也不愿去学习这些技能。正因如此,只有不断发挥自身长处,用自己所擅长的领域弥补自己的短板,以提升自我在社会的竞争力,以至于不那么容易被淘汰。
返校的一年
今年也是我重归学校的一年,倘若,去年没有休学一年的话,如今我可能已经在外实习了,转瞬一年就过去了,如今的我还沉浸在当初休学和别人创业工作的日子。
也是因为当时休学急迫,后事做得并未完善,学校的一些课程并未申请缓考,最终视为缺考,即挂科。然后此前对大学的课程也是抱着可有可无的心态,也挂了几门课程,如果不是辅导员告知,我还有 34 学分要补(20 学分为严重预警,40 学分为退学或降级处理),我都不曾了解自己在学校挂了这么多科 😂。最离谱的是有个同班同学正好就被降级处理了,不过好在今年上半年并未挂科,加上下半年也重修了一些课程,还不至于离本科毕业证书越走越远。
回到学校后,就感觉如同坐牢一般,只不过环境相对舒适一番,尤其是在疫情当下更是如此,我这一年出校玩乐的次数好像不超过 10 次。当我仔细回想一下大学的真正意义是什么?貌似就是混个日子,混个证书。我也想不出大学能够有什么实质性的作用,也许是因为我所处的学校不行,换个好一点的大学或许都不是这样了。
不过今年回学校反而去参加了曾经都不怎么看上的社团(虽然现在也差不了多少),给社团写了些项目,主要也为了给自己重返学校带点个人知名度。但因为学校不是那么有名(臭名可能有),所以这里就不便放上相关信息。
考研
明年的话我就大三下了,面对我的有条熟知的考研路。说实话,从目前来看,我对考研不抱有太大的希望,我是属于实践派的那种,我坚信没有什么是试不出来。背理论,刷八股,我很反感。
不知道由于什么原因,总感觉一段时间不写代码,真的就不会写代码。仿佛与自己写的代码成为了陌生人一般(所以写注释的重要性就体现出来了)
倘若读研的话,必然将会有数个月的时间重心不在代码上,到时候回来编写代码时,又发现自己好像又重新学了一遍似的。加之万一上岸失败的心理落差,会让自我觉得这几个月的努力都白费。而我又恰好是一位结果论者,即只在意结果,不在意过程如何。在别人的眼中,是难以看到你考研备战努力的过程,只会在意你上没上岸。这便是我不想考研因素之一。
但今年在互联网上所认识伙伴中挺多给我过于高的评价,都认为我作为一个学生,能有这水平是不是在某某牛逼的高校读书。然而并不是,我甚至都不好意思述说自己的高校,感觉是当下的污点。也正因如此反而让我有点过于焦虑,就从身份上,这不得让我萌生读研的一丝丝想法,也不至于死绝考研。
自我认为离真正的大佬还差很长的一段距离,我只是靠着三分钟热度,加上爱折腾,才维系下去,而那些真正的大佬是肯花费大量时间去编写他们所认为有意义的代码。
如果可以的话,在下方的留下你对我的评价与建议。我尽可能的争取在明年这时候完成你心目中我的样子。
结语
今年的年终就告一段落,与之前的年终总结相比,篇幅缩减了许多,主要感觉之前写的挺多流水账的,废话挺多的。也有一点是因为时间相对紧迫,其实 12 月我还没放假,都处于线上上课,线上考试的状态,而线上考试的方式我就不得吐槽了,提前打印给定的答题纸,题目以电脑的方式展示,最终将答案手写到答题纸上并通过手机扫描(扫描全能王)成 PDF 的格式提交,当然摄像头必然也是有的。总之麻烦事还是有的,还没到彻底闲下来闭关学习的时候。
按往常可能还有明年的规划,但我现在认为很多时候都难以依照自身意愿做事,而规划正好自己所设想美好的计划,很容易事与愿违。因为回顾过往的规划,有太多美好的计划,但在实际分析下也将变得不堪一击。不止项目需要可行性分析,人生计划同样需要,一些天马行空幻想,其实就不再有意义去记录了。
坚持做自己想做的事情,而不是逼自己做不愿做的事情。这是我编程学习中座右铭,也是给予他人编程学习的建议。
写于2022年12月22日 By 愧怍