解惑

解己之惑,解人之惑

标签:方法

得到当前方法

在写代码的时候我们可能会需要当前的方法名,特别是在输出一些调试信息的时候,但是如果使用字符串硬写的话不太好,API好像也不带对应的功能,如果细心的话,异常信息里面是带出错的方法名的,我们可以dump stack trace并分析得到当前方法的方法名,实际上有更好的方法,和dump stack trace类似:
public static String getCurrentMethodName() {
    StackTraceElement element=Thread.currentThread().getStackTrace()[3];
    return element.getClassName()+"."+element.getMethodName();
}
为什么是3呢?从0到2分别是:
java.lang.Thread.dumpThreads
java.lang.Thread.getStackTrace
xxx.Xxxx.getCurrentMethodName:也就是你定义这个工具方法的类

Google面试题解说性能之总结

呵呵,说了这么多,到底怎么优化性能还是没有说多少,而且一个产品的代码比这个例子复杂得多,怎么才能优化产品代码呢?
很简单,找到性能瓶颈,而大部分的性能瓶颈都有一个特点:被执行的次数太多。一个耗时2分钟的操作,如果系统运行一天才需要运行一次,那么我们根本就不要去理会它,如果一个操作耗时2秒,但是一般运行一天它要被执行几千亿次,那么你就要小心了。
如何才能知道系统中的哪些代码被执行的次数最多呢?有很多工具可以,有的是挂到系统上一起运行,有的是可以单独运行,但是我推荐的方法就是使用单元测试工具和代码覆盖工具,运行所有的单元测试,查看代码覆盖报告中被执行的次数最多的那些语句,看看他们是否可以被优化,或者可以被减少执行的次数。
可以参考我以前的一些日志:
Ant+JUnit+Cobertura
成功提高20倍性能

很多情况下,找到性能的瓶颈并不是很困难,真正困难的是如何进行优化。这个没有通用的解决方法,只能结合具体的问题具体解决,一个大部分情况下有效的方法是使用某种缓存机制(实际上,我的第二个例子也是使用了缓存机制,把运算结果缓存了9次)。

  1. Google面试题解说性能之一:字符串运算VS数字运算

  2. Google面试题解说性能之二:分析问题

  3. Google面试题解说性能之三:不要小看循环中的任何一个语句

  4. Google面试题解说性能之四:优化无止境

  5. Google面试题解说性能之五:人比电脑聪明

  6. Google面试题解说性能之六:数学显神威

  7. Google面试题解说性能之七:缓存中间结果

  8. Google面试题解说性能之八:工欲善其事必先利其器

  9. Google面试题解说性能之总结

提高Java技能的几种简单有效的方法

这个问题可能是很多做Java的人最关心的,特别是新手,而且我原来也写过一些东西,现在我再简单的列举一些简单但是行之有效的方法:

  • 上各个技术论坛看别人的帖子,特别是那些回复数或者点击数比较高的帖子,回复数高说明讨论激烈,很可能有高手在当中切磋,点击数高说明这个是大家很关心的,你以后很可能也会遇到或者用得上。
  • 尝试帮助别人解决问题,特别是你没有遇到过,但是你知道原因或者你懂得其中的原理,在这个过程中,你可以逐步的培养自己解决问题的能力、经验以及自信心。
  • 多看别人写的代码,无论是高手还是新手,从高手的代码你可以学习东西,从新手的代码中,你可以尝试去修改他的代码,让这个代码更加的高效、通用、简单,总之就是尽可能优化,直到你自己感觉很满意。
  • 注意积累自己的代码库,有时候是一个简单的方法,有时候可能是一个小的功能块,有时候甚至是一个比较大的子系统,以后自己要写一个系统,或者要设计一个系统,甚至你遇到设计问题的时候,你都可以到这些代码库中寻找思路甚至是直接拿来用。最重要的是,无论你认为自己的公司多么的差,多么的没有技术含量,你所在的项目肯定会有有价值的代码。(但是要注意,不要仅仅拷贝一份代码,要抽取你能够理解,并认为有价值的部分)
  • 多看书,系统的看书,不要浅尝辄止,要看那些经典的书。程序设计风格、设计模式、OO、重构都是必看的。
  • 最后也是最重要的是,遇到问题,要尽量去了解为什么会出现这样的问题,而不是仅仅停留在解决问题的层次。

如果你有信心并且确实可以在一个月之内找到一份满意的工作,你基本上可以算是高手(高手不一定高薪,但是温饱应该问题不大)了

最后是关于时间,众所周知,新手都会面临一个先有鸡还是先有蛋的问题,公司都要求你有经验,但是新手没有,所以你一定是一个蛋,你要把你的全部时间都花在提高自己上,少看些新闻,多看些书、看些帖子吧,当然,要花一些时间在锻炼身体上(呵呵,这个是我现在最大的感受)。关于加班,尽量避免,有两个方法,一个是提高自己的效率(使用合适的工具辅助,工欲善其事必先利其器),另外一个就是多思考你的那些工作是重复性的,怎么样可以少写一些代码。

条条大路通罗马

今天在写测试的用例的时候发现框架的一个Bug,CMP在初始化Entity Bean的时候会自动初始化相关的Entity Bean,但是如果是在一对多的情况下,首先使用的如果是一那端的情况下,不会自动的初始化多那一端的Entity Bean,后来添加了代码修正这个问题后,发现原来只要2分钟运行的所有的测试用例要15分钟才能运行完了,跟踪了一下发现是其中一个测试用例所使用的Entity Bean会连带初始化其他十几个Entity Bean,而且其中有几个Entity Bean的初始数据非常的多,每一个都有300条数据,这样要初始化好需要3分钟,而每个test方法都会来这么一次初始化。后来想着加Cache,Entity Bean填充好以后就缓存起来,后面的test方法再需要初始化的时候就直接进行对象拷贝就可以了,但是Entity Bean在使用的时候会修改一些值,这样如果发生变化的话应该从Cache里面清除,而且需要连带清除所有的Entity Bean。原来缓存的是MockEJB动态创建的Proxy对象,所以要进行对象复制不容易,看了MockEJB的源代码本来想自己也创建一个新的Proxy对象进行复制保存,但是工作量比较大,后来想到的解决的办法就是把对象的属性都复制到一个Map里面,主键是属性的名字,值就是对象值,如果值是集合类型,那么要创建一个同样的集合类并发那个集合里面的全部值加进去。

上面是我在公司的时候的解决方案,在写这篇日志的时候,又想到可能的其他方法,例如初始化Entity Bean的时候不初始化相关的其他的Entity Bean,只有在需要的时候才初始化(增加一个BaseGetterAspect,就像其他的Aspect一样);另外就是在发布Entity Bean的时候不初始化所有的Entity Bean实例,只有在需要使用到那个实例的时候再初始化。当然这两个也不是那么简单就可以实现的,明天还要再好好的考虑下哪种最保险最简单。

在遇到一个问题的时候,解决方案是多种多样的,只要你敢想。:)

© 2024 解惑

本主题由Anders Noren提供向上 ↑