Java业务开发常见错误100例【1-30】

1、Tomcat的工作线程是基于线程池的,线程池会重用固定的几个线程,一旦线程重用,那么很可能首次从ThreadLocal获取的值是之前其他用户的请求遗留的值。这时,ThreadLocal中的用户信息就是其他用户的信息。使用类似ThreadLocal工具来存放一些数据时,需要特别注意在代码运行完后,显式地去清空设置的数据

2、大量写的场景(10万次add操作),CopyOnWriteArray几乎比同步的ArrayList慢一百倍;在大量读的场景下(100万次get操作),CopyOnWriteArray又比同步的ArrayList快五倍以上

3、静态字段属于类,类级别的锁才能保护;而非静态字段属于类实例,实例级别的锁就可以保护

4、即使我们确实有一些共享资源需要保护,也要尽可能降低锁的粒度,仅对必要的代码块甚至是需要保护的资源本身加锁

5、如果业务逻辑中锁的实现比较复杂的话,要仔细看看加锁和释放是否配对,是否有遗漏释放或重复释放的可能性;并且对于分布式锁要考虑锁自动超时释放了,而业务逻辑却还在进行的情况下,如果别的线程或进程拿到了相同的锁,可能会导致重复执行。

6、线程池默认的工作行为:

不会初始化corePoolSize个线程,有任务来了才创建工作线程;

当核心线程满了之后不会立即扩容线程池,而是把任务堆积到工作队列中;

当工作队列满了后扩容线程池,一直到线程个数达到maximumPoolSize为止;

如果队列已满且达到了最大线程后还有任务进来,按照拒绝策略处理;

当线程数大于核心线程数时,线程等待keepAliveTime后还是没有任务需要处理的话,收缩线程到核心线程数

7、要根据任务的“轻重缓急”来指定线程池的核心参数,包括线程数、回收策略和任务队列:

对于执行比较慢、数量不大的IO任务,或许要考虑更多的线程数,而不需要太大的队列。

而对于吞吐量较大的计算型任务,线程数量不宜过多,可以是CPU核数或核数*2(理由是,线程一定调度到某个CPU进行执行,如果任务本身是CPU绑定的任务,那么过多的线程只会增加线程切换的开销,并不能提升吞吐量),但可能需要较长的队列来做缓冲。

8、JedisPool是线程安全的连接池,Jedis是非线程安全的单一连接。知道了原理之后,我们再使用Jedis就胸有成竹了。如果多个线程在执行操作,那么既无法确保整条命令以一个原子操作写入Socket,也无法确保写入后、读取前没有其他数据写到远端

9、对类似数据库连接池的重要资源进行持续检测,并设置一半的使用量作为报警阈值,出现预警后及时扩容。

9、连接超时参数ConnectTimeout,让用户配置建连阶段的最长等待时间;通常可以认为出现连接超时是网络问题或服务不在线,而出现读取超时是服务处理超时

读取超时参数ReadTimeout,用来控制从Socket上读取数据的最长等待时间。读取超时指的是,向Socket写入数据后,我们等待Socket返回数据的超时时间

通过ribbon发送get请求,会有自动重试的机制,可通过设置:ribbon.MaxAutoRetriesNextServer=0,或者改为post请求。

10、spring事务@Transaction生效的前提:

1)除非特殊配置(比如使用AspectJ静态织入实现AOP),否则只有定义在public方法上的@Transactional才能生效

2)必须通过代理过的类从外部调用目标方法才能生效

11、强烈建议你在开发时打开相关的Debug日志,以方便了解Spring事务实现的细节,并及时判断事务的执行情况。通过JPA访问数据库可通过logging.level.org.springframework.orm.jpa=DEBUG打开

12、事务即便生效也不一定能回滚

通过AOP实现事务处理可以理解为,使用try…catch…来包裹标记了@Transactional注解的方法,当方法出现了异常并且满足一定条件的时候,在catch里面我们可以设置事务回滚,没有异常则直接提交事务。

这里的“一定条件”,主要包括两点。

第一,只有异常传播出了标记了@Transactional注解的方法,事务才能回滚。(或者手动回滚:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();)

第二,默认情况下,出现RuntimeException(非受检异常)或Error的时候,Spring才会回滚事务。(可通过@Transactional(rollbackFor = Exception.class)检测所有异常)

13、出了异常事务不一定回滚;不出异常,事务也不一定可以提交

14、聚簇索引、二级索引、B+树、回表、成本计算

B+树的特点包括:

最底层的节点叫作叶子节点,用来存放数据;

其他上层节点叫作非叶子节点,仅用来存放目录项,作为索引;

非叶子节点分为不同层次,通过分层来降低每一层的搜索量;

所有节点按照索引键大小排序,构成一个双向链表,加速范围查找。

15、额外创建二级索引的代价:

1)维护代价

2)空间代价

3)回表的代价

16、索引失效的情况:

1)索引只能匹配列前缀

2)条件涉及函数操作无法走索引

3)联合索引只能匹配左边的列

17、对于自定义的类型,如果要实现Comparable,请记得equals、hashCode、compareTo三者逻辑一致。

18、使用BigDecimal表示和计算浮点数,请务必使用字符串的构造方法来初始化BigDecimal:

浮点数的字符串格式化也要通过BigDecimal进行

19、BigDecimal的equals比较的是BigDecimal的value和scale,如果我们希望只比较BigDecimal的value,可以使用compareTo方法

20、不能直接使用Arrays.asList来转换基本类型数组

Arrays.asList返回的List不支持增删操作

对原始数组的修改会影响到我们获得的那个List

List list = new ArrayList(Arrays.asList(arr));

21、使用List.subList进行切片操作居然会导致OOM?

22、MySQL中sum函数没统计到任何记录时,会返回null而不是0,可以使用IFNULL函数把null转换为0;

MySQL中count字段不统计null值,COUNT(*)才是统计所有记录数量的正确方式。

MySQL中使用诸如=、<、>这样的算数比较操作符比较NULL的结果总是NULL,这种比较就显得没有任何意义,需要使用IS NULL、IS NOT NULL或 ISNULL()函数来比较。

23、捕获和处理异常容易犯的错

1)不在业务代码层面考虑异常处理,仅在框架层面粗犷捕获和处理异常

2)捕获了异常后直接生吞

3)丢弃异常的原始信息

4)抛出异常时不指定任何消息

24、捕获了异常打算处理的话,除了通过日志正确记录异常原始信息外,通常还有三种处理模式:

1)转换,即转换新的异常抛出。对于新抛出的异常,最好具有特定的分类和明确的异常消息,而不是随便抛一个无关或没有任何信息的异常,并最好通过cause关联老异常。

2)重试,即重试之前的操作。比如远程调用服务端过载超时的情况,盲目重试会让问题更严重,需要考虑当前情况是否适合重试。

3)恢复,即尝试进行降级处理,或使用默认值来替代原始数据。

25、

1)虽然try中的逻辑出现了异常,但却被finally中的异常覆盖了

2)千万别把异常定义为静态变量(把异常定义为静态变量会导致异常信息固化,这就和异常的栈一定是需要根据当前调用来动态获取相矛盾)

3)提交线程池的任务出了异常会怎么样?(从线程名的改变可以知道因为异常的抛出老线程退出了,线程池只能重新创建一个线程。如果每个异步任务都以异常结束,那么线程池可能完全起不到线程重用的作用),execute提交的任务会这样,submit提交的任务,只有在获取执行结果的时候才会抛出异常(既然是以submit方式来提交任务,那么我们应该关心任务的执行结果,否则应该以execute来提交任务)

修复方式有2步:

以execute方法提交到线程池的异步任务,最好在任务内部做好异常处理;

设置自定义的异常处理程序作为保底,比如在声明线程池时自定义线程池的未捕获异常处理程序:

26、配合使用标记和EvaluatorFilter,实现日志的按标签过滤,是一个不错的小技巧

27、使用Logback提供的AsyncAppender即可实现异步的日志记录

28、在进行文件IO处理的时候,使用合适的缓冲区可以明显提高性能

29、默认情况下,在反序列化的时候,Jackson框架只会调用无参构造方法创建对象

30、定义的static的SimpleDateFormat可能会出现线程安全问题,比较好的解决方式是,通过ThreadLocal来存放SimpleDateFormat:

private static ThreadLocal<SimpleDateFormat> threadSafeSimpleDateFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/687380.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

opencv源码编译及配置完整版教程(win10+vs2019+opencv-4.4.0+opencv_contrib-4.4.0)收藏

opencv源码编译及配置完整版教程&#xff08;win10vs2019opencv-4.4.0opencv_contrib-4.4.0&#xff09; https://blog.csdn.net/zhoufm260613/article/details/126107994

使用Python生成二维码的完整指南

无边落木萧萧下&#xff0c;不如跟着可莉一起游~ 可莉将这篇博客收录在了&#xff1a;《Python》 可莉推荐的优质博主首页&#xff1a;Kevin ’ s blog 本文将介绍如何使用Python中的qrcode库来生成二维码。通过简单的代码示例和详细解释&#xff0c;读者将学习如何在Python中轻…

突发!测试OpenAI新产品——sora

哈喽大家好&#xff0c;我是chowley&#xff0c;最近sora真是垄断了科技区的话题榜&#xff0c;几乎每个技术博主都上来讲两句 我在半年前也是一名深度学习的研究者&#xff0c;今天我以测试开发工程师的视角来解读一下sora&#xff01; 首先打开OpenAI官网的sora页面&#x…

春节专题|产业7问:区块链厂商的现在和未来——混合技术厂商

2023转瞬即逝&#xff0c;不同于加密领域沉寂一整年后在年末集中爆发&#xff0c;对于我国的区块链厂商而言&#xff0c;稳中求胜才是关键词&#xff0c;在平稳发展的基调下&#xff0c;产业洗牌也悄无声息的到来。 从产业总体而言&#xff0c;在经过了接近3年的快速发展后&…

解决vitepress首次加载慢(从40秒到1秒的倔强)

前言&#xff1a;在艰难的博客系统升级之路 这篇博客中我有提到vitepress首次加载非常耗时的问题&#xff0c;之前也在网上搜索时发现也有很多人说这个“问题”&#xff0c;但是在折腾了这么一段时间后&#xff0c;发现这也许本身不是vitepress的问题&#xff0c;而是我的启动方…

【Java多线程】线程中几个常见的属性以及状态

目录 Thread的几个常见属性 1、Id 2、Name名称 3、State状态 4、Priority优先级 5、Daemon后台线程 6、Alive存活 Thread的几个常见属性 1、Id ID 是线程的唯一标识&#xff0c;由系统自动分配&#xff0c;不同线程不会重复。 2、Name名称 用户定义的名称。该名称在各种…

Arduino程序简单入门

文章目录 一、结构1.1 setup()1.2 loop() 二、结构控制2.1 if2.2 if...else2.3 switch case2.4 for2.5 while2.6 do...while2.7 break2.8 continue2.9 return2.10 goto 三、扩展语法3.1 ;&#xff08;分号&#xff09;3.2 {}&#xff08;花括号&#xff09;3.3 //&#xff08;单…

百度地图接口 | 实现校验收货地址是否超出配送范围

目录 1. 环境准备 2. 代码开发 2.1 application.yml 2.2 OrderServiceImpl &#x1f343;作者介绍&#xff1a;双非本科大三网络工程专业在读&#xff0c;阿里云专家博主&#xff0c;专注于Java领域学习&#xff0c;擅长web应用开发、数据结构和算法&#xff0c;初步涉猎Py…

数据结构-双指针法

介绍 双指针法是一种可以在O&#xff08;n&#xff09;时间复杂度内解决数组、链表、字符串等数据结构相关的问题的方法。核心思想为使用两个指针在不同位置遍历数组或链表&#xff0c;从而实现特定操作。 常见的双指针法有 1.快慢指针&#xff1a;快指针每次移动两步&…

AI:131- 法律文件图像中的隐含信息挖掘与敲诈勒索检测

🚀点击这里跳转到本专栏,可查阅专栏顶置最新的指南宝典~ 🎉🎊🎉 你的技术旅程将在这里启航! 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带有在本地跑过的关键代码,详细讲解供…

天锐绿盾|防泄密系统|计算机文件数据\资料安全管理软件

“天锐绿盾”似乎是一款专注于防泄密和计算机文件数据/资料安全管理的软件。在信息安全日益受到重视的今天&#xff0c;这样的软件对于保护企业的核心数据资产和防止敏感信息泄露至关重要。 通用地址&#xff1a;www.drhchina.com 防泄密系统的主要功能通常包括&#xff1a; 文…

[前端开发] 常见的 HTML CSS JavaScript 事件

代码示例指路 常见的 HTML、CSS、JavaScript 事件代码示例 常见的 HTML CSS JavaScript 事件 事件HTML 事件鼠标事件键盘事件表单事件 JavaScript 事件对象事件代理&#xff08;事件委托&#xff09; 事件 在 Web 开发中&#xff0c;事件是用户与网页交互的重要方式之一。通过…

LeetCode405. Convert a Number to Hexadecimal

文章目录 一、题目二、题解 一、题目 Given an integer num, return a string representing its hexadecimal representation. For negative integers, two’s complement method is used. All the letters in the answer string should be lowercase characters, and there …

二进制和进制转换

前言 我们经常能听到2进制、8进制、10进制、16进制这样的讲法&#xff0c;那是什么意思呢&#xff1f;其实2进制、8进 制、10进制、16进制是数值的不同表示形式而已。 比如&#xff1a;数值15的各种进制的表示形式&#xff1a; 15的2进制&#xff1a;111115的8进制&#xff1…

阅读笔记(BMSB 2018)Video Stitching Based on Optical Flow

参考文献 Xie C, Zhang X, Yang H, et al. Video Stitching Based on Optical Flow[C]//2018 IEEE International Symposium on Broadband Multimedia Systems and Broadcasting (BMSB). IEEE, 2018: 1-5. 摘要 视频拼接在计算机视觉中仍然是一个具有挑战性的问题&#xff0…

完成端口的看法

很早之前使用过完成端口&#xff0c;当时觉得是很不错的技术。但是后来发现用的地方并不多&#xff0c;对它也有些自己的想法&#xff0c;仁者见仁智者见智。 应用场景上&#xff0c; 个人觉得&#xff0c;iocp有些鸡肋&#xff0c;一般的应用用不上&#xff0c;复杂的程序…

wps使用方法(包括:插入倒三角符号,字母上面加横线,将word中的所有英文设置为time new roman)

倒三角符号 字母上面加横线 将word中的所有英文设置为time new roman ctrla选中全文

语音唤醒——

文章目录 配置主代码 参考文档&#xff1a;https://picovoice.ai/docs/quick-start/porcupine-python/ 配置 pip install pvporcupine主代码 ACCESS_KEY&#xff1a;需要将该参数填入即可 # # Copyright 2018-2023 Picovoice Inc. # # You may not use this file except in …

人机协同中的感应与响应

人机协同中的感应与响应是指人与机器之间的互动过程中&#xff0c;机器对人的动作、行为、情感等进行感知&#xff0c;并根据这些感知信息作出相应的反应。感应是指机器能够通过传感器、摄像头等设备感知到人的动作、语音、表情等信息&#xff0c;将其转化为数字信号或数据&…

MySQL事务的概念

一、事务定义 事务&#xff1a;事务是一个最小的不可在分的工作单元&#xff1b;通常一个事务对应一个完整的业务(例如银行账户转账业务&#xff0c;该业务是一个最小的工作单元)一个完整的业务需要批量的DML(insert、update、delete)语句共同联合完成。事务只和DML语句有关&a…