今天我们的高级开发工程师张晓培将会带领大家一起探索开发中遇到的各种问题,
培哥(法号:西街恶人)用诙谐幽默的言语为大家迅速打开了开发的大门,
从走入Web Development、继续探索Web Server以及Pair Programming三个方面共同领略开发的魅力。
CargoWare开发问题集锦
——培哥
走入前端世界
万恶的NullPointerException
Memory爆了
Flex开发中所使用的ActionScript语言(简称AS)也是一种支持GC的语言。
经过编译后的AS代码运行在AS虚拟机(简称AVM)中,由AVM自动完成垃圾内存回收的工作;
Flash Player垃圾回收工作是由垃圾回收器(garbage collection)完成的,运行在后台的一个Process;
AS采用两种方法来判定一个对象是否还有活动的引用,从而决定是否可以将其回收。
一种方法是引用计数法,另一种方法是标记清除法。
Memory Leak原因举例
引用泄露:对子对象的引用,外部对本对象或子对象的引用都需要置null ;
系统类泄露:使用了系统类而忘记做删除操作了,如BindingUtils.bindSetter() ,ChangeWatcher.watch() 函数时候
完毕后需要调用ChangeWatcher.unwatch() 函数来清除引用,否则使用此函数的对象将不会被删除;
类似的还有MUSIC ,VIDEO ,IMAGE ,TIMER ,EVENT ,BINDING 等。
效果泄露:当对组件应用效果Effect 的时候,当本对象本删除时需要把本对象和子对象上的Effect 动画停止掉,
然后把Effect 的target 对象置null; 如果不停止掉动画直接把Effect 置null 将不能正常移除对象。
SWF 泄露:要完全删除一个SWF 要调用它的unload() 方法并且把对象置null;
图片泄露:当Image 对象使用完毕后要把source 置null;( 为测试) ;
声音、视频泄露: 当不需要一个音乐或视频是需要停止音乐,删除对象,引用置null。
Memory Leak解决方法
在组件的REMOVED_FROM_STAGE 事件回掉中做垃圾处理操作(移除所有对外引用(不管是VO 还是组件的都需要删除),
删除监听器,调用系统类的清除方法),先remove 再置null, 确保被remove 或者removeAll 后的对象在外部的引用全部释放干净;
利用Flex 的性能优化工具Profile 来对项目进程进行监控,可知道历史创建过哪些对象,
目前有哪些对象没有被删除,创建的数量,占用的内存比例和用量,创建过程等信息。
正确的使用集合
Flex中集合有Array、ArrayCollection、Vector,
以下是插入和遍历10000项性能对比:
插入10000项
Array耗时:465
ArrayCollection耗时:788
Vector耗时:444
遍历10000项
Array耗时:2
ArrayCollection耗时:98
Vector耗时:2
Array与Vector性能接近,插入时Vector略快,遍历相近,
Vector的优点是强类型,缺点是要Flash Player 10,所以作数据存储运算等建议使用Array。
ArrayCollection性能最差,插入时约比Array慢了一倍,遍历慢了几十倍,
ArrayCollection的优势是界面的数据绑定以及支持数据排序等高级方法。
我们可以更快
①Load on demand ②返回指定的字段
③Minimum nested ④使用正确的组件
继续探索后端
Hibernate自动更新的坑
之前有个开发的同学遇到一个问题,跑来问培哥,hibernate查询出来的对象集合,
根据业务需要遍历赋值,结果赋值的对象都会更新到数据库...
在培哥看来,这明显是有问题的。
在查看日志后发现,系统总是会打印出一个update语句,
说明系统的确是执行了更新操作的,但是这里并没有调用任何和update相关的方法。
通过hibernate中hql查询出的实体都是持久化对象,拿到该对象后,如果调用了该对象的set方法,
那么在事务递交的时候,Hibernate会把设置的值自动更新到数据库中。
如何处理这个问题?
采用getCurrentSession().evict(entity),懒加载获取的实体后,
通过调用evict(entity)的方法,把缓存持久化对象变成托管状态。
变成托管状态后,Hibernate就不会再去自动更新该实体。
什么是懒加载?以及他的作用
延迟加载,也叫懒加载,它是Hibernate为提高程序执行效率而提供的一种机制,即只有真正使用该对象的数据时才会创建。
当我们要修改这个对象的数据时,可能会发生no session的错误,
这是因为事务已经提交session已经关闭,而我们还要去查询数据库,所以hibernate就报错。
解决方案
通过对象的主键查询一次数据库赋给新的对象,再进行数据操作。
高效操作LIST
查找不同元素
两层遍历查找,遍历次数为list1.size()*list2.size(),有点蠢;
两层遍历查找,用retainAll()方法查找,也很蠢,方法底层依旧是两层遍历;
用Map存放List1和List2的元素作为key,value为其在List1和List2中出现的次数。
学以致用
查询结果需要计算某个字段;计算交集、差集。
发现更新结果不对
ExecuteUpdate介绍
executeUpdate用来执行HQL的更新或者删除语句。
返回结果为整数型,可能有些时候程序会根据更新的返回结果来执行下一步操作,
这会导致判断不正确,具体要看程序配置mysql链接useAffectedRows设置是否正确;
useAffectedRows的含义 :是否用受影响的行数替代查找到的行数来返回数据,也就是查找到了 但却不一定真正修改了。
结对编程
什么是结对编程?
在此模式下,一对程序员并肩作战,平等互补进行开发工作。
两个程序员并排坐在一台电脑前,同对一台显示器,使用同一个键盘,同一个鼠标进行工作。
一起分析,一起测试,一起设计,一起编程。
结对编程的好处
互相鼓励,不容易沮丧;互相监督,不容易偷懒;互相学习编程技巧;
可以培养和训练新人;多双眼睛,少点 bug。
结对编程的坏处
1、与合不来的人一起编程容易发生争执,不利于团队和谐;
2、经验丰富的老手可能会对新手产生不满的情绪;
3、一山不容二虎,开发者之间可能就某一问题发生分歧,产生矛盾,造成不必要的内耗;
4、开发人员可能会在工作时交谈一些与工作无关的事,分散注意力,造成效率低下。
什么时候采用结对编程?
最主要的因素是技术与挑战相匹配。
在独自编程中,如果技能和挑战能互相匹配,最高产的模式就是流模式。
结对编程添加了一个更有效的模式——指导模式,它能够提高全队当前与未来任务的生产率。
A)成功的模式
1. 流模式(Flow)——两个程序员共同从事一个有趣又有挑战性的问题。
他们会有不同的技术、遇到不同的挑战,但是它们都善于找到好的解决方法。
例如,其中 一个人可能是javascript专家,另一个人可能是强大的后台程序员。
他们能够结合彼此的脑力、知识及经验来共同处理复杂的AJAX任务,从而创造出 最好的解决方案。
2. 指导模式(Coaching)——老练的程序员在解决问题方面有经验和知识,可以与其他不能有效地独自解决问题的程序员分享。
后来加入的程序员有足够的理论基础来理解这些解决方法和程序的实现。他会在学习中慢慢进步,成为更优秀的程序员。
B)失败的模式
3. 浪费专家时间(Wasting expert time)——问题太简单,以致专家的经验无指导意义
4. 不知所措的新手(Overwhelmed novice)——问题太过复杂或者需要太多新知识,使程序员学不到任何有用的东西。
C)有疑问的模式
5. 两个专家共事一个易管理的任务——若两个程序员都了解如何实现任务并且之前都成功地解决过相似的问题,那么结对编程就没有太多的用处了。
6. 一个程序员处于流模式(Flow),另一个在一旁学习(Learning)——若另一个程序员时不时地打断他,
并要求对一些基本的但与挑战性问题没有直接关系的事情做出解释,那么他很难专注于解决挑战性的问题。
7. 一个程序员处于流模式,另一个专注于指导(Coaching)——如果想让这种模式获得成功,指导者应该思想开放,避免指导过多,
同时也可以给另一个程序员想出自己的(甚至是更好的)解决方法的机会。
END
专家招募活动进行中~
WallTech诚邀我们的客户大佬们
成为常年客座讲师传道受业解惑
有想要报名的大佬们欢迎联系市场部哦~
科技改变生活,也在改变我们的工作!
CargoWare一小步,
货代转型一大步!
如此方便快捷的工具!
还不速速来一套?