1727 字
9 分钟
面试小结

面试小结#

这一次面试没有想象中的那么压力山大,面试官也没有去死咬着某个知识点去提问,而是通过投递的简历来提问,其中计算机操作系统相关的题目较多,而我有对计算机系统方面的线程进程问题又比较了解,在这个部分表现得还算过得去,但是在于存储的方面我确实没有一个很好的实践积累,回答的大多都是在理论上的知识点,还有设备IO方面,我知道的也不是很多,面试官看我不是很清楚也就没有深挖。计算机网络相关的基础没有问到,不知道是不是看我的简历上有一两个网络编程的经验就跳过了。

缺少知识点:多线程相关的细节,Mysql,Redis,哈希表,红黑树

面试除了基础知识的提问,还考察了在设计项目上的思路,例如操作系统上如何去降低一个响应的时间:我除了进程之外也懂得不多,我就回答的是可以优化进程调度的一个策略,例如调整时间片大小,在线程之下创建亚线程。内存我直接不管了,另外加多CPU支持并行,多的我面试的时候也没有想到。

以下是AI生成的其他回答

 I/O优化
异步I/O:用非阻塞I/O(如epoll、io_uring)替代同步阻塞调用。

缓冲和批处理:合并小I/O请求为大操作(如磁盘写合并)。

SSD/高速存储:替换机械硬盘,降低I/O延迟。

内核参数调优
调整调度器:如Linux的CFS(完全公平调度器)参数或改用实时调度策略(SCHED_FIFO)。

中断优化:启用中断负载均衡(irqbalance),或绑定中断到特定CPU。

亚线程/协程:将任务拆分为更轻量级的单元(如协程、用户态线程),减少阻塞。

CPU绑定(Affinity):将关键进程绑定到特定CPU核心,避免缓存失效和迁移开销。

网络相关场景题#

还有在网络繁忙的时候该如何解决大量访问的问题,这里我回答的是一个限流,以下是常见的限流算法

令牌桶(Token Bucket):

固定速率生成令牌,请求需消耗令牌(突发流量允许一定峰值)。

实现工具:Nginx limit_req、Redis + Lua脚本。

漏桶(Leaky Bucket):

请求以恒定速率处理(平滑流量,严格限制突发)。

固定窗口/滑动窗口计数:

统计单位时间内的请求数(如每分钟100次),滑动窗口更精确但开销略高。

自适应限流:

根据系统负载动态调整阈值(如CPU、队列长度),如Netflix的Hystrix。

以下是AI回答

流量整形与负载均衡
队列缓冲:用消息队列(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队列调优)。

哈希表和红黑树#

问题“哈希表和红黑树有什么区别?如何选择?” 回答模板

  1. 先对比核心特性: “哈希表基于哈希函数,理想情况下查询是O(1),但可能因冲突退化;红黑树是自平衡二叉搜索树,稳定在O(log n),且支持有序遍历。”
  2. 提优缺点: “哈希表内存占用大但查询快,适合字典类场景;红黑树更省内存且有序,适合范围查询。”
  3. 举例应用: “比如Java的HashMap用哈希表实现快速查找,而TreeMap用红黑树保证键的有序性。”
  • 哈希表如何解决冲突? → 拉链法(链表+红黑树,如Java 8的HashMap)、开放寻址法。
  • 红黑树 vs AVL树? → 红黑树牺牲严格平衡性换取更少的旋转操作,适合频繁插入删除的场景。

算法题目#

有思路的,可惜没有写出来,以下是题目样例,具体的输入我想不起来了

我理解的这是一种压缩的方式:

例如字符串 ab[avv]{2}dd 代表的是 abavvavvdd,要求写一个算法输入字符串,输出对应的字符串,这一道题我的理解是将 [ 放入栈结构里面,记录右侧下表,遇到]时候弹栈,读取后面的循环次数(限制为2-9,不然更麻烦了),循环输出,但是这里有个重点是这样一个[ ] 是要求可以嵌套使用的,最后写出来的只能处理不嵌套的一种样式,以下是 AI生成的算法,学学看吧

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));  // 输出: abavvavvdd

        String s2 = "a[b[c]{2}]{3}d";
        System.out.println(decodeString(s2));  // 输出: abccbccbccd
    }

    // 手动实现的字符串重复方法(兼容 Java 8)
    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 == ']') {
                // 遇到 ']', 准备读取 '{n}'
                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++;  // 跳过 '}'
                        }
                        // 弹出栈顶状态并使用自定义的repeat方法
                        StringBuilder prevStr = strStack.pop();
                        String repeatedStr = repeat(currentStr.toString(), repeatTimes);  // 使用自定义repeat
                        prevStr.append(repeatedStr);
                        currentStr = prevStr;
                    }
                }
            } else {
                // 普通字符,直接追加
                currentStr.append(c);
                i++;
            }
        }

        return currentStr.toString();
    }
}

其实看起来还是有点困难的,主要还是我Java还没有学习到字符串相关的常用类String那里,哎,慢慢学吧

面试小结
https://thrinisty.github.io/Blog/posts/面试小结/
作者
Thrinisty
发布于
2025-03-27
许可协议
CC BY-NC-SA 4.0