个人问题总结:JavaBoy第一个正式参与的实际项目
第一个有自己负责模块的项目接近尾声,总结一下自己在这个项目中产生的问题,希望以后减少、不会再犯此类错误。
项目分为java语言开发的web端与python语言开发的app端,后端与后端之间通过openFeign通信,此次开发我主要负责后端代码。
下面我以一个学生管理系统为例,记录一下本次开发遇到的不足。
开发时的问题总结
问题1:字段冗余、混淆
在建表之初,由于建表风格不统一(不是同一个人)带来了以下问题。
表的逻辑外键出现了多种写法:student表的id,在class表是studentId,在team表就成了student。
在设计之初设计了冗余字段:因为双端互通,数据库选型不相同,app端使用sqlite,而web端使用pgsql。数据同步时,为后续拓展考虑,给student设置了两个键:id、sync_id,由于在开发过程中混淆了两者,导致后续开发在新建数据时,必须让id=sync_id。
上述两种问题都有解决方案:第一个需要统一建表风格;第二个则是明确开发时到底要不要sync_id,如果需要,那就明确id和sync_id的使用场景:id只需在新增时保持唯一,而查询和同步都是使用sync_id作为键,不需要额外处理id键。(可能这个解决方法并不好,目前就想到这里了)
问题2:中文、枚举与标识
这是一个开发的基本规则问题,这次开发我不仅是懒而且也赶进度,犯下了这个问题。
在存学生考试评级的时候,level字段应该存一个通过字典/枚举实现的k,比如1对应优秀,2对应良好。
因为图省事,我直接存了'优秀'在level字段中。
在设计性别字段时,一开始使用了枚举类型,方便Excel导入导出的转换(使用了easyexcel的转换器功能),但是枚举类型在存储的时候会优先存index,而非value,我设置的是{key=1,value="男"},{key=2,value="女"}。实际存储到数据库中则是0=男,1=女。在最初的过程中没有遇到问题,后续因为体育课的评分要分类全性别组0、男组1、女组2。导致数据再此出现不一致情况。
原因是:JPA默认使用枚举的ordinal()索引值存储,而非自定义的value,下次使用枚举时,应该首选string类型数据作为key,可以直接通过注解存储
@Enumerated(EnumType.STRING) // 存储枚举名称 "MALE", "FEMALE"
问题3:git分支管理
项目前期在其他人搭好架构后,基本都是我在写,因此我一直在用一个test分支,后续因为赶时间,其他人也要参与实现部分功能。由于没有明确的分支管理,多人使用一个分支,可能造成了代码丢失,代码混乱等问题。后续开发应该严格遵循一人一分支,最后merge总分支的实践。
后续补充:可能不是因为分支管理问题,后续使用了多分支,但是我的代码还是在git不会提示的情况下被merge的代码覆盖,很头疼。
后续再补充,感谢客户端开发的大哥告诉我:分支管理的问题,我的另一个同事写完代码后解决冲突没有仔细合并,导致 了代码丢失,这些丢失都可以通过git的提交记录回溯。尤其在idea中,记录了merge对两个线的代码的修改情况,可以明确看到用户是怎么合并的。
问题4:PGsql的jsonb使用情况
有一个模块由我来负责设计、开发:一个考试,考试包括了成绩梯度划分、扣分项详细说明。在我的设计中,创建了三张表:考试规则表、考试规则详情表(外键考试规则表)、扣分项明细表(外键考试规则表)。在创建考试规则时,前端只需要在一张大的table上输入三张表信息,需要先请求createExamRule,通过返回的id再请求创建其他两张表。三次分别的数据库更新操作无法保证事务一致性,尤其是当考试规则创建成功后,考试规则详细/扣分项一旦创建失败,前端只能再调用删除数据保证数据一致性。这是创建时的弊端。在更新时,分别更新带来的问题更大:考试规则更新成功,而考试规则详情更新失败的情况难以回滚,考试规则详情与扣分项的增删改需要前端额外判断修改。
在开发进行大半后,前端提出了以后的后端开发都是设计为使用extra直接存储详情内容和扣分项,不需要这么复杂的额外的工作处理。没办法,我对pgsql的掌握不精,初次使用忘了jsonb存储,只能求前端硬着头皮和我一起写....
那么为什么使用jsonb?
首先就是事务一致性的问题,使用jsonb就意味着仅对一个表操作,原子性得到保证。
更新操作也是原子的,能减少前后端工作量
还有就是这里可能用不到的,jsonb的查询方式也非常灵活。
举个例子:
SELECT * FROM exam_rules WHERE rule_config -> 'deduction_items' @> '[{"item_code": "LATE"}]';
-
->操作符:从 JSONB 对象中提取指定键的值 -
@>操作符:检查左边的 JSONB 是否包含右边的 JSONB(包含操作)
问题5:代码耦合
在开发python项目中,对语言比较陌生+时间紧迫,很多代码由trae辅助完成,trae写代码不会特意注意项目架构,主要以完成用户需求为主。因此在一个service中会混合多个entity使用,调用读json频繁新造轮子,造成代码比较臃肿。在开发初期这部分问题我没有处理,后续虽然整体代码量不大,但是我还好注意到了这个问题,分清楚工具类,service解耦,希望下次再写陌生语言的项目也能提前注意,做好规范。
问题6:代码的全局观
在开发项目时,对自己代码的把控度不够。尤其是py的项目,在修改代码时,经常会出现修改了新增,但查询和修改的接口没有同步进行修改,导致后续和前端联调时频繁出现原本已经可以使用的接口,由于局部修改不可用,影响了开发进度。问题的主要在于我的项目经验不足,整体代码思路不够清晰且语言陌生带来的项目熵增非常严重。
此外,项目使用了openFeign作为数据交互通信接口,Java端和python端的数据交互功能频繁出现问题,两者使用的数据库不一样,数据类型会有错误,一方table修改,另一方不仅要修改table,更要去修改其对应的方法,本就在单个模块上步履维艰,两个模块上的同步修改更是雪上加霜。在这次项目中fix 同步xxxx是我最多的commit...
出差时的问题总结:
代码基本开发完成后没想到我还需要去部署项目,先给甲方使用并继续完善,这个过程中,避免不了业务和逻辑问题的修改,前前后后大概半个月,总结一下出差时出现的问题。
问题1:项目部署nginx与docker的使用
由于疏于对nginx的了解,在学习nginx教程时也只是了解了一些非常基础的框架理论,无法支撑我的实际操作。在出差需要本地部署nginx时仅依赖trae帮我生成对应的conf文件,在trae生成的conf文件不符合项目实际需求时无法处理,带来了出差后开发与测试进度的小拖延,后面在假期稍微学习了一下nginx。了解了最基本的使用,在后面docker部署nginx出问题的时候,也能够及时排查问题,提高了效率。
本人对于docker的使用几乎也只记得docker ps和docker pull push等操作,现在因为项目包含了mq、pgsql、minio、redis等其他中间件,Windows本地部署还是很麻烦的(虽然我确实实现了Windows本地部署minIO、redis和pgsql)为了提升自己,也是确实中间有稍微的空闲时间,使用了Windows上的docker desktop和docker-compose实现了一系列的部署。这中间主要遇到的问题是:对挂载概念的不熟悉,在一开始使用nginx时,虽然成功将nginx.conf挂载到docker中。但在前端部署好dist文件后,本以为可以直接使用,后经教我的同事提醒才知道,nginx中的html没法直接映射到本地,也需要挂载。本来自己也清楚测试环境dev和生产环境prod,但是在实际使用时一开始确实忽略了两个yaml文件的重要性,一直在修改dev文件,给自己的部署进度带来了很多不便。
问题2:远程开发的弊端
出差时,我作为后端的代表,很多信息难以明确传达给同是后端开发组同事,导致很多数据不符合预期。临近项目尾声,我除了负责自己的部分开发功能,部署项目以及测试,还要对他们的代码把个关,尤其有的同事比较摸鱼,AI跑出来的代码不自己仔细看就直接commit。还有人AI修改删除了部分函数也直接commit,拖慢了进度。后续修改几乎都由我一个人负责,这个问题也几乎消失。
问题3:计算机网络的不了解与树莓派不熟悉
因为是多个软件协同,通过上述信息大家可以知道我的这个项目是web+app,并且app需要额外绑定树莓派。甲方又需要在独立的内网环境(我自己搭建,让树莓派作为交换机)中运行,因此网络的连接问题对我造成了很大的困扰,曾经上学时所学的计算机网络,我现在连7层结构都印象模糊,WAN口LAN口更是只记得一个名字,在连接整个项目时,遇到了一些困难。
树莓派里的SD卡非常脆弱,意外关机可能会导致SD卡无法正常使用。
树莓派的螺丝大小不一,在装拆的时候对应不上螺丝很难拧。。。(物理意义上的非常困难)
还有最棘手的,也是现在最难把控的问题:树莓派(本身也作为交换机)偶尔连不上局域网,至今不知道具体原因,只能依靠重启树莓派解决问题(感觉是线或者接口太脆弱了?)。指纹识别模块的异常操作会导致设备异常,使设备不可用,在部分情况下可以通过拔插指纹模块解决,但是大部分情况下只能通过重启树莓派解决对应问题。这个问题困难点在于团队里的指纹模块、树莓派是采购的,没有人会硬件设备,无法对这部分进行优化。
问题4:实际业务与开发时的差距
甲方实际体验软件后,发现开发与实际的愿景还是有区别的。以大学体测为例,50米跑步、3000米跑步是多人同时开始,在设计时不论是前端还是后端都很容易将他们归为一类。但是实际使用情况下,我们的项目在场景上无法全方位替换秒表功能。3000米跑大家间隔相对较大,可以每个人一个结束计时器,软件上可以操作的过来,而50米跑的时候,大家相差较多,如果每个人一个计时器完全无法提供实际功能。
总结
这次项目虽然还没有交付,通过上述问题,我已经学会了很多:pgsql的使用、开发规范、中间件nginx与docker的使用,对树莓派以及linux操作系统有了更进一步的了解,对git的使用方法也有了加强。对我来说这次的收获还是很多的,最后希望项目验收能顺利进行。

浙公网安备 33010602011771号