程序Bug的产生,通常分为三种类型

  1. 逻辑漏洞

    低级错误,程序执行后无法达到想要效果。

  2. 越界访问

    访问了非法区域,造成程序崩溃。

  3. 条件考虑不全面

    你以为你万无一失,但你永远都不知道输入参数究竟是什么!

如何防范未知Bug:异常捕获

异常捕获一般依靠try,catch语句。很好理解:try(尝试)一下,如果有问题,直接捕获 (catch)住,防止程序崩溃。

如果核心流程处理到一半服务器崩了怎么处理?

这里同时存在三个问题:

  • 问题排查以及快速恢复
  • 异常数据修复
  • 服务高可用,规避服务宕机

1、先抢通业务

当发现服务器宕机后,最关键的是抢通业务,而不是抢修服务器。

因此,需要做应急方案。最好准备2个网站服务器,他们存放的内容相同,而ip不同,并且机房的地理位置不同。这样第一时间发现宕机问题后,可以迅速的通过修域名记录,指向目前正常的网站空间。而且2个主机,同时宕机的可能性就大大降低了。

2、定位服务器崩溃原因

  • 内存溢出,磁盘资源耗尽
  • 线程死锁,进程过多或者不断创建,耗尽资源导致
  • 数据库慢查询,连接数过多,临时表不够用,程序死锁
  • 主备数据不一致
  • 应用程序异常
  • 流量负载过大
  • DOSS攻击
  • 散热问题

3、异常数据修复

  • 写数据做事务控制,保障数据安全。
  • 磁盘备份,重启服务时恢复数据。
  • 记录关键日志。

4、服务高可用

  • 服务多实例集群部署,负载均衡策略访问,做好服务降级、服务限流。
  • 数据库读写分离、分库分表方案。
  • 做好服务性能测试、压力测试。

开发中常见问题

空指针异常

在访问或操作对象之前,检查对象是否为null

类型转换异常

在进行类型转换之前,先检查对象的类型是否与目标类型兼容。

金额数值计算精度问题

金额一般都是用BigDecimal

循环条件错误

可能会导致死循环或者无法执行

文件操作异常

文件操作之前,先检查文件是否存在、是否可读写等。

事务不起作用没有回滚

异常被try.catch吃了,手动抛了别的异常Exception,默认情况下只会回滚RuntimeException

访问权限不是public;方法用final,static修饰;方法内部调用;

未开启事务;未被spring管理,需要创建bean实例。

内存溢出异常

在编写程序时,要注意控制内存的使用,及时释放不需要的对象。

性能问题

比如使用缓存、减少对象创建、优化算法等。

大数据量导出Excel存在问题及优化方案

问题1:一次性获取全部数据到内存当中,容易引起系统OOM。

解决方案:分页查询数据,分批处理。

问题2:分页查询存在深度分页问题,数据偏移量越大导致sqL查询变慢。

解决方案:使用标签记录优化(id自增且连续)、索引覆盖优化。

问题3:查询数据串行耗时长。

解决方案:可以通过线程编排,并行执行sql查询,最后顺序导出到excel。

问题4:一个excel文件数据过大,用户存在打不开的情况。

解决方案:通过easyexcel多sheet页导出数据。

如何保证接口幂等性?

概念:同一个接口,多次发出同一个请求,必须保证操作只执行一次。

什么情况下,会产生接口幂等性的问题?

  • 网络波动, 可能会引起重复请求
  • 用户重复操作,用户在操作时候可能会无意触发多次下单交易,甚至没有响应而有意触发多次交易应用
  • 使用了失效或超时重试机制(Nginx重试、RPC重试或业务层重试等)
  • 页面重复刷新
  • 使用浏览器后退按钮重复之前的操作,导致重复提交表单
  • 使用浏览器历史记录重复提交表单
  • 浏览器重复的HTTP请求
  • 定时任务重复执行
  • 用户双击提交按钮

如何保证接口幂等性?

  • 业务字段加唯一约束(简单)
  • 令牌+唯一约束(简单推荐)客户端每次在调用接口的时候,需要在请求头中,传递令牌参数(令牌可以存储到redis中),每次令牌只能用一次。一旦使用之后,就会被删除,这样可以有效防止重复提交。
  • mysql的insert ignore或者on duplicate key update(简单)
  • 共享锁+普通索引(简单)
  • 利用MQ或者Redis扩展(排队)
  • 同步锁(单线程,集群可能会失效)
  • 分布式锁如redis(实现复杂)
  • 其他方案如多版本控制MVCC 乐观锁 悲观锁 状态机等。。。

实际开发中,如何正确使用多线程?

  1. 处理并行任务:多线程可以同时处理多个任务,提高程序的执行效率。比如批量处理数据、同时上传多个文件等。
  2. 事件驱动的编程:Java多线程可以用于事件驱动的编程,如GUI、网络编程等。
  3. 并发访问共享资源:多线程可以应用于并发访问共享资源的场景,如数据库连接池。
  4. 高效的IO操作:在网络编程中,Java多线程可以提供高效的IO操作,如同时读写多个Socket。
  5. 多任务协同处理:在复杂的任务中,不同的任务可以以各自独立的方式并行运行,最终合并结果。
  6. 节约资源:多线程可以提高CPU和内存的使用效率,使得我们能够更好地利用系统资源。
  7. 提高用户体验:在一些高并发场景下,如网站、游戏等,使用多线程可以提高用户体验,使得用户能够更快地得到反馈。

常见的多线程问题包括

  1. 线程安全问题

    多个线程同时访问共享资源时可能导致数据不一致或异常。解决方案包括使用同步机制(如synchronized关键字、Lock对象)、使用线程安全的数据结构、避免共享状态等。
  2. 死锁问题

    多个线程因相互等待对方释放资源而无法继续执行。解决方案包括避免循环等待资源、按照固定顺序获取资源、设置超时时间等。
  3. 上下文切换问题

    线程切换需要耗费一定的时间和资源,如果线程频繁切换,会降低程序性能。解决方案包括合理设计线程数量、减少线程间的竞争、使用线程池等。
  4. 数据同步问题

    多个线程访问共享数据时,可能出现数据不一致的问题。解决方案包括使用锁来保证数据的原子性、使用volatile关键字保证可见性、使用线程安全的数据结构等。
  5. 过度创建线程问题

    创建线程需要消耗系统资源,如果过度创建线程,可能导致系统资源耗尽。解决方案包括使用线程池来复用线程、合理设置线程池大小等。

定时任务如果集群,如何保证不被重复执行?

  1. 独立部署,将定时任务独立出来,成为一个单独的项目工程,单一部署
  2. 配置实现,配置文件设置一个标识符号,定时任务读取此配置文件此属性, 读取到ture执行定时任务,否则不执行
  3. 利用分布式锁,虽然两个机器都会运行定时任务,但是一个时刻只有一台机器会真正的执行定时任务的核心方法

一个订单30分钟未支付自动取消功能,有几种实现方案?

  1. 数据库轮询

    该方案通常是在小型项目中使用,即通过一个线程定时的去扫描数据库,通过订单时间来判断是否有超时的订单,然后进行 update 或 delete 等操作。

    优点:简单易行,支持集群操作。

    缺点:对服务器内存消耗大;

    存在延迟,比如你每隔 3 分钟扫描一次,那最坏的延迟时间就是 3 分钟;

    假设你的订单有几千万条,每隔几分钟这样扫描一次,数据库损耗极大。

  2. JDK 的延迟队列

    该方案是利用 JDK 自带的 DelayQueue 来实现,这是一个无界阻塞队列,该队列只有在延迟期满的时候才能从中获取元素,放入 DelayQueue 中的对象,是必须实现 Delayed 接口的。

    优点:效率高,任务触发时间延迟低。

    缺点:服务器重启后,数据全部消失,怕宕机;集群扩展相当麻烦;代码复杂度较高;

    因为内存条件限制的原因,比如下单未付款的订单数太多,那么很容易就出现 OOM 异常。

  3. 时间轮算法

    时间轮算法可以类比于时钟,按某一个方向按固定频率轮动,每一次跳动称为一个 tick。

    优点:效率高,任务触发时间延迟时间比 delayQueue 低,代码复杂度比 delayQueue 低。

    缺点:服务器重启后,数据全部消失,怕宕机;集群扩展相当麻烦;

    因为内存条件限制的原因,比如下单未付款的订单数太多,那么很容易就出现 OOM 异常。

  4. Redis 缓存

    思路一:利用 Redis 的 zset,zset 是一个有序集合,每一个元素 (member) 都关联了一个 score, 通过 score 排序来取集合中的值。

    思路二:使用 Redis 的 Keyspace Notifications,中文翻译就是键空间机制,就是利用该机制可以在 key 失效之后,提供一个回调,实际上是 Redis 会给客户端发送一个消息。是需要 Redis 版本 2.8 以上。

    优点:由于使用 Redis 作为消息通道,消息都存储在 Redis 中。如果发送程序或者任务处理程序挂了,重启之后,还有重新处理数据的可能性;做集群扩展相当方便;时间准确度高。

    缺点:需要额外进行 Redis 维护。

  5. 使用消息队列

    可以采用 RabbitMQ 的延时队列。RabbitMQ可以实现延迟队列。

    优点:高效,可以利用 RabbitMQ 的分布式特性轻易的进行横向扩展,消息支持持久化增加了可靠性。

    缺点:本身的易用度要依赖于 RabbitMQ 的运维。因为要引用 RabbitMQ, 所以复杂度和成本变高。

为什么不用eureka非要用nacos作为注册中心?

nacos在自动或手动下线服务,使用消息机制通知客户端,服务实例的修改很快响应;Eureka只能通过任务定时剔除无效的服务。

nacos可以根据namespace命名空间,DataId,Group分组,来区分不同环境(dev,test,prod),不同项目的配置。

Mq如何保证消息不丢失?

丢数据一般分为两种,一种是mq把消息丢了,一种就是消费时将消息丢了。

Mq如何保证消息顺序的一致性?

如何避免消息一直堆积在mq服务器端?

在遇到消息堆积的时候,先检查下导致堆积的原因,可能有如下几种:

  1. 消费失败时大量重试导致消息堆积。
  2. 消费者程序的故障:如 程序死锁,io阻塞等。
  3. 消费者资源瓶颈:目前的主流消息队列,单个节点消息收发的性能可以达到万级别甚至10万级+的水平。除非容量预估没有做好,一般不会出现这种问题。即使出现这种问题,通过Scale Out Broker 的实例数也是比较轻松可以解决的。

消息堆积的解决方案:

  1. 提高消费者数量;更多的消费者将允许同时处理更多的消息,并减少消息堆积。
  2. 调整超时设置;例如,在某些情况下,因为某些原因(例如网络延迟),MQ 消费者需要等待更长时间才能接收到新的消息。
  3. 批量操作;例如,在生产者端,您可以使用管道来一次性发送多条信息。在消费者端,您可以使用批处理来一次性处理多个消息。
  4. 数据结构优化;例如,在使用MQ时,可以通过在消息中添加一些元信息来优化处理流程,或者采用更合适的数据结构存储消息,以减少在 MQ 中积累的消息数量。

Mq异步消费,如何获取到返回结果?

以下用Rabbit为例:

  1. 异步操作,获取回调消费结果,需要实现RabbitTemplate.ConfirmCallback 接口,然后重写 confirm()方法。
  2. 获取回调结果,指的是获取消息是否被消费端正常消费而返回的结果,并不是消费端返回的处理结果,这一点得注意,如果需要等待消费端返回处理结果,则需要做同步操作,而不是做回调操作。
  3. 需要做同步操作时,应该rabbitTemplate.convertSendAndReceive()方法,返回结果类型是Object,需要根据消费端返回的数据类型来决定强转的类型。
  4. 异步则使用rabbitTemplate.convertAndSend()方法。

常见业务功能实现技术选型

需求描述 技术选型
Excel、Word、Pdf文件操作 Apache POI,Spire,Asponse,EasyExcel,Stirling-PDF
在线文档编辑预览技术 OnlyOffice,OpenOffice
图片处理 Thumbnailator
分库分表中间件 ShardingSphere,Mycat,DBLE
任务调度 XXL-Job,Quartz,Elastic-Job,TBSchedule,Saturn
大数据同步 Datax,Otter,Canal
消息推送 WebSocket,Server-Sent Events
表达式引擎 JEXL,Aviator,jfireEL
模板引擎 Thymeleaf,Freemarker,Velocity,Beetl,Enjoy,JSP
前端框架 Vue,Angularjs,React,Bootstrap,LayUI,EasyUI,Jquery
报表开发 iReport,EasyReport,JimuReport,SpringReport,JFreeChart,ECharts
OA工作流审批 Activiti,Flowable,Jbpm,Osworkflow
MQ消息队列 ActiveMQ,RabbitMQ,RocketMQ,kafka
代码生成器 mybatis-plus-generator,EasyCode
接口文档 Knife4j,Swagger,Apifox,YApi,JApiDocs
数据库表结构文档生成工具 screw(螺丝钉),database-export
热门开发工具包 Hutool

Java开发常见问题分析和处理方案的更多相关文章

  1. 微信小程序开发常见问题分析

    距离微信小程序内测版发布已经有十几天的时间了,网上对微信小程序的讨论也异常火爆,从发布到现在微信小程序一直占领着各种技术论坛的头条,当然各种平台也对微信小程序有新闻报道,毕竟腾讯在国内影响力还是很大的 ...

  2. Web开发常规调试方法与常见问题分析

    一.Web项目基本原理 现在的web项目大都已经前后端独立开发与部署. 前后端独立开发,一般是前端与后端通过web接口(常见的有RESTful与websocket)文档进行交流.前端开发人员先更具业务 ...

  3. 《阿里巴巴Java开发手册》扫描插件正式发布--插件安装和使用分析

    "不管做什么,只要坚持下去就会看到不一样!在路上,不卑不亢!" 阿里巴巴于10月14日上午9:00在杭州云栖大会<研发效能峰会>上,正式发布<阿里巴巴Java开发 ...

  4. 2019最新最全Java开发面试常见问题答案总结

    2019最新最全Java开发面试常见问题答案总结 马上准备9月份出去面试Java开发,自己学习丢西瓜捡芝麻,学了的都忘了,所以有机会自己做个学习笔记,摘录自各个博文以及总结. 1.JAVA面向对象的特 ...

  5. Java开发网络安全常见问题

    Java开发网络安全常见问题 等闲识得东风面,万紫千红总是春 1.敏感信息明文传输 用户敏感信息如手机号.银行卡号.验证码等涉及个人隐私的敏感信息不通过任何加密直接明文传输. 如下图中小红书APP 的 ...

  6. 如何透彻分析Java开发人员

    第一部分:对于参加工作一年以内的同学.恭喜你,这个时候,你已经拥有了一份Java的工作. 这个阶段是你成长极快的阶段,而且你可能会经常加班.但是加班不代表你就可以松懈了,永远记得我说的那句话,从你入行 ...

  7. Linux(Ubuntu 16) 下Java开发环境的配置(二)------Tomcat的配置及常见问题

    前言 相比于java JDK的配置,Tomcat的配置简单的多,简直就相当于直接运行了,本文以Tomcat8.0为例进行配置   1.Tomcat的下载 地址:https://tomcat.apach ...

  8. JAVA开发相关

    JAVA开发相关1. IntelliJ IDEA开发工具熟练使用2. Maven3. Spring框架(IoC.AOP) 1)数据库相关MyBatis 2)数据库连接池 3)事务.多数据源.跨数据库分 ...

  9. 常用 Java 静态代码分析工具的分析与比较

    常用 Java 静态代码分析工具的分析与比较 简介: 本文首先介绍了静态代码分析的基 本概念及主要技术,随后分别介绍了现有 4 种主流 Java 静态代码分析工具 (Checkstyle,FindBu ...

  10. java开发常用jar包介绍(转载)

    jta.jar 标准JTA API必要 commons-collections.jar 集合类 必要 antlr.jar  ANother Tool for Language Recognition ...

随机推荐

  1. csapp-attacklab(完美解决版)

    注意:必须阅读Writeup,否则根本看不懂这个lab要怎么做 实验前准备 1.在终端中输入./ctarget和./rtarget结果报错 百度后得知自学的同学需要在执行文件时加上-q参数,不发送结果 ...

  2. jeecg-boot中分页接口用自定义sql和list实现

    1.controller中 @ApiOperation(value="分析仪工作状态和报警-3列-分页", notes="分析仪工作状态和报警状态-分页") @ ...

  3. 远程控制软件 TeamViewer 的局限性和替代方案

    TeamViewer 公司创建于2005年,总部位于德国,客户遍及全球,其中企业用户居多,其各方面性能都很不错,但价格却非常贵.针对个人用户,TeamViewer 提供免费版软件,但时不时会提示&qu ...

  4. Ubuntu 启用交换分区

    前言 交换分区也称之为 swap 分区,允许系统在内存不足的情况下将内存程序写入文件,防止系统卡死失去响应的情况发生. 检查现有交换分区 首先,确认系统中是否已存在交换分区或文件.在终端中输入以下命令 ...

  5. hadoop部署2

    完全分布式部署介绍 学习目标 完全分部式是真正利用多台Linux主机来进行部署Hadoop,对Linux机器集群进行规划,使得Hadoop各个模块分别 部署在不同的多台机器上. 能够了解完全分布式部署 ...

  6. salesforce零基础学习(一百三十七)零碎知识点小总结(九)

    本篇参考: https://help.salesforce.com/s/articleView?id=release-notes.rn_lab_conditional_visibiliy_tab.ht ...

  7. P1036 [NOIP2002 普及组] 选数

    传送锚点:https://www.luogu.com.cn/problem/P1036 题目描述 已知 \(n\) 个整数 \(x_1,x_2,\cdots,x_n\),以及 \(1\) 个整数 \( ...

  8. 一文搞懂C++继承、多继承、菱形继承、虚继承

    继承 目录 继承 继承 继承的访问权限 子类赋值给父类 赋值兼容规则 "天然"的行为 验证: 1. 其他权限继承能否支持赋值兼容规则 2.是否"天然",有没有产 ...

  9. 分享5款.NET开源免费的Redis客户端组件库

    前言 今天大姚给大家分享5款.NET开源.免费的Redis客户端组件库,希望可以帮助到有需要的同学. StackExchange.Redis StackExchange.Redis是一个基于.NET的 ...

  10. SwiftUI Stack中的View被压缩的效果

    一.背景 我们在布局中,经常会遇到视图元素排列时空间不足或者空间过大的情况,在这种场景下面,不同的布局方式有不同的方法: 绝对布局frame:纯靠计算过程控制,获取父视图的大小,根据需求,计算自己需要 ...