十一月广州的夜风终于带上了点凉意。晚上十一点半,宿舍里的顶灯已经熄了,舍友的机械键盘敲击声和游戏里的语音交流声混杂在一起,是大学男生宿舍最日常的底噪。我盯着屏幕,IDE 里的光标在深色的背景下规律地闪烁。
刚才为了查一个 Spring Security 的拦截器配置问题,我习惯性地打开了搜索引擎。点进排在第一的 CSDN 链接,先是弹出一个要求关注博主才能阅读全文的遮罩层,接着侧边栏的广告开始闪烁,等我耐着性子往下划,想要复制那段核心代码时,系统又提示我必须下载 APP 或者扫码登录。
我把鼠标移到浏览器标签页的那个小叉上,按了下去。接着又点开了掘金,首页的信息流里充斥着《拿到字节 Offer,我做了这几件事》、《前端已死,后端还有出路吗》这样的焦虑制造机。SegmentFault 倒是清爽一些,但总觉得少了点什么,像是一个沉寂已久的旧图书馆,落着灰。
现有的技术社区各有各的庞大,也各有各的臃肿。我靠在椅背上,看着屏幕发呆。一个念头在脑海里慢慢浮现:既然找不到一个完全合心意的地方,我能不能自己试着做一个?一个更纯粹一点的,没有满屏广告,没有为了流量贩卖焦虑,只有干干净净的代码和技术讨论的开发者社区。
这个想法一旦冒出来,就有点按捺不住。
在广州商学院这几年,我拿了 4.02 的绩点,拿了两次国家奖学金。在很多人眼里,民办三本的标签像是一道无形的墙,墙里的人容易陷入某种自我放逐的松弛,或者是在考研和找工作的焦虑中盲目打转。学校里的技术氛围确实谈不上浓厚,没有那种极客文化,也没有推门就能遇到大佬的社团。
但我知道,在这所学校的各个角落,在那些晚上亮着微光的宿舍床铺上,或者在图书馆闭馆前最后一秒才合上电脑的座位上,是有那么一群人的。他们可能在死磕一个底层的 Bug,可能在看一本厚厚的计算机网络,他们散落在不同的专业和班级里,像是一座座孤岛。
我想把这些散落的技术人聚起来。不只是为了我们学校,也是为了所有像我一样,渴望在一个安静的角落里纯粹地讨论技术的人。
我给这个项目起名叫「灯台」(Dengtai)。没什么特别宏大的寓意,只是觉得,在信息过载的暗夜里,能有一束光,哪怕很微弱,只要能照亮一小块礁石,让航行的人知道这里有同类,就足够了。
决定了要做,接下来就是长达几个月的敲代码日常。
技术选型上,我没有去追逐那些最花哨的框架。后端我选了 Java 加上 Spring Boot。这套东西很重,但它是工业界的事实标准。我想借着这个完整的项目,把 Spring Boot 生态里的那些组件真正地揉碎了、吃透。
数据库是 MySQL 搭配 Redis。在设计表结构的时候,我在草稿纸上画了很久的 ER 图。用户表、文章表、标签表、评论表,它们之间的关联,索引的建立。Redis 被我用来做热点数据的缓存和点赞、阅读量的计数器。看着控制台里 Redis 的命中率一点点上升,接口的响应时间从几百毫秒降到几十毫秒,那种感觉比打通关一个游戏还要好。
最折腾的是搜索模块。一开始我只用 MySQL 的 LIKE 语句做模糊查询,数据量小的时候还能应付,但稍微长一点的关键词,或者想要做分词匹配,就完全歇菜了。于是我引入了 Elasticsearch。
那几天,我几乎泡在了 ES 的官方文档里。在一台只有 2C4G 配置的便宜云服务器上部署 ES,简直是一场灾难。JVM 内存动不动就溢出,进程直接被系统 Kill 掉。我只能一点点地调优 JVM 参数,配置 IK 分词器。当我在搜索框里输入一个不完整的技术名词,下拉列表里瞬间弹出带有高亮标签的相关文章时,我长长地舒了一口气,拿起桌上已经放凉的水喝了一大口。
前端我用了 React。写惯了后端的严谨逻辑,再去写前端的组件化,像是在两种不同的思维模式之间来回切换。我没有用太多现成的 UI 库,很多样式都是自己手写 CSS 调出来的。我希望它的界面是克制的,大面积的留白,合适的行距,代码块要有舒适的高亮配色。
核心功能其实就那么几个,但我尽量把每一个都打磨到自己觉得舒服的状态。
技术文章的发布与阅读是核心。我集成了一个纯粹的 Markdown 编辑器,去掉了所有花里胡哨的富文本排版。因为代码本身就是最好的排版。
标签体系和个性化推荐,我没有用那种会让人上瘾的推荐算法。我只是根据用户平时阅读和订阅的标签,做了一个简单的权重计算。我希望用户在这里看到的是他们真正需要的东西,而不是被算法投喂的信息垃圾。
评论与互动模块,我设计了嵌套的回复结构。我不希望这里的评论是清一色的“博主牛逼”、“感谢分享”,我更期待看到那种带着代码片段的质疑,或者是对某一个技术细节的补充。
为了让社区有一点生命力,我加入了一套轻量级的用户等级与贡献体系。不是为了攀比,只是觉得,那些愿意在这里留下思考痕迹的人,他们的贡献应该被记录下来。
代码写完,部署上线的那天凌晨,我看着浏览器里那个干干净净的首页,心里其实没有太多激动的波澜,反而是一种巨大的空虚感。
服务器跑起来了,域名解析成功了,但是,数据库是空的。
冷启动,是每一个社区产品都要面对的死局。一个没有内容的社区,就像一个装修精美但空无一人的餐厅,路过的人看一眼就会离开。
我成了灯台的第一个,也是唯一一个用户。
接下来的一个星期,我把自己这几年存在本地笔记软件里的技术总结、踩坑记录,一篇篇地整理好,重新排版,发布到灯台里。我像一个孤独的建筑工人,在自己建好的空城里,一块砖一块砖地往里填东西。
有了十几篇文章打底后,我开始尝试去找第一批用户。
我没有去那些大平台发软文,觉得那样太刻意。我只是在学校的几个技术交流群,还有平时认识的一些外校开发者的微信群里,发了一段很简短的话,附上了链接:“自己写了一个纯粹一点的开发者社区,目前只有我一个人在上面写文章,如果大家有兴趣,可以来逛逛,或者把平时写的笔记存上来。”
发完之后,群里有短暂的沉默。接着,有几个人回复了“支持”、“看着不错”。
那天下午,我一直盯着后台的用户注册表。数字从 1,变成了 2,然后是 5,慢慢地爬到了 20。
更让我欣慰的是,到了晚上,我刷新首页的时候,发现信息流里多了一篇不是我写的文章。是一个我不认识的 ID 发的,写的是关于 Vue3 响应式原理的源码解析。排版很干净,代码块也处理得很好。
我点进那篇文章,认认真真地看完,然后在评论区敲下了一行字:“写得很透彻,特别是 Proxy 拦截那一块的图解,学到了。”
那一刻,我突然觉得,这几个月的熬夜、掉头发、对着屏幕抓狂,都值了。
现在,灯台还在平稳地运行着。它没有爆发式的增长,每天的日活也就是那么一小撮人。但这里的氛围正慢慢变成我最初期望的样子。有人在这里提问,有人在这里分享自己做的小玩具,没有人在意你是不是大厂出身,也没有人在意你的学历背景,大家只讨论代码本身。
回头看,做这个项目让我真正地从全局的视角去审视了一个 Web 应用的生命周期。从需求分析、数据库设计,到后端架构、前端渲染,再到服务器部署和后期的运维调优。它让我对 Spring Boot 生态的理解,从停留在书本上的概念,变成了肌肉记忆。
大学四年很快就要结束了。拿着 4.02 的绩点和那些奖状,我可能很快也会汇入找工作或者继续深造的人海中。但灯台会一直留在那里。它就像我在这段青春里留下的一块自留地。
我不知道它未来会变成什么样,也许有一天它会因为服务器欠费而关闭,也许它会一直这样不温不火地存在着。但只要还有一个开发者在深夜里打开它,在这个安静的角落里写下一行代码的感悟,它就完成了它的使命。
所有的代码都已经开源了,如果你也想看看它的内部构造,或者想自己部署一个玩玩,可以去这里看看。
夜已经深了,舍友的呼噜声渐渐响起。我合上电脑,屏幕的微光在宿舍的墙壁上闪烁了一下,然后归于黑暗。明天,还有新的 Bug 等着去修。