论坛首页 Java企业应用论坛

人在江湖:如何用代码保护好自己

浏览 45572 次
该帖已经被评为良好帖
作者 正文
   发表时间:2011-10-14  
好帖啊
同样的事情,每个人的看法都不一致。

还是要具体问题具体分析的。
0 请登录后投票
   发表时间:2011-10-14  
严重的学习了。请问如果LZ创建的精灵线程发现超时后,会自动释放该精灵线程所占用的内存?假如这个精灵线程正在等待其他资源而引起了超时,该精灵线程是否会被销毁?
0 请登录后投票
   发表时间:2011-10-14   最后修改:2011-10-14

引用

人感觉,从纯技术角度上看,楼主的做法其实属于治标不治本,实在是丑陋的架构和管理手法下不得已采用的丑陋做法。

从风险一的应对措施来看,这段代码一次性不管三七二十一把所有Exception都catch起来,加上了一段没有任何业务语义的描述 (An error occured during XXX之类,如果方法名称起得好的话,从异常的调用栈里就能得到同样的信息。如果你觉得这种异常信息有用,有三种可能:1. 你打算让这条异常一直抛到用户界面上去,显示异常信息。或者 2.你所在的团队没有仔细看异常调用栈的习惯。或者 3.你们的代码类名和方法名起得不知所谓。) ,然后包装成另一个Unchecked Exception抛出来。正常来说,只要在架构的高层位置有一个大的try catch统一来干这个事情,这里就根本不用管。
。。。。。。。。。。。。。。。。

大哥,我觉得你分析的非常好,无论是从代码上 还是管理上,都让我认识到了一些工作中关键点,非常感谢!!向你学习
0 请登录后投票
   发表时间:2011-10-14  
   LZ写的不错,记得以前做告警,经常被测试提单说告警丢失,最后发现是使用开源组件的问题,以后凡是掉别人接口都打日志,之后就没单了。
0 请登录后投票
   发表时间:2011-10-14  
非常好。
那些强调加强管理,代码走查之类的固然有道理,但是很多原因导致了你做不了这事:
1 老板不支持重构遗留代码
2 遗留代码连源代码都没有
3 积重难返的项目管理问题
4 你控制不了的第三方系统
...
我们以前做计费系统也这样,计费数据来自于之前填写的所有表单,业务进行中产生的数据,一旦有漏填和填错计算结果肯定不对,一开始只要计算不对就找我们,后来再调用其他Service获得计算所需数据时统统加上了日志和异常记录,将计算过程透明化,这样再也不用计费模块的开发者苦苦追查,结果是生产,订单等模块出现的错误了。

多些异常控制,特别是当你认为一旦出了这个错一定是调用的模块出了问题了,你就明确的抛出异常,这样排错方便多了。而且这些异常都是应该跟业务相关的,所以AOP也帮不上什么忙。
1 请登录后投票
   发表时间:2011-10-14  
LZ 在代码上标志,画图,用的什么工具?
0 请登录后投票
   发表时间:2011-10-14  
hommy8 写道
严重的学习了。请问如果LZ创建的精灵线程发现超时后,会自动释放该精灵线程所占用的内存?假如这个精灵线程正在等待其他资源而引起了超时,该精灵线程是否会被销毁?

会释放的。这个测试过了,可以把代码拿下来测试下,有些地方我可能还没有想到。


0 请登录后投票
   发表时间:2011-10-14  
步青龙 写道
LZ 在代码上标志,画图,用的什么工具?

用的是snagit,一个抓图软件,抓完图会自动打开编辑窗口。
0 请登录后投票
   发表时间:2011-10-14  
kidneyball 写道
个人感觉,从纯技术角度上看,楼主的做法其实属于治标不治本,实在是丑陋的架构和管理手法下不得已采用的丑陋做法。

从风险一的应对措施来看,这段代码一次性不管三七二十一把所有Exception都catch起来,加上了一段没有任何业务语义的描述 (An error occured during XXX之类,如果方法名称起得好的话,从异常的调用栈里就能得到同样的信息。如果你觉得这种异常信息有用,有三种可能:1. 你打算让这条异常一直抛到用户界面上去,显示异常信息。或者 2.你所在的团队没有仔细看异常调用栈的习惯。或者 3.你们的代码类名和方法名起得不知所谓。) ,然后包装成另一个Unchecked Exception抛出来。正常来说,只要在架构的高层位置有一个大的try catch统一来干这个事情,这里就根本不用管。

通用的异常处理应该放在高层,通常底层代码是不用管更底层的代码抛出的RuntimeException的,除非:
1. 你有处理这个异常的具体方法(也就是在你的层面看,这个根本不是异常,而是业务的一部分)。
2. 你认为这段代码的调用者有能力处理这个异常,你就应该把这个异常封装成一个Checked Exception再抛出去。
3. 你为这个异常加入更具业务语义的message再抛出去。

从发现错误的角度看,一前一后两个log已经解决所有问题了,这里的异常处理纯属多余。除非,你的上层代码把异常吃掉了(既没日志又没继续往上抛),这纯属是做架构的人胡闹,害人不浅(如果你能拿到他们的代码,把吃异常的地方找出来,追究责任时可以拿来说事)。

不过就算是上层代码不可控,楼主也应该在可控的范围内把这种通用的异常处理往高层放,不用在底层搞那么多层层叠叠的try catch。

第二个风险的应对也不是正路,你开了新线程去调别人的东西,超时了你的线程就异常终止了,另一条线程还在跑呀(就算你强行kill了这条新线程,你也不知道黑箱里有没有再开新线程,或者通过异步方式干其他东西,例如读写数据库之类),它跑的结果怎么样,有没有什么副作用你都不管了。你这个异常终止之后,整个系统就处于一种未知状态了,后面的操作还怎么做,干脆直接Runtime.exit()再重新启动还安全一点。

既然别人的包本来预期是同步使用的,而且你不知道它的运行细节,把它强行改为异步没什么好处。如果你怕别人的包死锁,一般来说也是一前一后两个log就能发现问题了。感觉你在这里有点贪心,除了想发现错误,还想搞点错误恢复,但异步调用不能这么简单处理的。但如果要处理好,成本太高了。

从管理角度看,也很有问题:

1. 自己人的代码还搞什么黑箱。我一般都要求程序员如果调用不是自己写的接口,至少要往下看三层实现代码,包括别人的代码和开源代码。如果要修改代码,需要先往上找出所有调用关系并阅读代码,保证不会修改了一条调用路径上的bug却把另外的调用路径搞死了。如果是黑箱代码(我所在的项目基本没有),除非有完善的技术支持或者口碑非常好,否则一律不用,而且调用黑箱代码的前后必须做好日志。违反者一经发现,口头鄙视。

2. 找人负责也不是不行,但也不能老板越过技术主管直接找程序员的麻烦吧。不懂技术(甚至懂技术,但不了解具体上下文)的人直接批评程序员,往往只找到了表面现象就开骂(例如楼主说的李四),等到找到真正原因,又挂不住面子,反而更不爽你。楼主举的例子,我想象的场景是这样的:老板问张三,你这个语音模块怎么回事,这么卡。张三就说,具体不清楚,不过我调用了李四的包,可能跟这个有关系(典型的推卸责任)。然后老板就问李四,你怎么回事,李四说具体不清楚,能不能告诉我怎样重现错误,我调试一下(典型的认真负责)?老板一个笔记本拍李四脸上:去死吧你,就是你这个害群之马,人头猪脑。。。。(省略一百字)。这种搞法怎么能管好技术团队?

好在楼主说是上一家公司,估计已经脱离苦海了吧,恭喜恭喜。

=======================================
补充一点。。。
我本来想这种方法调用的日志其实最好用debug或trace级别,放在info级别,岂不是逼人在生产环境下关闭info级别的日志(我循环调用一个黑箱方法100次就会看到200条重复的日志,再来50个用户并发访问。。。)。不过后来想想也有道理,这里的日志不是为了查错,而是为了在第一时间撇清责任,等到发现错误再打开日志就太晚了。所以说丑陋的管理导致丑陋的代码。。。


这位大哥说的甚好,学习了。
一个简单的问题大家一讨论竟然如此深奥,各有千秋啊。

我稍微总结一下:
1. LZ的猎狗式代码很有创意和想法(仅仅是技术上的),但是不提倡用:开启线程会有系统开销,而且异步情况不好控制,对后期维护和调试也不好。
2. LZ的try{}catch{}也不提倡:LZ的目的只是为了保护自身,能给自己有力的证明,像有几位说的,如果只是要找到问题所在前后一个log日志即可,不要去捕捉别人不确定的异常(除非要求你处理)----这里对做架构的人来讲要注意异常处理的设计
3. 代码编写时注意自己的方法应该抛出什么异常,是否需要处理

最后:
1. 程序编写者---调用别人的代码时,前后加log,便于找出问题,也保护自身---自己写代码时考虑一下可能会出现的异常和处理方式(向上抛或重新封装或....)
2. 架构者---注意异常捕捉和处理系统的设计
3. 管理者---....
0 请登录后投票
   发表时间:2011-10-14  
有些领域是需要更加的小心,要在产品开发的各个环节当中都要更多的关注程序的安全性。金融领域还好只是金钱上的损失,要是医疗或其它涉及到人身安全行业的系统,如果是因为代码上的一些错误出人命,那就更难收场了。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics