面试小结
这一次面试没有想象中的那么压力山大,面试官也没有去死咬着某个知识点去提问,而是通过投递的简历来提问,其中计算机操作系统相关的题目较多,而我有对计算机系统方面的线程进程问题又比较了解,在这个部分表现得还算过得去,但是在于存储的方面我确实没有一个很好的实践积累,回答的大多都是在理论上的知识点,还有设备IO方面,我知道的也不是很多,面试官看我不是很清楚也就没有深挖。计算机网络相关的基础没有问到,不知道是不是看我的简历上有一两个网络编程的经验就跳过了。
缺少知识点:多线程相关的细节,Mysql,Redis,哈希表,红黑树
面试除了基础知识的提问,还考察了在设计项目上的思路,例如操作系统上如何去降低一个响应的时间:我除了进程之外也懂得不多,我就回答的是可以优化进程调度的一个策略,例如调整时间片大小,在线程之下创建亚线程。内存我直接不管了,另外加多CPU支持并行,多的我面试的时候也没有想到。
以下是AI生成的其他回答
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| I/O优化 异步I/O:用非阻塞I/O(如epoll、io_uring)替代同步阻塞调用。
缓冲和批处理:合并小I/O请求为大操作(如磁盘写合并)。
SSD/高速存储:替换机械硬盘,降低I/O延迟。
内核参数调优 调整调度器:如Linux的CFS(完全公平调度器)参数或改用实时调度策略(SCHED_FIFO)。
中断优化:启用中断负载均衡(irqbalance),或绑定中断到特定CPU。
亚线程/协程:将任务拆分为更轻量级的单元(如协程、用户态线程),减少阻塞。
CPU绑定(Affinity):将关键进程绑定到特定CPU核心,避免缓存失效和迁移开销。
|
网络相关场景题
还有在网络繁忙的时候该如何解决大量访问的问题,这里我回答的是一个限流,以下是常见的限流算法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 令牌桶(Token Bucket):
固定速率生成令牌,请求需消耗令牌(突发流量允许一定峰值)。
实现工具:Nginx limit_req、Redis + Lua脚本。
漏桶(Leaky Bucket):
请求以恒定速率处理(平滑流量,严格限制突发)。
固定窗口/滑动窗口计数:
统计单位时间内的请求数(如每分钟100次),滑动窗口更精确但开销略高。
自适应限流:
根据系统负载动态调整阈值(如CPU、队列长度),如Netflix的Hystrix。
|
以下是AI回答
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| 流量整形与负载均衡 队列缓冲:用消息队列(Kafka、RabbitMQ)异步处理请求,削峰填谷。
负载均衡:
横向扩展:增加服务实例,通过LB(如Nginx、HAProxy)分发流量。
智能路由:根据服务器负载动态分配请求(如Least Connections算法)。
服务降级与熔断 降级:关闭非核心功能(如推荐服务),返回缓存或默认值。
熔断:当错误率超过阈值时,短暂拒绝请求(如Hystrix、Resilience4j)。
服务隔离:将关键服务与非关键服务分离(如线程池隔离)。
缓存优化 多级缓存:
客户端缓存 → CDN → 服务端缓存(Redis)→ 数据库缓存。
热点数据预加载:提前缓存高频访问数据(如秒杀商品库存)。
弹性伸缩与云原生方案 自动扩缩容:Kubernetes HPA、AWS Auto Scaling。
Serverless:突发流量由无服务函数(如AWS Lambda)处理。
协议与连接优化 长连接复用:减少TCP握手开销(如HTTP/2、gRPC)。
压缩数据:减小传输体积(如Gzip、Protobuf)。
快速失败:设置超时时间(如TCP SYN队列调优)。
|
哈希表和红黑树
问题:“哈希表和红黑树有什么区别?如何选择?”
回答模板:
- 先对比核心特性:
“哈希表基于哈希函数,理想情况下查询是O(1)
,但可能因冲突退化;红黑树是自平衡二叉搜索树,稳定在O(log n)
,且支持有序遍历。”
- 提优缺点:
“哈希表内存占用大但查询快,适合字典类场景;红黑树更省内存且有序,适合范围查询。”
- 举例应用:
“比如Java的HashMap
用哈希表实现快速查找,而TreeMap
用红黑树保证键的有序性。”
- 哈希表如何解决冲突?
→ 拉链法(链表+红黑树,如Java 8的HashMap
)、开放寻址法。
- 红黑树 vs AVL树?
→ 红黑树牺牲严格平衡性换取更少的旋转操作,适合频繁插入删除的场景。
算法题目
有思路的,可惜没有写出来,以下是题目样例,具体的输入我想不起来了
我理解的这是一种压缩的方式:
例如字符串 ab[avv]{2}dd 代表的是 abavvavvdd,要求写一个算法输入字符串,输出对应的字符串,这一道题我的理解是将 [ 放入栈结构里面,记录右侧下表,遇到]时候弹栈,读取后面的循环次数(限制为2-9,不然更麻烦了),循环输出,但是这里有个重点是这样一个[ ] 是要求可以嵌套使用的,最后写出来的只能处理不嵌套的一种样式,以下是 AI生成的算法,学学看吧
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| package com.algorithm; import java.util.Stack;
public class Interview { public static void main(String[] args) { String s1 = "ab[avv]{2}dd"; System.out.println(decodeString(s1));
String s2 = "a[b[c]{2}]{3}d"; System.out.println(decodeString(s2)); }
public static String repeat(String str, int times) { if (times <= 0) { return ""; } StringBuilder sb = new StringBuilder(); for (int i = 0; i < times; i++) { sb.append(str); } return sb.toString(); }
public static String decodeString(String s) { Stack<StringBuilder> strStack = new Stack<>(); Stack<Integer> numStack = new Stack<>(); StringBuilder currentStr = new StringBuilder(); int i = 0; int n = s.length();
while (i < n) { char c = s.charAt(i); if (c == '[') { strStack.push(currentStr); currentStr = new StringBuilder(); i++; } else if (c == ']') { i++; if (i < n && s.charAt(i) == '{') { i++; if (i < n && Character.isDigit(s.charAt(i))) { int repeatTimes = s.charAt(i) - '0'; i++; if (i < n && s.charAt(i) == '}') { i++; } StringBuilder prevStr = strStack.pop(); String repeatedStr = repeat(currentStr.toString(), repeatTimes); prevStr.append(repeatedStr); currentStr = prevStr; } } } else { currentStr.append(c); i++; } }
return currentStr.toString(); } }
|
其实看起来还是有点困难的,主要还是我Java还没有学习到字符串相关的常用类String那里,哎,慢慢学吧