SAP后端实习开发面试:操作系统与网络核心考点及Linux与Redis

0 阅读26分钟

今天看学长面试了西安SAP公司,写一篇面经记录

这里就省略自我介绍,直接上干货

Q1:虚拟内存管理是什么?(计算机操作系统)

A1:

虚拟内存管理是现代操作系统(如 Linux、Windows)的核心机制之一,它通过抽象物理内存,为每个进程提供一个连续、隔离、大小统一的虚拟地址空间,从而解决内存碎片、安全隔离、多任务并发等问题。

为什么需要虚拟内存?

如果没有虚拟内存,程序直接操作物理地址会面临:

  • ❌ 内存碎片:分配/释放后物理内存不连续,大对象无法分配
  • ❌ 进程互相干扰:一个进程写错地址可能破坏其他进程数据
  • ❌ 无法运行大于物理内存的程序
  • ❌ 安全风险:任意进程可读写内核或其他进程内存

虚拟内存解决了这些问题。


核心思想:地址空间隔离 + 按需映射

每个进程都拥有自己独立的 虚拟地址空间(例如 64 位 Linux 下通常是 128TB),但这些地址并不直接对应物理内存,而是通过 页表(Page Table) 由 CPU 的 MMU(Memory Management Unit) 动态映射到物理内存或磁盘。

✅ 对进程来说:内存是“连续”的
✅ 对 OS 来说:物理内存可以“离散”分配


关键机制详解

1. 分页(Paging)

  • 虚拟内存和物理内存都被划分为固定大小的 页(Page) ,通常为 4KB(也有 2MB、1GB 的大页)
  • 虚拟页(Virtual Page) → 通过页表 → 物理页帧(Physical Frame)

2. 页表(Page Table)

  • 每个进程有一个页表,记录虚拟页到物理页的映射关系
  • 页表本身也存储在内存中,由 CR3 寄存器指向当前进程的页目录基址
  • 为提高效率,CPU 提供 TLB(Translation Lookaside Buffer) 缓存最近的映射

3. 缺页中断(Page Fault)

当进程访问一个尚未加载到物理内存的虚拟页时:

  1. CPU 触发 缺页异常(Page Fault)

  2. 操作系统介入:

    • 若该页在磁盘(swap 或可执行文件),则将其加载到物理内存

    • 更新页表,建立映射

    • 重新执行原指令

      💡 这就是“按需分页(Demand Paging)”——程序启动快,只加载用到的部分

4. 交换(Swapping)

  • 当物理内存不足时,OS 会将不活跃的页写入磁盘的 Swap 分区
  • 需要时再换入(Swap In)
  • ⚠️ 频繁 Swap 会导致系统卡顿(“抖动 Thrashing”)

5. 内存保护与权限

页表项(PTE)包含权限位:

  • R/W:是否可写
  • U/S:用户态/内核态
  • NX(No-eXecute) :禁止执行(防缓冲区溢出攻击)

🔒 Java 程序若越界访问(如 native 代码 bug),会触发 Segmentation Fault(SIGSEGV)

总结(面试回答模板)

“虚拟内存是操作系统通过 MMU 和页表,为每个进程提供独立、连续的地址空间的机制。它基于分页实现,利用缺页中断按需加载数据,并通过权限位保障安全。对 Java 应用而言,JVM 堆只是虚拟地址空间的一部分,实际物理内存按需分配,这解释了为何 -Xmx 不等于实际内存占用。在高并发或容器化场景中,理解虚拟内存有助于排查 OOM、性能抖动等问题。”

Q2:线程和进程的区别是什么?(计算机操作系统)

A2:  

根本定义

概念定义
进程(Process)操作系统分配资源的基本单位。一个正在运行的程序实例,拥有独立的内存空间(虚拟地址空间) 、文件描述符、环境变量等。
线程(Thread)CPU 调度和执行的基本单位。属于某个进程,多个线程共享所属进程的资源(如堆内存、打开的文件),但拥有独立的栈、寄存器状态、程序计数器

✅ 一句话总结
进程是“资源容器”,线程是“执行单元”
一个进程至少包含一个线程(主线程),也可以包含多个线程(多线程)。


核心区别对比表

维度进程(Process)线程(Thread)
内存空间✅ 完全隔离(独立虚拟地址空间)❌ 共享所属进程的堆、代码段、数据段
每个进程有主线程栈✅ 每个线程有独立的栈(用于局部变量、方法调用)
创建/销毁开销⚠️ 大(需分配内存、建立页表、加载镜像等)✅ 小(只需分配栈 + TCB)
通信方式IPC:管道、消息队列、共享内存、Socket 等✅ 直接读写共享内存(如 Java 的 Heap 对象)
同步复杂度低(天然隔离)⚠️ 高(需锁、volatile、CAS 等保证线程安全)
健壮性✅ 一个进程崩溃不影响其他进程❌ 一个线程崩溃可能导致整个进程退出
切换成本⚠️ 高(需切换页表、TLB 刷新等)✅ 低(只需保存/恢复寄存器、栈指针)
典型例子Chrome 每个标签页是一个进程Java 应用中的 main 线程、Tomcat 的请求处理线程池

常见误区澄清

误区正确理解
“线程比进程快,所以应该多用线程”线程虽轻量,但并发带来复杂性;合理使用线程池,避免无限制创建
“每个线程都有自己的堆”❌ 堆是进程级别的!线程只有自己的
“多进程不能共享内存”可通过 共享内存(Shared Memory) IPC 实现,但复杂且需同步
“Java 线程 = 操作系统线程”在主流 JVM(HotSpot)中,是 1:1 映射(绿色线程已淘汰)

面试回答模板

“进程是操作系统资源分配的基本单位,拥有独立的内存空间;线程是 CPU 调度的基本单位,属于进程,多个线程共享进程的堆、文件描述符等资源,但各自拥有独立的栈。
在 Java 中,我们通常在一个进程中创建多个线程来处理并发请求,这提高了资源利用率,但也引入了线程安全问题,需要通过锁、原子类或无共享设计来保证正确性。
相比之下,多进程天然隔离,适合微服务架构,但通信和资源开销更大。”

Q3:HTTP和HTTPS区别是什么?默认端口是什么?(计算机网络)

A3:

核心区别对比表

特性HTTP(HyperText Transfer Protocol)HTTPS(HTTP Secure)
安全性❌ 明文传输,数据可被窃听、篡改、伪造✅ 加密传输(TLS/SSL),防窃听、防篡改、防冒充
协议栈位置应用层(直接跑在 TCP 上)应用层(HTTP + TLS/SSL 层 → 再跑在 TCP 上)
加密方式混合加密: • 非对称加密(RSA/ECC)交换密钥 • 对称加密(AES)加密数据
身份认证✅ 通过数字证书验证服务器身份(可选客户端证书)
默认端口80443
URL 前缀http://https://
性能开销低(无加解密)略高(首次握手有 RTT 开销,但现代优化已大幅降低)
SEO / 浏览器体验被标记为“不安全”✅ 被浏览器信任,利于 SEO

HTTPS 的工作原理(简化版)

  1. 客户端发起请求
    https://example.com → 连接服务器 443 端口

  2. TLS 握手(关键!)

    • 客户端发送支持的加密套件
    • 服务器返回 数字证书(含公钥 + CA 签名)
    • 客户端验证证书合法性(是否过期、域名匹配、CA 可信)
    • 双方协商出一个 会话密钥(Session Key)
    • 后续通信使用该密钥进行对称加密
  3. 加密传输 HTTP 数据
    所有请求/响应(Header + Body)均被加密

🔐 核心价值:即使数据被中间人截获,也无法解密或篡改(否则 MAC 校验失败)。


默认端口详解

协议默认端口说明
HTTP80浏览器访问 http://baidu.com 时自动连接 80 端口
HTTPS443浏览器访问 https://baidu.com 时自动连接 443 端口

💡 注意:

  • 端口号是约定俗成的,实际可自定义(如 https://api.example.com:8443
  • 但在生产环境中,必须使用 443 才能获得浏览器信任(否则会提示“不安全”)

常见误区澄清

误区正确理解
“HTTPS 只是加密,不影响功能”❌ HTTPS 还提供身份认证完整性校验
“用了 HTTPS 就绝对安全”❌ 仍需防范 XSS、CSRF、逻辑漏洞等
“HTTP/2 必须用 HTTPS”✅ 在浏览器中是强制的(但 HTTP/2 协议本身不强制)
“端口 80 和 443 可以互换”❌ 浏览器和 CDN 默认行为依赖标准端口

面试回答模板

“HTTP 是明文传输的超文本协议,默认端口 80;HTTPS 是在 HTTP 和 TCP 之间加入 TLS/SSL 加密层的安全协议,默认端口 443。
HTTPS 通过数字证书实现服务器身份认证,并使用混合加密保证数据机密性和完整性。
在实际开发中,所有涉及用户隐私或敏感操作的接口都必须使用 HTTPS,同时要注意反向代理下的协议传递和证书管理。”

Q4:讲一下ssh协议?(计算机网络)

A4:  

面试回答模板

“SSH 是一种基于 TCP 的加密网络协议,默认端口 22,用于安全远程登录和文件传输。它通过 Diffie-Hellman 密钥交换建立加密通道,并支持公钥认证实现免密登录。相比 Telnet/FTP,SSH 能有效防止窃听、篡改和中间人攻击。在实际开发中,我们使用 SSH 公钥实现 CI/CD 自动化部署,并通过端口转发安全访问内网服务。”

SSH 协议架构(分层设计)

SSH 协议栈分为三层:

层级功能关键技术
1. 传输层(Transport Layer)提供加密、压缩、完整性校验• Diffie-Hellman 密钥交换 • 对称加密(AES, ChaCha20) • HMAC 消息认证
2. 用户认证层(User Authentication Layer)验证客户端身份• 密码认证 • 公钥认证(推荐!) • 键盘交互式认证
3. 连接层(Connection Layer)多路复用、端口转发、子系统• 多个逻辑通道(shell、sftp、端口转发) • 支持 X11 转发、代理跳转

🔑 整个过程建立在 TCP 之上,默认端口:22


SSH 工作流程(以公钥认证为例)

这是最安全、最常用的登录方式(你在简历中提到“自动化部署”,很可能就用它):

步骤 1:建立加密通道(传输层)

  1. 客户端连接服务器 22 端口
  2. 双方协商加密算法(如 aes256-ctr + hmac-sha2-256
  3. 通过 Diffie-Hellman 密钥交换 生成共享会话密钥(即使被监听也无法推导)

步骤 2:服务器身份验证

  • 服务器发送其 公钥(Host Key)

  • 客户端检查 ~/.ssh/known_hosts 是否已信任该公钥

    • 若首次连接 → 提示 “Are you sure you want to continue connecting?”
    • 若公钥变更 → 警告 “WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!”(防中间人攻击)

步骤 3:客户端身份认证(公钥方式)

  1. 客户端声明:“我想用 id_rsa.pub 登录”
  2. 服务器在 ~/.ssh/authorized_keys 中查找该公钥
  3. 服务器生成一个随机 challenge,用公钥加密后发给客户端
  4. 客户端用私钥解密并返回响应
  5. 服务器验证成功 → 认证通过

✅ 优势:私钥永不离开客户端,比密码更安全,支持免密登录。


SSH 核心功能(不止是远程登录!)

功能命令示例应用场景
远程 Shellssh user@host登录服务器执行命令
安全文件传输scp file user@host:/path sftp user@host替代 FTP,加密传文件
端口转发(隧道)ssh -L 8080:localhost:8080 user@jump-host内网穿透、安全访问数据库
代理跳转(Jump Host)ssh -J jump-user@jump-host target-user@target-host通过堡垒机访问内网机器
X11 转发ssh -X user@host远程运行 GUI 程序(如性能分析工具)

💡 你在自动化部署中可能用到:

# 免密执行远程命令(配合公钥)
ssh deploy@prod-server "cd /app && ./restart.sh"


五、SSH 与 HTTPS 的区别(常被混淆)

特性SSHHTTPS
目的安全远程管理/文件传输安全 Web 浏览/API 调用
默认端口22443
认证方式主机公钥 + 用户公钥/密码CA 签发的服务器证书
协议模型客户端-服务器(双向可认证)浏览器-服务器(通常单向认证)
数据格式二进制协议(非文本)基于 HTTP(文本/JSON)
典型工具OpenSSH, PuTTY浏览器, curl, RestTemplate

📌 关键差异
HTTPS 依赖第三方 CA 信任链,而 SSH 依赖首次连接信任(Trust on First Use, TOFU)

Q5:讲一下数据库事务的四大特性?(数据库)

A5:

面试回答模板

“数据库事务的 ACID 四大特性是:
原子性(Atomicity)确保操作全成功或全失败;
一致性(Consistency)保证数据始终满足业务规则;
隔离性(Isolation)通过隔离级别控制并发副作用;
持久性(Durability)确保提交后的数据永不丢失。
在 MySQL InnoDB 中,原子性靠 Undo Log,持久性靠 Redo Log,隔离性靠 MVCC 和锁机制。而在分布式场景下,我们往往牺牲强一致性,采用最终一致性方案来保证系统可用性。”

ACID 四大特性详解

特性全称中文含义核心作用举例说明
AAtomicity原子性事务中的所有操作要么全部成功,要么全部失败回滚转账:A 扣 100 元 + B 加 100 元 必须同时成功或同时失败
CConsistency一致性事务执行前后,数据库必须从一个合法状态转移到另一个合法状态(满足约束、触发器、业务规则)账户余额不能为负;外键约束不能被破坏
IIsolation隔离性多个并发事务之间互不干扰,如同串行执行A 查询余额时,不能看到 B 正在转账的中间状态
DDurability持久性一旦事务提交,其结果将永久保存,即使系统崩溃也不会丢失提交后,数据已写入磁盘(或 WAL 日志),重启后依然存在

原子性(Atomicity)

  • 实现机制:通过 Undo Log(回滚日志) 实现。

  • 关键点

    • 如果事务中途失败,数据库利用 Undo Log 将已修改的数据恢复到事务开始前的状态。
    • 在 MySQL InnoDB 中,每条记录的旧值会被记录在 Undo Log 中。
  • Java 场景

    @Transactional
    public void transfer(Long fromId, Long toId, BigDecimal amount) {
        accountDao.decrease(fromId, amount); // 扣款
        accountDao.increase(toId, amount);   // 加款
        // 若 increase 抛异常,decrease 也会回滚
    }
    


一致性(Consistency)

  • 注意:一致性是目的,而原子性、隔离性、持久性是手段

  • 数据库本身通过约束(主键、唯一索引、外键、Check)保证基础一致性

  • 业务一致性需由应用层保证(如“库存不能超卖”)。

  • 例子

    • 表中有 CHECK (balance >= 0),则任何事务都不能使余额为负。
    • 如果你转账 100 元但只扣了 A 的钱没加 B 的钱,就违反了一致性(但原子性会阻止这种情况)。

✅ 一致性 = 原子性 + 隔离性 + 持久性 + 应用逻辑正确性


隔离性(Isolation)

  • 问题背景:多个事务并发执行可能引发:

    • 脏读(Dirty Read) :读到未提交的数据
    • 不可重复读(Non-Repeatable Read) :同一事务内多次读取同一数据,结果不同
    • 幻读(Phantom Read) :同一查询条件,两次结果行数不同(新增/删除)
  • SQL 标准定义了 4 种隔离级别

隔离级别脏读不可重复读幻读说明
READ UNCOMMITTED✅ 允许性能最高,几乎不用
READ COMMITTED(Oracle 默认)❌ 禁止✅ 允许每次读取都生成新快照
REPEATABLE READ(MySQL InnoDB 默认)⚠️ InnoDB 通过 MVCC + Gap Lock 解决保证同一事务内多次读一致
SERIALIZABLE完全串行化,并发性能最差

四、持久性(Durability)

  • 实现机制:通过 Redo Log(重做日志) + WAL(Write-Ahead Logging)

  • 关键流程(以 MySQL InnoDB 为例):

    1. 事务提交时,先将 Redo Log 写入磁盘(顺序 I/O,快)
    2. 后台线程异步将数据页刷入磁盘
    3. 即使 crash,重启后可通过 Redo Log 恢复已提交事务
  • 保障:只要事务返回“提交成功”,数据就不会丢失(即使断电)。

💡 注意:若磁盘损坏或日志未刷盘(如 innodb_flush_log_at_trx_commit=2),仍可能丢数据。


ACID 在分布式系统中的挑战

在微服务架构中(如你的简历项目),单数据库 ACID 很难跨服务保证,此时常用:

  • 最终一致性(通过消息队列补偿)
  • Saga 模式(长事务拆解 + 补偿事务)
  • TCC(Try-Confirm-Cancel)
  • Seata 等分布式事务框架(AT 模式模拟本地事务)

例如:订单服务创建订单 + 库存服务扣减库存 → 无法用 @Transactional 跨两个数据库。

Q6:SQL语言中左右连接和内连接是什么?(数据库)

A6:

面试回答模板

“SQL 中的内连接(INNER JOIN)只返回两表匹配的记录;左连接(LEFT JOIN)返回左表全部记录,右表无匹配时补 NULL;右连接(RIGHT JOIN)则相反。
在实际开发中,我常用 LEFT JOIN 查询主表全量数据(如所有用户及其行为),用 INNER JOIN 获取关联成功的数据(如有效订单)。需要注意的是,LEFT JOIN 中 ON 和 WHERE 的作用不同,错误使用可能导致意外过滤掉 NULL 行。”

核心概念图解(以两个表为例)

假设有两张表:

users 表(用户)

user_idname
1Alice
2Bob
3Charlie

orders 表(订单)

order_iduser_idproduct
1011Laptop
1021Mouse
1034Keyboard

三种连接详解

1. 内连接(INNER JOIN)

  • 含义:只返回两个表中都存在匹配记录的行。

  • 关键字INNER JOIN 或简写为 JOIN

  • SQL 示例

    SELECT u.name, o.product
    FROM users u
    INNER JOIN orders o ON u.user_id = o.user_id;
    

  • 结果

    nameproduct
    AliceLaptop
    AliceMouse

✅ 特点

  • 不包含任何“孤儿”数据(如 Charlie 没订单,Keyboard 的 user_id=4 无效)
  • 最常用,性能通常最好(可利用索引高效过滤)

2. 左连接(LEFT JOIN / LEFT OUTER JOIN)

  • 含义:返回左表(FROM 后的表)的所有记录,即使右表没有匹配项;右表无匹配时,字段为 NULL

  • 关键字LEFT JOIN 或 LEFT OUTER JOIN

  • SQL 示例

    SELECT u.name, o.product
    FROM users u
    LEFT JOIN orders o ON u.user_id = o.user_id;
    

  • 结果

    nameproduct
    AliceLaptop
    AliceMouse
    BobNULL
    CharlieNULL

✅ 典型场景

  • 查询“所有用户及其订单(包括未下单用户)”
  • 统计每个用户的操作次数(即使为 0)

3. 右连接(RIGHT JOIN / RIGHT OUTER JOIN)

  • 含义:返回右表(JOIN 后的表)的所有记录,即使左表没有匹配项;左表无匹配时,字段为 NULL

  • 关键字RIGHT JOIN 或 RIGHT OUTER JOIN

  • SQL 示例

    SELECT u.name, o.product
    FROM users u
    RIGHT JOIN orders o ON u.user_id = o.user_id;
    

  • 结果

    nameproduct
    AliceLaptop
    AliceMouse
    NULLKeyboard

⚠️ 注意

  • RIGHT JOIN 可通过交换表顺序 + LEFT JOIN 实现,实际开发中很少使用(可读性差)

  • 上例等价于:

    SELECT u.name, o.product
    FROM orders o
    LEFT JOIN users u ON u.user_id = o.user_id;
    


对比总结表

连接类型返回哪些行?是否包含 NULL?常用程度
INNER JOIN两表都有匹配的行❌ 不会⭐⭐⭐⭐⭐
LEFT JOIN左表全部 + 右表匹配部分(无匹配则 NULL)✅ 右表字段可能为 NULL⭐⭐⭐⭐
RIGHT JOIN右表全部 + 左表匹配部分(无匹配则 NULL)✅ 左表字段可能为 NULL

📌 记忆口诀

  • INNER → “交集”
  • LEFT → “左表全保留”
  • RIGHT → “右表全保留”(但建议用 LEFT 替代)

Q7:SQL中where和on的区别?(数据库)

A7:

面试回答模板

ON 是连接条件,用于定义表之间如何关联,作用于 JOIN 执行过程中;WHERE 是筛选条件,作用于最终结果集。
在 LEFT JOIN 中,若将右表的过滤条件写在 WHERE 中,会导致左表中无匹配的行被意外过滤,失去 LEFT JOIN 的意义。
因此,当我们需要保留主表全量数据时(如所有用户),应把关联表的过滤条件放在 ON 子句中。”

详细对比(以 LEFT JOIN 为例)

users

user_idname
1Alice
2Bob

orders

order_iduser_idamount
1011100
1021200
103350

✅ 场景 1:用 ON 过滤右表(正确做法)

SELECT u.name, o.amount
FROM users u
LEFT JOIN orders o 
  ON u.user_id = o.user_id AND o.amount > 150; -- ON 中加条件

执行过程

  1. 先根据 ON 条件 构建连接关系:只将 amount > 150 的订单与用户关联
  2. 再保留左表(users)所有行

结果

nameamount
Alice200
BobNULL

✅ 语义:查询所有用户,以及他们金额大于 150 的订单


❌ 场景 2:用 WHERE 过滤右表(常见错误!)

SELECT u.name, o.amount
FROM users u
LEFT JOIN orders o 
  ON u.user_id = o.user_id
WHERE o.amount > 150; -- WHERE 中加条件

执行过程

  1. 先完成完整 LEFT JOIN(包含所有订单)
  2. 再用 WHERE 过滤最终结果 → o.amount > 150
  3. 由于 Bob 的 o.amount 是 NULLNULL > 150 为 UNKNOWN(即 false),Bob 被过滤掉!

结果

nameamount
Alice200

❌ 问题:这实际上变成了 INNER JOIN!失去了 LEFT JOIN “保留左表全部”的语义。


对比总结表

特性ON子句WHERE子句
作用阶段连接过程中(构建临时结果集时)连接完成后(对最终结果过滤)
适用位置只能在 JOIN 后使用可用于任何 SELECT 查询
对 LEFT JOIN 的影响不会减少左表行数可能过滤掉左表行(当右表字段为 NULL 时)
性能通常更优(提前减少连接数据量)可能处理更多中间数据
语义重点“如何关联表”“要哪些结果”

不同 JOIN 类型下的行为差异

JOIN 类型ON中过滤右表WHERE中过滤右表
INNER JOIN等价于 WHERE(结果相同)等价于 ON
LEFT JOIN保留左表全部,右表按条件匹配可能丢失左表行(变成 INNER JOIN)
RIGHT JOIN保留右表全部,左表按条件匹配可能丢失右表行
FULL JOIN保留两表全部,按条件匹配可能丢失任一方的行

💡 黄金法则

  • 如果你想保留主表的所有行(如所有用户、所有岗位),过滤条件应写在 ON 中
  • 如果你只想获取满足条件的最终结果(不管是否保留主表),用 WHERE

Q8:HTTP协议中的常用状态码有哪些?

A8:3.1 HTTP 常见面试题 | 小林coding | Java面试学习

Q9:Linux的常用命令?如何查看磁盘使用情况?把a文件的内容拷贝到b中如何操作?

A9:

全局查看:整个系统的磁盘使用情况

✅ df(disk free)—— 查看挂载点的磁盘空间

df -h

  • -h:human-readable(以 GB/MB 显示,而不是 KB)

  • 输出示例

    Filesystem      Size  Used Avail Use% Mounted on
    /dev/nvme0n1p2   50G   30G   18G  63% /
    /dev/nvme0n1p1  512M  7.8M  504M   2% /boot
    tmpfs            16G     0   16G   0% /run/user/1000
    

  • 重点关注

    • Use% 列:超过 80% 需警惕,100% 会导致应用写文件失败(如 Tomcat 日志、MySQL binlog)
    • Mounted on:确认是哪个分区(如 //var/data

💡 Java 场景
若 / 分区快满了,可能是:

  • 应用日志未轮转(catalina.out 暴涨)
  • Core dump 文件(JVM Crash 生成)
  • Docker 镜像/容器日志堆积

定位大目录:哪个目录占空间最多?

✅ du(disk usage)—— 查看目录/文件的磁盘占用

# 查看当前目录下各子目录大小(排序后取前10)
du -h --max-depth=1 | sort -hr | head -10

# 查看 /var 目录下最大的子目录
sudo du -h /var --max-depth=1 | sort -hr

  • -h:易读格式
  • --max-depth=1:只统计一级子目录(避免递归太深)
  • sort -hr:按人类可读数字倒序排列(需 GNU coreutils)

📌 典型问题定位

# 发现 /var/log 占了 20G
sudo du -h /var/log --max-depth=1
# → 发现 catalina.out 有 18G!
ls -lh /var/log/tomcat/catalina.out


快速找出最大的文件(尤其是日志)

✅ 使用 find + ls 组合

# 查找 /var 下大于 100MB 的文件,按大小排序
sudo find /var -type f -size +100M -exec ls -lh {} ; | awk '{ print $5 ": " $9 }' | sort -hr

✅ 或用 ncdu(推荐!交互式工具)

# 安装(Ubuntu/Debian)
sudo apt install ncdu

# 使用
ncdu /    # 交互式浏览,方向键导航,d 删除(谨慎!)

  • 优势:图形化、可钻取、支持删除(按 d
  • 适合:快速定位“罪魁祸首”文件
需求推荐命令
标准复制(覆盖)cp a b
仅复制内容(不保留元数据)cat a > b
追加内容cat a >> b

💡 记住

  • 想保留原文件 → 用 cp
  • 只关心内容 → 用 cat >
  • 要追加 → 用 cat >>

Q10:简要介绍redis数据结构?(Redis)

A10:

数据结构中文名特点典型应用场景
String字符串最基本类型,可存文本、数字、二进制(如图片) • 支持原子自增(INCR) • 可设置过期时间• 缓存对象(JSON 序列化) • 计数器(如接口限流) • 分布式锁(SET key value NX PX
Hash哈希表类似 Java 的 Map<String, String> • 存储对象字段(field-value) • 节省内存(相比多个 String)• 用户信息(id → {name, age, email}) • 商品详情
List列表有序、可重复的字符串列表 • 支持从两端插入/弹出(LPUSH/RPOP) • 底层用 ziplist 或 linkedlist• 消息队列(简单场景) • 最新 N 条动态(如朋友圈 feed)
Set集合无序、唯一的字符串集合 • 支持交集、并集、差集运算• 标签系统(用户兴趣标签) • 抽奖(SRANDMEMBER) • 好友关系去重
Sorted Set (ZSet)有序集合每个成员带一个 score(分数) • 按 score 自动排序 • 支持范围查询(ZRANGEBYSCORE• 排行榜(如游戏积分) • 延时队列(score = 执行时间戳) • 带权重的 Top-K

🧩 补充:Redis 7+ 新增的实用结构

结构用途
Bitmaps位图,用于统计(如日活用户)
HyperLogLog超低内存基数估算(如 UV 统计)
Geospatial地理位置(基于 Sorted Set 实现)
Streams高可靠消息队列(类似 Kafka 简化版)

Q11:mcp是什么?(agent开发)

A11:

“MCP(Model Context Protocol)是一个新兴的开源标准,旨在为大语言模型提供统一、安全的外部工具调用接口。它通过标准化工具描述和基于 JSON-RPC 的通信机制,让不同模型能无缝集成数据库、API、文件系统等能力。相比 OpenAI Function Calling 或 LangChain Tools,MCP 的优势在于跨平台和开放生态,有望成为 AI Agent 时代的‘通用工具总线’。”

Model Context Protocol(模型上下文协议)

这是由 Anthropic、Databricks、Cohere、LlamaIndex 等公司于 2024 年底联合提出的一个新兴开源标准,旨在让 AI 模型(尤其是 LLM)能够安全、结构化地调用外部工具(Tools)和访问上下文数据

📌 简单说:MCP 是让大模型“连接世界”的通用接口协议,类似于当年的 HTTP 之于 Web。


一、MCP 解决了什么问题?

在 MCP 出现前,每个 AI 应用(如 Copilot、Agent 系统)都用自己的方式集成工具(如数据库、API、代码解释器),导致:

  • 🔧 工具无法复用:一个日历插件只能用于某一家模型
  • 🛡️ 安全风险高:权限控制、输入校验各不相同
  • 🧩 开发效率低:开发者要为不同平台重复造轮子

MCP 的目标:定义一套统一的通信协议,让任何支持 MCP 的模型都能调用任何 MCP 兼容的工具。


二、MCP 核心思想

  1. 标准化工具描述
    工具通过 JSON Schema 声明自己的能力、参数、权限要求

    {
      "name": "get_weather",
      "description": "获取指定城市的天气",
      "parameters": {
        "type": "object",
        "properties": { "city": { "type": "string" } }
      }
    }
    

  2. 基于 LSP(Language Server Protocol)扩展
    MCP 复用微软的 LSP 架构,使用 JSON-RPC over stdio/WebSocket 通信,天然支持 IDE、CLI、Web 等多种客户端。

  3. 上下文感知(Context Awareness)
    模型可请求“当前用户有哪些可用工具”,系统动态返回授权后的工具列表。

  4. 安全沙箱
    所有工具调用需经过 MCP 服务器鉴权,防止模型越权操作。


三、MCP 典型架构

[ LLM (如 Claude, Llama 3) ]
          ↓ (MCP 请求)
[ MCP Client (嵌入在 Agent 框架中) ]
          ↓ (JSON-RPC)
[ MCP Server (管理工具注册/鉴权) ][ Tools: 数据库 / API / 文件系统 / 自定义函数 ]

💡 你在简历中提到的 “AI Agent 会话状态管理” ,就可以通过 MCP 集成:

  • 一个 save_conversation 工具(写入数据库)
  • 一个 search_knowledge_base 工具(查向量库)
    而无需硬编码到 Agent 逻辑中。

四、MCP vs 其他工具调用方案

方案特点局限
MCP(Model Context Protocol)开源、标准化、跨模型、安全新兴标准,生态尚在建设
OpenAI Function Calling成熟、易用仅限 OpenAI 生态
LangChain Tools灵活、插件丰富绑定 LangChain 框架
自定义 Tool Call完全可控无法复用,维护成本高

🌐 MCP 的愿景:成为 AI 时代的 “USB 接口”——任何模型插上就能用任何工具。

Q12:用Java写一个算法,题目要求为接收一个字符串,由全0或0和1混合组成,需要判断是否所以的1在0之前,例如:110对,000对,101错(算法)()

A12:

public class Solution {
    /**
     * 判断字符串中是否所有 '1' 都在 '0' 之前(或全为 0 / 全为 1)
     * @param s 输入字符串,仅包含 '0' 和 '1'
     * @return true 表示合法,false 表示非法
     */
    public static boolean allOnesBeforeZeros(String s) {
        if (s == null || s.isEmpty()) {
            return true; // 空串视为合法
        }

        boolean seenZero = false;
        for (char c : s.toCharArray()) {
            if (c == '0') {
                seenZero = true;
            } else if (c == '1') {
                if (seenZero) {
                    // 已经见过 0,又出现 1 → 不合法
                    return false;
                }
            }
            // 题目保证只有 0/1,可不处理其他字符
        }
        return true;
    }

    // 测试用例
    public static void main(String[] args) {
        System.out.println(allOnesBeforeZeros("110"));  // true
        System.out.println(allOnesBeforeZeros("000"));  // true
        System.out.println(allOnesBeforeZeros("111"));  // true
        System.out.println(allOnesBeforeZeros("10"));   // true
        System.out.println(allOnesBeforeZeros("101"));  // false
        System.out.println(allOnesBeforeZeros("010"));  // false
        System.out.println(allOnesBeforeZeros("0110")); // false
        System.out.println(allOnesBeforeZeros(""));     // true
    }
}

个人评价:

本次面试除博客中提到的问题,还提问了实习经历及简历上的项目技术栈,但个人认为面试难度不高,知识点简单,没有深挖,但注重实操,如常用的Linux命令,算法题简单,总体面试顺利