第一 : 假如我在修改bug或者添加新东西的时候可能会修改其他很多东西。
为了完成某个功能或者修改某个bug,可能我会修改sql语句或者service中方法,那么在修改前应先查看,谁调用了此方法或谁使用了此sql,如果一修改,虽然满足了当前bug或功能,但是原有逻辑,则被弄坏,而且是一定被弄坏了。而且不能轻易修改基础数据信息。
第二 : 退出系统后,应该留在系统登录页面的逻辑分析。
需求:location.herf = WEB_URL + "exam/" + tenantCode;
实现方式一:登录时,tenantCode存session,在examMain.jsp中取出来放在input中,hidden。然后js取。
实现方式二:logout,然后在controller中返回tenantCode字符串,解决方式,方便。注意,AngularJS取值后,在赋值给$scope.tenantCode = data;然后,var tenantCode = $scope.tenantCode ;最后直接是需求那句。AngularJS中的值不能同步,多想下数据在哪个具体位置取出,并且直接构成需求。
实现方式三:logout,然后在controller中return address;比如/exam/tenantCode;/exam/0003等。
方式分析:三个方式都可以满足功能需求,但是方式一很笨,把事情变得十分复杂。方式二要注意AngularJS中响应的值无法同步,注意代码顺序。方式三简单易明白。如果一个方式实现起来很难,应多想想可能逻辑不太合理。
第三 : 优化DashboardController及涉及到的service和DAO。
本次优化依据:1,一个controller中调用一个service。2,前台需要什么,后台直接传什么。
分析:关键是看是否控制数据库事务?首先,应明确当前这个业务逻辑下,是否是一个完整的事务,具体到每一个小逻辑的实现,它们之间是否有依赖关系?这样子就应该把当前逻辑放在一个事务下。但有的时候,一分析功能需求,发现这个实现其实不是一个事务,那么是可以在controller的一个方法中调用多个service,注意它们之间无依赖关系,并且它们都只是查询。这个service下的事务,也就是当前功能的实现是一个事务,则最好弄成一个service,并在主要的service中调用其他的service即可。并且一定分析好需求,究竟是事务好还是分开更合理,因为并没有统一标准,都是根据具体情况来的。其次,就是前台需要的是字符串,可是却传入了list。事物都是两面性的,如果是字符串则要考虑nullPointer情况。
第四 : 阅读别人代码后的感受。
浏览别人的java代码,发现他们对逻辑的严密性把握的很好。当然如果是一个系统的登录,后台java应用程序再一次对前台传来的数据进行校验,这是很好的,也是必须的。但是对一些功能,他们也这样子进行了严密性控制,后来仔细想想也是必须的,这个严密性控制也就是,对去数据库查询出来的数据类型,比如对象,List,字符串,只要是去数据库查询的,都进行了非null判断。有时候想想好像也没有必要吧,但是在深入思考,发现这样更好,整个程序更倾向于合理和正确。
第五 : 理解项目中的AnswerContainer和AnswerLister。
AnswerContainer.java :
1,从类名文件分析,这是答案的容器。也就是装答案的容器。
2,由于答案这个基础类很大,比如字段很多而且大,则思考单例。一个最简单的单例模式写法。
3,使用的是BlockingQuene接口,并且实现使用的是LinkedBlockingQuene。还有一个实现是ArrayBlockingQuene。
4,类中提供的方法是,offerAnswer(添加答案),这是自己定方法名,内部则调用BlockingQuene中的方法,来把答案这个对象,放入这个容器中。
5,pollAnswer(获取答案),isEmpty(判断答案是否为null)。
6,由于在实际使用中出现,学生的答案未保存上。而且这并不是个别了,一共有342个考生就出现了12个考生答案未保存上,它是这样的现象,一部分保存上,中间大量空白,最后一小部分又保存上,这是相对一个考生来说的现象。
7,个人分析,感觉是这个AnsweContainer这个最简单的单例模式出现了问题。并未考虑并发,当A这个考生获取了AnswerContainer这个对象,并在调用offerAnswer()方法的这个时刻,这个时刻B这个考生来了,一看AnswerContainer这个对象已经存在啦,很开心,然后努力跟A抢夺资源,虽然机会平等嘛,但是B这个考生呢,运气就是好,抢到了这个对象资源,然后很开始地调用了offerAnser()这个方法,开心地把答案保存上了。可是这个时刻呀,A这个考生是准备马上进行offerAnser()这个方法调用呀,根据JVM指令进行程序执行,它没有可执行的指令了,所以答案也没有保存上。所以呀,要考虑并发,当A考生在执行offerAnswer()时,给对象上锁,其他任何考生想要获取AnswerContainer这个对象并调用offerAnswer()时,都必须等待其他考生使用完后。性能估计有所下降,但是应该不会出现这种答案存储不上的情况。存储不上并不是因为有数据存储不上,而是答案这个对象并未放入在AnswerContainer中。
AnswerListener.java:
1,从类名来分析,答案监听。顾名思义,它可能在监听AnswerContainer这个容器。
2,这个类实现了ApplicationListener。
3,并重写了onApplicationEvent方法,在方法调用启动监听。
4,启动监听。
5,timer.schedule(new TimerTask() { 业务逻辑代码 })
6,设置好,多少秒扫描一次,一次扫描多少内内容。
7,这个就是真正地,对答案进行持久性写入。被写的数据,就是AnswerContainer这个容器中。
8,对上述现象,它应该不是原因,因为容器中有一般就可以被持久化。
AnswerContainer和AnswerListener配合使用,进行答案的暂时存储在容器中和一定时间后被持久化在数据库中。
第六 : 因为实际项目中对判断的依赖十分强,所以有必要再次强调判断的重要性。
1,一般,我们的思维是条件真,执行条件为真的语句;条件为假,执行条件为假的语句。
2,在实际应用中,有各种条件,各种状态,在程序满足不同条件和状态下,执行相应的语句。
3,判断。在实际应用中,是重中之重,因为项目总是会充斥着一般与特殊;总是充斥着不同,而不同就是判断的来源。
4,既然是判断,则可以正着判断,亦可进行反着判断。多思考,应根据想要的结果,反过来写判断条件。