背景
最近这一段日子,绝大部分时间花在一个答题系统上,项目预期是利用扫描仪获取到试卷的数据,随后对数据进行处理以及匹配规则,最终算出该题目的正确答案。目前系统已经开发到第二版本,现在还仅仅是一个简易型的Demo,但是其中涉及到一部分坑以及在工作的时候发现的一些问题,鉴于此,使用文本记录下来,为以后成为优秀程序员铺路搭桥。
首先说一下数据,数据是由做底层算法的同事提供的,使用XML格式存储,绝大部分数学公式都是Latex格式。我所做的事情,其实很简单,就是将数据保存起来,同时提供数据配合前端。但真的有这么简单吗???
第一版
在第一版中快速开发,直接将提供的XML格式原封不懂的保存到Mongodb中,然后提供查看的数据的接口给前端的同时,由前端展示题目。同时再提供一个接口,用于接收前端传来xml格式,将xml作为参数调用有算法小组提供的jar,最后获取到题目计算结果反馈给前端。其实就相当于数据的搬运工....
开发异常简单,接口不多,又不用处理....So?快速开发,解决掉项目,然后转战别的工作。但是在前端人员开发的过程中,这样的后台设计暴露出越来越多的问题。For example:
- 前端展示题目需要获取到题目的文本信息,并不需要xml中的标签,于是乎前端开始解析Xml,大量的xml解析必定是消耗资源的....,同时文本中也存在一些影响展示的信息,因此前端需要最数据进行处理。
- 题目分成三种类型,选择、填空以及简答,前端需要识别题目归属于那种类型的题目,然后才能合理的展示题目(因为不同的类型题目,展示风格会不同)
- 由于项目不仅可以计算预先设定的题目,还可以在原题目的基础上修改题目内容,因此前端使用一个插件来展示和修改题目(主要是公式的latex的展示和修改),这个公式编辑器有些坑,不识别我们这边的很多latex。
- 在前端开始解答事件被触发时,需要后台实时传递题意分析结果,用于展示在前端,提供一个良好的人机交互(主要让使用者知道,我们的系统在计算, 而不是死机...),这个地方一开始为了快速开发,也是采用比较low的方法,没错!!!就是AJAX轮询...轮询的各种弊端,我就不多做阐述了,各位脑补吧
第二版
由于第一版出现的各种问题,在第二版中做了很多改进,改进如下:
- xml数据的处理从前端移交到后台,使用python脚本预先处理好xml数据,然后按照不同的数据格式保存到Mongodb中(根据题目类型的不同而不同)
- 由于一开始使用的开源Latex公式编辑器并不适应算法小组的Latex,因此经过调研以及各位领导的努力,我拿到了一个团队基于这个公式编辑器开发的绝大部分适应算法小组的Latex格式。
- 将原先使用AJAX轮询实现实时前后端同步数据,改成使用webSocket(这部分逻辑有些长,下篇博客会主要讲一下这部分)
整个项目是基于Spring boot框架与Jetty服务器的,使用这个Spring boot框架的目的有两个
- 快速开发,不需要过多的配置
- webSocket 与 Spring boot 配合很好
- 以前没用过这个框架,而它又很火,So?我心里痒痒的,于是就开始了任性...(其实使用Jetty的目的也是因为这个原因)
坑与解决办法
- 算法小组提供的数据存在数据有误、格式不统一等等。
- 解决办法:
- 在编写python代码时,多考虑可能会出现的错误,做好容错以及发现错误之后,对错误的定位。
- 具体实施:
- 对于文件格式不符合要求的,会抛出异常,捕获异常之后,打印到控制台。
- 对于xml格式不正确(由于是数学公式,因此存在<,>符号,而这些在xml中是不允许出现的),在解析之前先进行一层过滤,将不符合xml规范的数据规范化,然后在调用xml解析程序,解析完成后处理再保存。
- 解决办法:
- 新的公式编辑器虽然比老版本的兼容性要高,但是还是存在很多不兼容问题,这不仅仅影响展示,更加影响计算过程(算法小组所需的Latex与公式编辑器生成的不一致)
- 解决办法:
- 在公式编辑器利用Latex生成公式图片之前,进行Latex的处理(为什么不直接在解析xml的时候处理呢?因为...我尽最大可能不改变算法小组所需的Latex格式,如果使用者没有对原来的题目进行修改,直接答题,会将原先的Latex传递给计算模块,这样可能保证计算模块所需数据的正确性)
- 在传递给计算模块之前还有一层公式转换器,会将那些不符合计算模块的Latex修改成符合计算模块的Latex
- 具体实施:
- 基于这两层处理层,基本上可以保证计算模块所需数据的正确性
- 使用各种正则表达式替换和处理(很锻炼正则的能力)
- 解决办法:
- ....(还有很多小坑,就不详细说了,绝大部分都是自己那菜鸟级的经验)
项目现版本存在的问题:
- 前端单个页面承担太多的展示任务,导致CSS与Js文件臃肿且bug层出不穷。
- 算法小组提供的数据有很多错误,在同一个文件中描述同一个公式却使用不同的Latex公式,让我这边适应很困难,因为不知道到时候真正需要计算的Latex具体格式,如果传递有偏差,计算模块是否可以能解题
- 系统在相隔一段时间没有人访问之后,再次访问会莫名其妙的报Mongodb time out错误,解决了好几次,都以为自己解决了,但是...bug还是一致存在(间断性)
感悟
- 项目在一开始的需求步骤和第一版的开发前中期我都没有参与,导致对需求的不理解与项目整体把握程度不够,不能做到很好的协调。个人认为无论开发什么项目都应该将大家聚在一起,一起讨论需求,一起规定我们要做出什么模样的产品,而不是一个人在想,另外一帮人在等着被安排,凡事应当主动,主动参与到项目的需求讨论中。这样不仅能提高项目的整体质量,而且也能提升个人能力以及对项目的把握程度!
- 跨部门的合作成本过高,一定在开发之前约定好数据格式!!!编写维护好开发文档!!!
- 写代码之前要先设计,没有思路就不要动手写代码,项目要的是高水准的代码,而不是一坨坨...
最后很感激部门领导给我这次机会,让我开发并协调各开发人员,这是对我的锻炼,虽然辛苦和烦恼,但是对于个人能力的提升有很大帮助。