目录

初入编程王国:「新生信息查询」是如何炼成的

本篇文章来自杭电助手技术部,杭电助手是一个服务于全校师生的学生社团。

相信新生们都已经用过了「新生信息查询」功能。本文将以通俗的视角,讲讲这个功能是如何开发、测试、部署上线的。

这篇文章能给你带来什么?

对于零编程基础

众所周知(对于新生来说可能是冷知识),大学的计算机课程多是偏理论的,与现实互联网大厂实际使用的框架并不一致。

换句话说,如果只学习书本的知识,毕业后所拥有的编程能力大概率和大厂的要求不一致。这中间存在一个知识壁垒。

助手的核心成员们有着丰富的项目实战经验,开发维护了许多学校服务。 开启这个系列,就是为了让大家接触到更真实的编程环境,少做无用功。

你将从本文中了解计算机常用的基础知识、如何编写程序、程序如何与微信公众号交互、如何测试程序、如何使用GitHub协作、如何自动部署/上线应用。

对于编程老鸟:

你可能已经会写代码,已经写过不少项目,甚至已经开始带领团队。但你可能并不熟悉如何使用 GitHub 优雅地协作、如何缩短代码从编译、测试、部署上线的周期(DevOps)。

可以翻到本文的后半部分,我们将介绍助手的协作流程与简单的 CI/CD 。

让我们开始吧!

计算机基础知识

不要慌,这一章的计算机基础知识并不是吓人的操作系统、计算机组成原理这种知识。我只讲书本里没有的、工作中却很重要的知识。

大部分本科计算机学生,毕业后都是去开发所谓的「软件」。而软件可以简单地分成「前端」和「后端」两部分。所以大家毕业后的工作方向一般也是这两个。

前端

前端可以狭义地理解为,一个软件中看得到的部分。比如网页上的文字图片、各种花里胡哨的样式、以及交互操作。广义上来说,大家用的各种APP、电脑上的应用程序,用户界面的部分都是前端干的活。

后端

相当于前端,后端当然是「看不见的部分」。为什么有前端?因为光有后端是不行的哈哈哈。举个例子,网上有很多软件都可以修改支付宝上的「余额」,如果只有APP表面,即前端,那不是人均黑客,人均首付? 所以一个软件的关键数据,肯定不是存在用户侧,即前端的。需要有这么一个东西,来存储数据(存储数据的地方叫数据库),来解析用户的请求,这就是后端。

举个详细的例子,购物软件上点了下单并支付,这时候前端就会发送一个网络请求,告诉后端:用户某某某,买了什么东西,价格和数量是多少,收货地址是多少。。。

然后后端收到了信息,先解析,然后修改数据库中存储的关键信息,比如新建一个订单信息,把商品的数量-1等等,再把下单的结果告诉给前端。前端收到信息后,就会渲染页面,提示「下单成功」!

新生查询系统的前端和后端

新生查询系统的流程是,用户给微信发信息,然后返回查询得到的新生信息。

所以可以简单地理解成

  • 前端:公众号的界面,即发送信息与显示查询得到的学生信息
  • 后端:后台的查询指令解析、信息查询操作

其实这个例子并不典型,实际上都属于后端。不过大家以后工作基本上不是做前端就是做后端,所以我想尽可能地把这个概念告诉大家,而不是一味地去学C语言。(当然C语言也很重要,它是你学习以后的所有编程语言的基础,大部分人都是通过学习C语言构建编程世界观的。基础不牢,地动山摇)

一起来写程序吧

下面我们将一起来写完这个神秘的查询系统。

我不会讲述过多的代码细节,而是带你认识实战开发的思路、编程的基本架构。

不用担心,虽然你现在可能什么都不会,但相信我,你一定能看懂大部分内容!

初分析 - 怎么收到用户的消息

我们要做的第一步是什么?首先要知道是谁给助手发信息了,发的是什么信息?例如用户A发送了「新生信息 123456」。

用户实际上是把信息发送给了谁呢?很简单,微信公众号。更详细地说,是微信公众号的服务器(服务器就是一个配置更好的永远不停机的电脑,里面跑着公众号的程序)。

所以我们只要告诉微信公众号官方,每次用户发信息的时候,你记得抄送我一份啊!

怎么告诉它呢,我们只要申请一个微信公众号的测试号,这样配置一下就行了,主要是填一下程序的服务地址。

https://bird-notes.oss-cn-hangzhou.aliyuncs.com/img/wechat-config-20220815.png

这样一旦有用户给公众号发送信息,助手就能收到了

怎么解析用户发来的指令

能收到信息还不够,我们还得解析指令!

因为助手还有很多其他的服务,例如「今日课表」、「成绩查询」等等(甚至学校旧的疫情防控系统也是由助手开发的,供学校近3万学子使用),我们要能区分出来用户发送的是哪个指令?

怎么区分呢?

判断用户发送的信息中,是否含有「新生信息」这四个字,就是这么简单,就是这么朴实无华!

我们再稍微完善一下,以免被喷:改成「新生信息」这四个字在消息的开头才触发。比如「123 新生信息」不触发。

然后再解析一个指令的另一部分,得到考生号。

有了考生号怎么查学生信息

前面讲到过,所有的数据都是存在数据库里的(你可以简单理解为一个加大号的自动化的 Excel ,每一行就是一个学生的信息)。

所以我们只要根据考生号,从数据库里查信息就行了。查到的话,就返回给用户,查不到的话,查不到的话,就报错,告诉用户考生号不对。

渲染用户提示

大家可以想象,Excel 里的数据都是单独的字段,并不是一段完整的话。从数据库里读出来的数据也是这样。

怎么利用基础的学生信息,拼接成人性化的查询结果呢?

简单,直接上图!

https://bird-notes.oss-cn-hangzhou.aliyuncs.com/img/wechat-freshmen-info-20220815.png

就是预定义一个模板,然后用代码把对应的信息塞进去。

框架

其实我还隐藏了很多细节,这些东西需要「框架」来实现。框架可以简单地理解为牛逼的人提前做好了一些东西,封装了基本的功能,你可以直接拿来用。

  • 比如如何用程序真正地和微信服务器交互?
  • 如何把拼接好的查询结果返回给学生?
  • 每个查询指令就是一个模块,助手有几十个模块,怎么统一管理起来?
  • 比如信息过长会被微信截断,如何自动分割消息?

助手在已有的底层框架基础上,开发出了一个便于小型业务的敏捷开发、多模块组合设计的微信公众号后端框架。并开源了出来:wechat-templat,作者: @Atom

再加点料

项目上线后,我们发现杭州电子科技大学果然不是虚的,很多同学有极强的 「探索精神」

有人尝试 爆破数据库,就像猜6位数密码,从000000猜到999999那样,疯狂地给公众号发信息,企图遍历出所有人的考生号以查询所有人的信息。

虽然理论上来说,因为大部分同学考生号在15位左右,就有至少 10^15 种可能性。就算ta一秒能猜100次,到 寿终正寝 也遍历不出所有人的信息。

但是助手还是决定「简单」限个流。

下面的内容可能稍微有一点硬核,不过不用担心,大家现在这个阶段完全不需要看懂。

如何限流?

还是很简单,记录一下每个微信用户在5分钟的查询次数,如果超过2次,就提示超过次数就行了。

怎么记录这个次数呢?

用一个叫做 Map 的东西(可以简单理解成只有两列的表格),键是微信用户的唯一标识(Union ID ),值是最近5分钟的查询次数。

怎么实现只记录5分钟的查询次数呢?

依然很简单,我们只要找到一个好用的工具,叫做 cache,你可以往里面塞东西,设定过期时间(比如5分钟)。时间到了,往里面塞的东西会自动消失,在达到效果的同时还能省内存。

怎么找这个东西呢?再引用一个简单的概念,「库」。

程序员喜欢分享代码,总会有人写一些好用的工具,然后分享出来,我们直接用就行。拥有一定能力的封装了部分功能的代码集合,就可以称为「库」。大家学C语言时代码最上面的那个 <stdio.h> 就是库,只不过是官方库。

开源

说点题外话。

前面提到的把自己写的代码共享出来的过程,就叫「开源」。

开源是程序员的浪漫。

开源的好处有很多。

  • 比如你把厉害的代码公开出来,别人看了之后会夸你牛逼。(就像我前面放的那个 wechat-template)。
  • 正因为开源的代码很优雅,所以我们阅读开源代码能极大地提高自己的编程水平。
  • 搞开源也是实打实的编程经验
  • 开源能让自己的简历贴金(比奖学金还猛),甚至能在参与开源的过程中遇到以后的面试官,走上人生巅峰。

如果大家感兴趣的话,可以留言。或许助手技术部以后可以专门出一篇开源的博客,讲讲开源的好处,如何参与开源,如何选择开源社区,如何参加开源活动等等。

协作

这个新生信息查询系统并不是一个人完成的。笔者完成了基础功能部分,@sslime 完成了查询限流部分。

我们是如何同时/共同写一个程序的呢?

答案是:Git/GitHub

我们可以这么理解它:现在有很多成熟的在线文档,比如腾讯文档,支持多人编辑。而 Git 是一个代码界的协作工具,它的牛逼之处如下:

  • 每个人都可以编辑代码的一部分,只要两个人没有修改同一个地方,它就能自动把两个人的修改合并到一起。
  • 版本控制。我们平时写一个文档可能要改很多次,然后就有了《文档1.1》《文档1.2》这样的东西。使用 Git,你可以在每次修改完简单打个标记,以后可以随意切换到任何版本。不用手动重命名和复制文件。
  • 分支。比较复杂我就不介绍了,大家可以自行搜索。对于有基础的同学,我推荐这个 Git教程 来进阶。(没基础的千万别点进来折磨自己)。

所以 ssilme 同学在本地拥有一个和我差不多的项目,然后给项目加了限流功能,再通过一个叫做 「GitHub Pull Request」 的操作,请求合并到主仓库中来。

接下来,我需要去审阅(review)他的代码,看看有没有哪里可以提升的地方。如果 review 通过,那么我和他的代码就融在一起,大家就能用到最新的程序了。

review 是协作中最重要的一环,能保证代码的质量。 同时,如果你作为一个新手,每次写的代码都能获得大佬的修改意见,那你离成为大佬也不远了。助手即将开启招新,欢迎点击「阅读原文」加入招新群。

以下是助手本次协作的部分截图。

这个是 ssilme 同学发起了 pr。

https://bird-notes.oss-cn-hangzhou.aliyuncs.com/img/freshmen-info-github-1.png

以下是部分 review 建议:

https://bird-notes.oss-cn-hangzhou.aliyuncs.com/img/freshmen-info-github-2.png

https://bird-notes.oss-cn-hangzhou.aliyuncs.com/img/freshmen-info-github-3.png

https://bird-notes.oss-cn-hangzhou.aliyuncs.com/img/freshmen-info-github-4.png

最后,代码已经接近完美,让我们完成神圣的最后一步,合并修改!

https://bird-notes.oss-cn-hangzhou.aliyuncs.com/img/freshmen-info-github-5.png

DevOps - 缩短代码从编译、测试、部署上线的周期

这部分是主要面向有编程基础、项目基础的同学的,零基础的可以简单浏览一下(这次是真的简单),当作扩展视野。

大学期间的大部分人写的程序都只是在自己的电脑上跑通,但在实际的生产实践中,想要上线给上万的人使用,还需要漫长且复杂的流程。

例如,先要把代码编译好,然后执行一系列测试工作来保证程序如期运行。再通过 ftp 工具把编译好的二进制文件拷到服务器上,再 ssh 登录服务器上线部署。

最后,可能只是改了一行代码,然后却花了半小时编译、测试、部署上线等等。

我们能不能写完代码,就直接部署上线,后面的操作全部自动化完成呢?

当然!可以!

这个东西叫 DevOps ,Dev 指 Development 即开发,Ops 指 Operation 即运维。但他们连起来不是指简单的「开发和运维」,而是尽可能地打通与自动化开发流程,提升团队研发效率、交付效率与交付质量

助手使用 GitHub Action 配置了简单的 CI/CD 流程。

如下图,每次有人提交新的代码,都会自动执行一系列自动化程序,

https://bird-notes.oss-cn-hangzhou.aliyuncs.com/img/freshmen-info-ci-1.png

目前助手的 CI/CD 流程比较简单,能做到检查代码规范性(golangci-lint) 、自动编译 Go 语言 程序、将编译好的二进制代码上传到服务器、自动部署上线新项目。

https://bird-notes.oss-cn-hangzhou.aliyuncs.com/img/freshmen-info-ci-2.png

也就是说,在代码完成 review 后,不需要任何额外操作能自动完成上线等一系列操作。

推荐想了解 DevOps 的老鸟一些高质量文档:

最后

程序虽然很简单,但这个是学校给的紧急需求,所以基础部分是在一个小时内完成的(包含测试)。

抱歉忍不住一下子写了那么多的内容, 其实还有很多内容因为篇幅原因无法展开。

再提两件事情

  1. 助手即将开启招新,欢迎志同道合的小伙伴们加入,不限年级。可以扫描二维码或者点击文末的「阅读原文」。
  2. 助手有打算创建一个编程实战系列教程,会选定一个实际的项目,以文档的形式一步步带领大家做一个项目。敬请期待。

https://bird-notes.oss-cn-hangzhou.aliyuncs.com/img/招新二维码.jpg