晶泰科技实习经历

晶泰科技实习经历

在晶泰科技的实习经历: 2021.6-2021.12

这是我第一段在公司中的工作经历,在此感谢所有一起工作过的同事~

Python 后端开发

前四个月做的是 Python 后端开发,这也是当时的我唯一能胜任的工作了。在来公司之前,我熟悉的是Django+MySQL这一套,因此一开始还不太习惯写Flask。再加上要学习新的图数据库Neo4j,当时还是有一些不适应的。开始我是跟同事结对编程,在一两周之后就可以独立开发了。

重构

现在回忆起来,其实第一个项目复杂度蛮高的,需要对该领域有一定程度的理解。再加上一开始写后端的时候分层没有做好,当新需求到来的时候就发现系统越来越难写。接口层(api)直接接到数据库层(db)去了,没有在中间加上一个模型层(model)。于是tutor带着我一起重构了系统。这个系统甚至需要一个校验层,因为接口输入和输出的处理本身就很复杂,包含了不少业务逻辑。

重构当然不能少不了自动化测试。重构的过程就像是在走钢丝,如果没有之前写好的一些单元测试和接口测试,那在重构过程中就很可能使系统产生bug。当时公司还组织了一次敏捷开发的工作坊,授课老师提到了一个小步快走的策略:改一点代码,跑一遍测试,改一点代码,跑一遍测试…… 就这样重复下去。当时也看了《重构:改善既有代码的设计》这本经典书籍,从中得到了不少启发,其中最重要的一点就是重构会带来更好的性能。虽然重构代码可能会将一些性能高的写法优化成可读性好的写法(比如把一个for循环拆成两个),但是可读性好的代码更容易被优化。而且在一般的业务开发场景中,性能远没有你想象中的那么重要,在遇到性能问题的时候再去考虑优化代码运行效率也不迟。

敏捷开发

以前我从来没有听说过敏捷开发这个概念,来到公司后体验了一两个月的敏捷开发。每天早上十分钟站会,把看板上面的任务过一遍,每个人都报告一下自己昨天的任务进展,跟大家同步开发进度。每两周开一次总结回顾会和需求计划会,首先总结上两周任务完成情况,再一起规划下两周要做的任务。在我看来,这种开发方式真的挺神奇的,你可以知道同事们都在忙些什么(尽管听完之后可能也不太懂),知道整个团队的重点开发方向。Code Review 也是敏捷开发的一环,这个过程可以帮我们发现很多代码里面的问题。

DevOps

来到公司之后,我才切身体会到CI/CD带给程序员的巨大生产力提升。之前在校内创业公司的时候,后端都是需要自己登上服务器手动部署的,而且从来也没有什么自动化测试来保证交付质量。公司里面有Jenkins做自动化测试、自动化镜像打包,有一键部署镜像到集群上的平台。

Docker

云原生时代怎么能不懂点容器技术呢?

我是在学习CI/CD的过程中踏入容器技术的大门的。当时看的是Docker — 从入门到实践这本书,认真读完一遍后就基本了解了容器的概念及用法。之后就开始给项目写Dockerfile和DockerComposeFile,实现一键启动后端及其依赖服务,切身体会到容器带来的便利。后来做了一个管理Docker Compose的小后端,在开发过程中反复读Docker文档,更令我加深了对容器技术的了解。

SDK

第一个项目需要给其他同事提供SDK,包括离线和在线版本的。当时就在想怎么才能减少维护SDK的工作量,因为在线SDK的代码基本只是调用了接口,完全可以用一些代码生成工具解决的。摸索了好几天,最后在CI中集成了 Swagger Codegen ,通过 Swagger 生成在线版本的SDK。离线版本就只是把一部分代码复制过去改动一点点。在开发第一版SDK的过程中,由于是第一次写Python Package,踩了不少坑。后来有了新的需求,两个版本的SDK不方便使用,我们把它们合成了一个,还加上了缓存的功能以减少服务压力。

API Doc

前后端协作怎么能离开API文档呢?

  • 开发第一个项目的时候用的是Swagger,API文档就放在代码仓库里面一起维护。起初我还觉得挺好的,后端先跟前端约定好接口规范再开发,这样能减少很多前后端对接的时间。后来,当开发速度加快以后,我发现API文档跟代码不同步了,有时候只更新了代码,却忘了更新API文档。不仅如此,前端同事提出了接口用例和接口Mock的需求。
  • 于是我们前后端约定使用Insomnia来进行接口定义和调试,每次更新文档或者接口用例之后就把配置文件导出后发给对方。这种做法仍未解决接口Mock的问题,而且也不便于版本管理。后来,我们觉得在群里发配置文件的方式很麻烦,想要一种更便捷的同步文档的方式。
  • 于是在经过技术选型后,部门部署了YApi,同时解决了文档同步和接口Mock这两个需求。我们在第二个项目中就完全采用了YApi,接口定义、接口Mock、接口测试都在上面做。它不需要我们写Swagger,大部分操作都是傻瓜式的。这既是优点也是缺点:优点是学习成本低,便于上手;缺点就是它无法提供像Swagger一样完善的功能,比如由于YApi不支持定义schema,每次修改model的字段时都要改好几个接口。YApi的接口测试还是十分实用的,可以自动检测接口返回的数据结构是否符合文档定义,同时也支持测试有依赖关系的一组接口。总体来说,YApi还是比较好用的。

Golang 后端开发

最后两个月我转去做Golang开发。从零开始学Golang挺有意思的,从学习它的语法到学习它的设计哲学。我推荐看官方的Go TourEffective Go,认真学习完这两个基本就能开发简单的项目了。如果想继续深入了解底层原理,可以看Go 语言设计与实现
我当时跟着同事开发一个新项目,在实践中学习一些高并发架构设计的经验以及Golang的开发规范,这样会比自学效率高很多。同事帮我Review代码也让我少走了很多弯路。

并发安全

Golang开发一定绕不开并发安全这个话题,其实哪怕是Python开发也会涉及到并发安全。一般人的思维都是串行的,难以推测出程序在并发场景下的行为。在写有一致性要求的代码时,一定要考虑好不同线程/进程间的同步机制。该加锁的地方就得加,不要自作聪明想着这个地方应该不会存在 race condition。正如The Go Memory Model这里写到的:If you must read the rest of this document to understand the behavior of your program, you are being too clever. Don't be clever. 不要自作聪明觉得这里可以无锁编程,只要涉及并发的地方都要加上同步原语(如锁、信号量)。加锁一方面可以确保程序是以正确的顺序运行,另一方面也是告诉其他程序员这块区域是critical section,改动时要特别小心。虽然加锁会带来一定程度上的性能损失,但请记住这句话:在一般的业务开发场景中,性能远没有你想象中的那么重要,在遇到性能问题的时候再去考虑优化代码运行效率也不迟。

总结

时间过得飞快,眨眼间我也在业界工作了半年了。工作没有想象中的有趣,但也还可以吧,起码自己大部分时候还是怀有工作热情的。希望自己早日找到钱多事少离家近的工作吧😂。