大多数开发人员理所当然地以为性能优化很复杂,需要大量的经验和知识。好吧,不能说这是完全错误的。优化应用程序以获得最佳性能不是一件容易的事情。但是,这并不意味着如果你不具备这些知识,就不能做任何事情。这里有11个易于遵循的建议和最佳实践可以帮助你创建一个性能良好的应用程序。大部分建议是针对Java的。但也有若干建议是与语言无关的,可以应用于所有应用程序和编程语言。在讨论专门针对Java的性能调优技巧之前,让我们先来看看通用技巧。
1.在你知道必要之前不要优化
这可能是最重要的性能调整技巧之一。你应该遵循常见的最佳实践做法并尝试高效地实现用例。但是,这并不意味着在你证明必要之前,你应该更换任何标准库或构建复杂的优化。在大多数情况下,过早优化不但会占用大量时间,而且会使代码变得难以阅读和维护。更糟糕的是,这些优化通常不会带来任何好处,因为你花费大量时间来优化的是应用程序的非关键部分。那么,你如何证明你需要优化一些东西呢?首先,你需要定义应用程序代码的速度得多快,例如,为所有API调用指定最大响应时间,或者指定在特定时间范围内要导入的记录数量。在完成这些之后,你就可以测量应用程序的哪些部分太慢需要改进。然后,接着看第二个技巧。
2.使用分析器查找真正的瓶颈
在你遵循第一个建议并确定了应用程序的某些部分需要改进后,那么从哪里开始呢?你可以用两种方法来解决问题:
-
查看你的代码,并从看起来可疑或者你觉得可能会产生问题的部分开始。
-
或者使用分析器并获取有关代码每个部分的行为和性能的详细信息。
希望不需要我解释为什么应该始终遵循第二种方法的原因。很明显,基于分析器的方法可以让你更好地理解代码的性能影响,并使你能够专注于最关键的部分。如果你曾使用过分析器,那么你一定记得曾经你是多么惊讶于一下就找到了代码的哪些部分产生了性能问题。老实说,我第一次的猜测不止一次地导致我走错了方向。
3.为整个应用程序创建性能测试套件
这是另一个通用技巧,可以帮助你避免在将性能改进部署到生产后经常会发生的许多意外问题。你应该总是定义一个测试整个应用程序的性能测试套件,并在性能改进之前和之后运行它。这些额外的测试运行将帮助你识别更改的功能和性能副作用,并确保不会导致弊大于利的更新。如果你工作于被应用程序若干不同部分使用的组件,如数据库或缓存,那么这一点就尤其重要。
4.首先处理最大的瓶颈
在创建测试套件并使用分析器分析应用程序之后,你可以列出一系列需要解决以提高性能的问题。这很好,但它仍然不能回答你应该从哪里开始的问题。你可以专注于速效方案,或从最重要的问题开始。速效方案一开始可能会很有吸引力,因为你可以很快显示第一个成果。但有时,可能需要你说服其他团队成员或管理层认为性能分析是值得的——因为暂时看不到效果。但总的来说,我建议首先处理最重要的性能问题。这将为你提供最大的性能改进,而且可能再也不需要去解决其中一些为了满足性能需求的问题。常见的性能调整技巧到此结束。下面让我们仔细看看一些特定于Java的技巧。
5.使用StringBuilder以编程方式连接String
有很多不同的选项来连接Java中的String。例如,你可以使用简单的+或+ =,以及StringBuffer或StringBuilder。那么,你应该选择哪种方法?答案取决于连接String的代码。如果你是以编程方式添加新内容到String中,例如在for循环中,那么你应该使用StringBuilder。它很容易使用,并提供比StringBuffer更好的性能。但请记住,与StringBuffer相比,StringBuilder不是线程安全的,可能不适合所有用例。你只需要实例化一个新的StringBuilder并调用append方法来向String中添加一个新的部分。在你添加了所有的部分之后,你就可以调用toString()方法来检索连接的String。下面的代码片段显示了一个简单的例子。在每次迭代期间,这个循环将i转换为一个String,并将它与一个空格一起添加到StringBuilder sb中。所以,最后,这段代码将在日志文件中写入“This is a test0 1 2 3 4 5 6 7 8 9”。
StringBuilder sb = new StringBuilder(“This is atest”);for (int i=0; i<10; i++) {sb.append(i);sb.append(” “);}log.info(sb.toString());
正如在代码片段中看到的那样,你可以将String的第一个元素提供给构造方法。这将创建一个新的StringBuilder,新的StringBuilder包含提供的String和16个额外字符的容量。当你向StringBuilder添加更多字符时,JVM将动态增加StringBuilder的大小。如果你已经知道你的String将包含多少个字符,则可以将该数字提供给不同的构造方法以实例化具有定义容量的StringBuilder。这进一步提高了效率,因为它不需要动态扩展其容量。
6.使用+连接一个语句中的String
当你用Java实现你的第一个应用程序时,可能有人告诉过你不应该用+来连接String。如果你是在应用程序逻辑中连接字符串,这是正确的。字符串是不可变的,每个字符串的连接结果都存储在一个新的String对象中。这需要额外的内存,会减慢你的应用程序,特别是如果你在一个循环内连接多个字符串的话。在这些情况下,你应该遵循技巧5并使用StringBuilder。但是,如果你只是将字符串分成多行来改善代码的可读性,那情况就不一样了。
Query q = em.createQuery(“SELECT a.id, a.firstName, a.lastName ”+ “FROM Author a ”+ “WHERE a.id = :id”);
在这些情况下,你应该用一个简单的+来连接你的字符串。Java编译器会对此优化并在编译时执行连接。所以,在运行时,你的代码将只使用1个String,不需要连接。
7.尽可能使用基元
避免任何开销并提高应用程序性能的另一个简便而快速的方法是使用基本类型而不是其包装类。所以,最好使用int来代替Integer,使用double来代替Double。这允许JVM将值存储在堆栈而不是堆中以减少内存消耗,并作出更有效的处理。
8.试着避免BigInteger和BigDecimal
既然我们在讨论数据类型,那么我们也快速浏览一下BigInteger和BigDecimal吧。尤其是后者因其精确性而受到大家的欢迎。但是这是有代价的。BigInteger和BigDecimal比简单的long或double需要更多的内存,并且会显著减慢所有计算。所以,你如果需要额外的精度,或者数字将超过long的范围,那么最好三思而后行。这可能是你需要更改以解决性能问题的唯一方法,特别是在实现数学算法的时候。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
最后
本人也收藏了一份Java面试核心知识点来应付面试,借着这次机会可以送给我的读者朋友们
目录:
Java面试核心知识点
一共有30个专题,足够读者朋友们应付面试啦,也节省朋友们去到处搜刮资料自己整理的时间!
Java面试核心知识点
已经有读者朋友靠着这一份Java面试知识点指导拿到不错的offer了
一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算
Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算**