Java笔试关键要点梳理
1. 无第三方组件实现类Kafka消息队列的设计要点
在不借助第三方组件的情况下构建类似Kafka的消息队列,需从以下方面开展设计:
明确功能需求
首先得明确消息队列要达成的核心功能,同时对需处理的消息类型、预计的消息数量以及消息的处理速率等进行剖析。
选取架构模式
依据前期明确的需求与功能,从Pub/Sub模式、队列模式、管道模式等架构模式中挑选适配的模式。
规划存储方案
根据消息自身特性以及处理需求,在内存存储、磁盘存储、数据库存储等存储方式里选定合适的方案。
设计消息传输协议
确定消息传输所采用的协议,例如TCP、UDP或者HTTP等。
构建消息处理机制
实现消息的接收、入队、出队、分发以及处理等流程的机制。
设定消息确认机制
让消费者能够向消息队列反馈成功处理消息的时间,可通过在消息队列中添加确认机制来实现。
完善错误处理机制
当消息处理失败时,需有错误处理机制来重新处理该消息或者将其发送至错误队列进行后续处理。
实施负载均衡机制
当存在多个消费者时,运用负载均衡机制来分配消息。
保障高可用与容错性
设计并实现高可用和容错机制,确保消息队列在面对各种异常状况时能稳定运行。
打造监控与管理机制
设计并实现监控和管理机制,方便管理员对消息队列的状态和运行情况进行监控。
支持扩展与升级
设计并实现扩展和升级机制,以便后续能对消息队列的功能进行扩展和升级。
2. JVM系统卡顿的定位方法
当运行在JVM上的系统出现卡顿现象时,可按以下步骤定位问题:
区分卡顿出现的位置
首先要判定系统卡顿是出现在远程服务器端还是客户端调用方。
远程服务器端卡顿的排查
- 查看日志:查看远程系统的机器服务日志,获取相关信息。
- 分析日志数据:对远程服务器的操作数据日志进行剖析,收集服务器错误信息,包括服务器是否经常宕机、服务器节点压力值、处理数据的读写I/O、磁盘利用率、不同时间段的服务器请求数量等,以此分析卡顿缘由,如是否存在线程安全问题(并发、死锁等)、服务是否为单体项目且未做分布式微服务处理导致用户量过大、服务器节点服务在数据库访问方面是否有问题、后台服务接口数据处理是否存在缺陷等;同时检查网络方面,如网络阻塞、网络安全问题(丢包、数据传输错误等)、网络带宽是否过窄、网络数据流量是否过大、数据链光缆等物理设备是否故障、数据报文是否错误以及网络是否通畅等。
- 反馈问题:向远程服务器的服务提供方提供出错信息,等待对方反馈。
客户端调用方数据异常的排查
- 检查前端限流:查看前端是否有限流情况,若流量过大则考虑进行服务拆分。
- 查看后端线程请求:检查后端服务是否存在线程请求阻塞状况。
- 监控集群节点:若服务是集群部署的,需对服务器集群节点信息进行监控。
- 优化数据库相关:考虑数据库数据量过大导致查询过慢的情况,可对数据查询过慢的操作代码进行优化、对数据库表和索引库进行优化、实施数据库分布式处理(如分区、分库、分节点、读写分离等)。
- 检查内存情况:查看是否存在内存过载的情况。
- 排查编码问题:排查程序员的后台服务编码是否存在问题,如代码处理数据的性能不高。
硬件因素排查
还要考虑硬件方面的因素,如CPU和计算机节点存储设备、网络连接设备是否出现故障或性能不佳,以及是否存在异常和安全故障等情况。
3. 超大数相加的代码实现
下面是实现两个任意长度超大数相加的代码:
@Test
public void testBig() {
System.out.println(bigAdd("123456789", "9999999999999999999999999"));
}
public static String bigAdd(String a, String b) {
char[] charsA = new StringBuilder(a).reverse().toString().toCharArray();
char[] charsB = new StringBuilder(b).reverse().toString().toCharArray();
int maxLength = Math.max(charsA.length, charsB.length);
int[] result = new int[maxLength + 1];
int temp = 0;
for (int i = 0; i <= maxLength; i++) {
temp = result[i];
if (i < charsA.length) {
temp += charsA[i] - '0';
}
if (i < charsB.length) {
temp += charsB[i] - '0';
}
if (temp >= 10) {
temp -= 10;
result[i + 1] = 1;
}
result[i] = temp;
}
StringBuilder sb = new StringBuilder();
boolean flag = true;
for (int i = maxLength; i >= 0; i--) {
if (result[i] == 0 && flag) {
continue;
}
flag = false;
sb.append(result[i]);
}
return sb.toString();
}
该代码通过将输入的字符串反转处理,逐位进行相加并处理进位情况,最终得到两个超大数相加的结果。
相关文章
暂无评论...