Terminal 4.

复盘

2026/04/14
loading

2026/4/14校招聘会复盘

SAP 外企,需要网上投递

海鼎, 没有技术交流

化工数字化,没有技术交流,说是学长学姐创立的公司(i can see from name

兴业数金,金融业,感觉是kpi!但是复盘。。。

  • 问项目里的threadlocal的生命周期,什么时候删除?为什么要删除?

  • 讲一下IO和NIO。(我不记得了!

    (B)IO是传统的 IO,是阻塞式的(Blocking),对于每个连接,都需要创建⼀个独⽴的线程来处理读写操作。

    NIO是非阻塞同步IO(Non-blocking),可以⽤⼀个线程处理多个客户端连接,通过 Selector 监听多个 Channel 来实现多路复⽤。还有缓冲区。

  • 问我有没有自己写synchronized或者lock?我说cas逻辑实现。。。(我草,这对吗

    他指的应该是自造lock,synchronized我不知道该怎么写

    那就是CAS+AQS

    首先,我需要一个全局可见的标志位来表示锁是否被占用。我会使用一个 volatile int state0 代表锁空闲。1 代表已被某个线程持有。 使用 volatile 是为了保证多线程间的可见性,确保每个线程都能实时看到最新的锁状态。

    当多个线程同时调用 lock() 时,我不能使用简单的 if(state == 0),因为这不具备原子性。 我会调用 Unsafe 类提供的 CAS (Compare And Swap) 方法。只有当 state 预期为 0 且成功将其修改为 1 的那个线程,才算真正拿到了锁。这保证了并发环境下的唯一性

    对于没有抢到锁的线程,我不能让它们一直死循环自旋(这会榨干 CPU),我会构建一个 FIFO(先入先出)的等待队列

    我会将当前线程封装成一个 Node 节点放入队列。然后调用 LockSupport.park() 方法挂起当前线程。此时线程进入阻塞状态,不再消耗 CPU 资源。

    当持有锁的线程执行完逻辑调用 unlock() 时:先将 state 重新设为 0。然后从等待队列的头部取出一个 Node,调用 LockSupport.unpark(thread)。 被唤醒的线程会重新尝试执行 CAS 操作去争抢锁。

  • Redis一般用来存什么数据?项目里存了什么数据?有没有做持久化?

  • 索引是不是越多越好?

  • 垃圾清除的方式了解吗?

好像没了。

东方海外货柜航运,这个好像是500强?虽然不是互联网。。。好像是外企?国企?,香港的。为什么这个公司消息这么少!

  • 技术交流之前,人事问我能不能做全栈(我:可以学.jpg)

  • 问我都上什么课

  • 项目是哪里来的

  • deepseek的流式响应是怎么样的?(只吐出来sse几个字,回答的不是很好

    DeepSeek 的流式响应底层基于 SSE 协议

    在我的项目中,我通过 Spring WebFlux 的 WebClient 异步消费这个流。之所以这么设计,是因为 AI 推理是一个长耗时过程,流式输出能将 TTFT(首字到达时间) 缩短到毫秒级,显著提升用户体验。

    具体的实现细节是:后端以响应式非阻塞的方式接收数据片,并实时转发给前端。这种‘随收随发’的模式避免了在 JVM 堆内存中缓存大段文本,保证了系统在高并发场景下的内存稳定性。同时,我也通过异步线程池和异常处理机制,确保了即使流式连接意外断开,后台资源也能被正确释放。

  • llm有没有本地部署?(答:只是用了api!

  • mybatis二级缓存清楚吗(不是很清楚!

    mybatis的一级缓存是缓存在每一个sqlsession内部的,而mybatis的二级缓存一般是一个mapper(namespace)里的sqlsession共享的。但是会有数据不一致的问题(比如遇到多表查询)(本地内存),所以一般都是把缓存放在redis里。

  • 有没有在用ai编程?知不知道国内这些ai有什么区别

好像没了。这个公司不会都是拷打项目不问八股吧??那真的完鸟()应该ai也会问挺多的。

到此我的简历投完了,还有一个日企和金融的没投,其他的都不对口,也许下次还有招聘会的话应该打印10张,开发还是要的挺多的。。

感想:回答的时候先思考一会儿再回答!

美的笔试复盘

编程题

  • 把aaabbbbccc转换为a3b4c3,只有一个字母的时候不要写数字

​ 最直观的方法就是遍历字符串,统计连续字符出现的次数

​ 拼接字符串的场景记得用stringbuilder

1
2
3
4
5
6
7
8
9
10
11
12
13
int count = 1; // 用于计数

for (int i = 0; i < s.length(); i++) {
// 如果当前字符是最后一个,或者当前字符和下一个字符不同
if (i + 1 == s.length() || s.charAt(i) != s.charAt(i + 1)) {
sb.append(s.charAt(i)); // 拼接字符
sb.append(count); // 拼接数字
count = 1; // 计数重置
} else {
// 如果和下一个字符相同,计数加1
count++;
}
}

其实我觉得这里的点是,因为你是往后看提前结束,所以count是从1开始的。

  • 很复杂的情景题但是没有什么思维量,把我吓跑了。。。忏悔中

    在该日历下的第X年,月Y满足是X最小素因数(当X等于1时Y等于1),一共有Z等于X + 233天,在前Y-1个月是Z/Y向下取整天,剩下的天数都在最后一个月(即第y月)。 一个星期同样是七天,已知第一年的一月一日是第一个星期的星期一。一共T组询问,每次询问第n星期一是该日历的哪年哪月哪

    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
    import java.util.Scanner;

    public class Main {
    public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    while (sc.hasNextLong()) {
    long n = sc.nextLong();
    // 第 n 个星期一距离 1年1月1日的天数 (1-based index)
    long targetDay = 1 + (n - 1) * 7;

    long currentX = 1;
    while (true) {
    long Y = getMinPrimeFactor(currentX);
    long Z = currentX + 233;

    if (targetDay <= Z) {
    // 答案就在这一年
    printResult(currentX, Y, Z, targetDay);
    break;
    }
    targetDay -= Z;
    currentX++;
    }
    }
    }

    // 获取最小素因数
    private static long getMinPrimeFactor(long x) {
    if (x == 1) return 1;
    if (x % 2 == 0) return 2;
    for (long i = 3; i * i <= x; i += 2) {
    if (x % i == 0) return i;
    }
    return x;
    }

    private static void printResult(long X, long Y, long Z, long dayInYear) {
    long dPrev = Z / Y;
    long currentMonth = 1;

    // 判定在哪个月
    while (currentMonth < Y) {
    if (dayInYear <= dPrev) {
    System.out.println(X + " " + currentMonth + " " + dayInYear);
    return;
    }
    dayInYear -= dPrev;
    currentMonth++;
    }
    // 在最后一个月
    System.out.println(X + " " + Y + " " + dayInYear);
    }
    }
  • 动态规划

好像和leecode42题差不多。

我算了一下,假设选择题用了10分钟,那就是80分钟写3道题,平均一道题是26分钟,感觉以后做题要计时了。

and这个是acm标准的输入输出,,,力扣做多了上手很不熟悉,,,

选择题

  • 对于“非静态内部类”(Member Inner Class),编译器会自动在构造器中传入外部类的引用。

    1
    2
    3
    4
    5
    6
    class Outer {
    class Inner {
    Inner() { // 看上去是无参构造器
    }
    }
    }

    编译器处理过后:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Outer$Inner {
    // 1. 自动生成一个指向外部类的 final 字段
    final Outer this$0;

    // 2. 构造器被修改,强制要求传入 Outer 引用
    Outer$Inner(Outer outer) {
    this.this$0 = outer;
    }
    }

    原因:

    1
    2
    Outer out = new Outer();
    Outer.Inner in = out.new Inner(); // 必须用 out 来 new

    因为内部类的构造器需要那个外部类引用,所以你必须通过 out.new 来告诉 Java把 out 这个实例传给 Inner 的构造器

    但是静态内部类不会传

    如果内部类的生命周期比外部类长(比如在内部类里开了一个异步线程),那么即使外部类不再使用了,由于内部类构造器自动传入并持有了 this$0 引用,外部类也将永远无法被 GC 回收。

  • 内部类可以使用外部类的私有成员(当然!)

  • boolean是作为int处理的,但是在数组里不是

  • 还有一个execute不知道他在说什么!

  • 关于aqs他说了很多源码的词,我从功能上判断他们应该都是对的

  • this()和super()不可以同时出现,super()必须在代码的第一行。

  • 联合索引又称组合索引

  • 255.255.252.0每个子网的主机数量最多可以有多少台?

    第一步:将掩码转换为二进制

    子网掩码 255.255.252.0 的二进制表示如下:

    • 255: 11111111
    • 255: 11111111
    • 252: 11111100
    • 0 : 00000000

    组合起来就是:

    1
    11111111.11111111.11111100.00000000

    第二步:确定主机位(Host Bits)

    在掩码中,1 代表网络位,0 代表主机位。

    • 我们可以看到,末尾共有 10 个零(第三段有 2 个,第四段有 8 个)。
    • 因此,主机位数量 n = 10。

    第三步:套用公式计算

    每个子网的总 IP 地址数为 2^n。但由于每个子网中有 2 个特殊地址不能分配给主机,必须扣除:

    1. 网络地址(主机位全为 0)
    2. 广播地址(主机位全为 1)

    计算公式:

    1
    2
    3
    $$ \text{主机数量} = 2^n - 2 $$

    $$ 2^{10} - 2 = 1024 - 2 = 1022 $$

所以,每个子网最多可以有 1022 台主机。

  • 英特网服务提供商的英文缩写:ISP,Internet Service Provider

怎么这么多计算机网络的内容?!

CATALOG
  1. 1. 2026/4/14校招聘会复盘
  • 美的笔试复盘
    1. 1. 编程题
    2. 2. 选择题
      1. 2.0.1. 第一步:将掩码转换为二进制
      2. 2.0.2. 第二步:确定主机位(Host Bits)
      3. 2.0.3. 第三步:套用公式计算