Java后台研发部门,腾讯面试一面(问题+参考答案+反思)

一、自我介绍

二、项目介绍

三、技术面试

1、Java基础

1,说一说jdk,jre,jvm

  • JDK (Java Development Kit)

    • 是 Java 开发工具包,包含 JRE + 开发工具(如编译器 javac、调试器 jdb、文档生成器 javadoc 等)。

    • 开发者用它编写、编译和调试 Java 程序。

  • JRE (Java Runtime Environment)

    • 是 Java 运行时环境,包含 JVM + 核心类库(如 java.langjava.util 等)。

    • 用户用它运行已编译的 Java 程序(.class 或 .jar 文件)。

  • JVM (Java Virtual Machine)

    • 是 Java 虚拟机,负责 执行字节码.class 文件),实现跨平台特性(“一次编译,到处运行”)。

    • 它通过 类加载器 加载字节码,由 解释器/JIT 编译器 转换为机器码执行,并管理内存(堆、栈等)。

2,你知道第三方的jar包中包括什么东西吗?(不了解,没回答上)

一个 JAR(Java Archive)包本质是一个 ZIP 压缩文件,包含以下内容:

  1. 编译后的 .class 文件

    • 第三方库的核心代码(如工具类、接口实现)。

  2. 资源文件

    • 配置文件(如 .properties.xml)、图片、国际化资源等。

  3. 元数据文件

    • META-INF/MANIFEST.MF:定义 JAR 的版本、入口类、依赖等信息。

  4. 依赖库(可选):

    • 如果是一个“Fat JAR”(如 Spring Boot 项目),可能包含其他依赖的 JAR。

示例
解压 commons-lang3-3.12.0.jar 后,会看到 org/apache/commons/lang3/StringUtils.class 等文件。

3,Java中的反射有了解吗?(没怎么用过,没回答上)

        反射(Reflection)是 在运行时动态获取类的信息并操作对象 的机制,核心类在 java.lang.reflect 包中。

核心功能

  1. 获取类信息

    Class<?> clazz = Class.forName("com.example.User");
  2. 创建对象

    Object obj = clazz.getDeclaredConstructor().newInstance();
  3. 调用方法

    Method method = clazz.getMethod("setName", String.class);
    method.invoke(obj, "Alice");
  4. 访问字段(甚至私有字段):

    Field field = clazz.getDeclaredField("name");
    field.setAccessible(true); // 突破私有权限
    String name = (String) field.get(obj);

应用场景

  • 框架(如 Spring 的依赖注入、MyBatis 的结果映射)。

  • 动态代理(如 AOP 实现)。

缺点

  • 性能低:反射操作比直接调用慢(需 JVM 动态解析)。

  • 安全问题:可能破坏封装性(如访问私有字段)。

 2、JVM相关

1、你知道垃圾回收算法吗?介绍一下Java的垃圾回收算法。

  1. 标记-清除(Mark-Sweep)

    • 步骤

      1. 标记所有活动对象。

      2. 清除未标记的对象。

    • 缺点:内存碎片化。

  2. 复制算法(Copying)

    • 步骤

      1. 将内存分为两块(From 和 To)。

      2. 将 From 区的存活对象复制到 To 区,清空 From 区。

    • 优点:无碎片。

    • 缺点:内存利用率 50%。

    • 应用场景:新生代(Eden 和 Survivor 区)。

  3. 标记-整理(Mark-Compact)

    • 步骤

      1. 标记所有活动对象。

      2. 将存活对象向一端移动,清理边界外的内存。

    • 优点:无碎片、内存利用率高。

    • 缺点:移动对象成本高。

    • 应用场景:老年代。

  4. 分代收集(Generational)

    • 原理:根据对象存活周期划分内存(新生代、老年代)。

    • 新生代:频繁 GC,使用复制算法。

    • 老年代:较少 GC,使用标记-清除或标记-整理。

现代 GC 算法

  • G1(Garbage-First):将堆划分为多个 Region,优先回收价值高的 Region。

  • ZGC:低延迟,通过染色指针和读屏障实现并发标记。

3、数据库相关

1,你用过什么数据库?

2,说一说MyISAM和InnoDB的区别。

MyISAM:

        不支持事务,但是每次查询都是原子的; 支持表级锁,即每次操作是对整个表加锁; 存储表的总行数; 一个MYISAM表有三个文件:索引文件、表结构文件、数据文件采用非聚集索引,索引文件的数据域存储指向数据文件的指针。辅索引与主索引基本一致,但是辅索引 不用保证唯一性。

InnoDb:

        支持ACID的事务,支持事务的四种隔离级别; 支持行级锁及外键约束:因此可以支持写并发不存储总行数;一个InnoDb引擎存储在一个文件空间(共享表空间,表大小不受操作系统控制,一个表可能分布在多 个文件里),也有可能为多个(设置为独立表空,表大小受操作系统文件大小限制,一般为2G),受操 作系统文件大小的限制; 主键索引采用聚集索引(索引的数据域存储数据文件本身),辅索引的数据域存储主键的值;因此从辅 索引查找数据,需要先通过辅索引找到主键值,再访问辅索引;最好使用自增主键,防止插入数据时, 为维持B+树结构,文件的大调整。

特性MyISAMInnoDB
事务支持不支持支持(ACID 兼容)
锁机制表级锁行级锁(并发性能更高)
外键不支持支持
崩溃恢复较差(需手动修复)支持自动恢复(redo log)
存储结构三个文件(.frm.MYD.MYI所有表存储在共享表空间或独立文件(.ibd
适用场景读多写少(如日志系统)高并发、事务处理(如电商订单)

3,什么叫回表?

当使用 非聚簇索引(二级索引)查询时,若所需字段不在索引中,需 根据主键值回到主索引(聚簇索引)查找完整数据,这个过程称为回表。

 4,怎么排查一个MySQL的慢查询?

  1. 开启慢查询日志

    SET GLOBAL slow_query_log = 'ON';
    SET GLOBAL long_query_time = 2; -- 超过 2 秒的查询记录
    SET GLOBAL slow_query_log_file = '/path/to/slow.log';
  2. 分析日志

    • 使用 mysqldumpslow 工具:

      mysqldumpslow -s t /path/to/slow.log
    • 第三方工具:Percona Toolkit 的 pt-query-digest

  3. EXPLAIN 分析执行计划

    EXPLAIN SELECT * FROM orders WHERE user_id = 100;
    • 关注 type(扫描方式)、key(使用的索引)、rows(扫描行数)。

  4. 优化索引或 SQL

    • 添加缺失索引。

    • 避免 SELECT *,减少数据传输。

5,用什么命令来查询一个sql语句走了哪些索引,是否走索引这些信息?

1.使用 EXPLAIN 命令:

EXPLAIN SELECT * FROM user WHERE age > 20;

输出中的关键字段:

  • possible_keys:可能使用的索引。

  • key:实际使用的索引。

  • type

    • index:全索引扫描。

    • ref:使用非唯一索引查找。

    • range:范围扫描。

  • rows:预估扫描行数。

示例
若 key 为 NULL,说明未使用索引。

6,解释一下最左前缀原则

定义
在使用 联合索引(如 INDEX (a, b, c))时,查询条件必须 从最左列开始,且 不能跳过中间列

有效场景

  • WHERE a = 1 AND b = 2 → 使用索引。

  • WHERE a = 1 AND c = 3 → 仅使用 a 列索引。

无效场景

  • WHERE b = 2 → 无法使用索引。

  • WHERE b = 2 AND c = 3 → 同上。

原理
索引的存储结构按 (a, b, c) 排序,类似电话簿按“姓氏-名字-中间名”排序。跳过最左列时,无法利用有序性。

4、redis相关

1,redis有哪些常用的数据结构?

  1. String

    • 存储文本、数字(如计数器 INCR)。

  2. List

    • 双向链表,支持队列(LPUSH/RPOP)或栈(LPUSH/LPOP)。

  3. Hash

    • 键值对集合(如存储用户信息 HSET user:1000 name "Alice")。

  4. Set

    • 无序唯一集合(如共同好友 SINTER)。

  5. Sorted Set

    • 带分数的有序集合(如排行榜 ZADD)。

  6. 其他

    • Bitmaps(位操作)、HyperLogLog(基数统计)、Streams(消息队列)。

2,在哪些项目中使用到了redis?

  • 缓存
    缓存数据库查询结果(如商品详情),减少 DB 压力。

  • 会话管理
    存储用户登录状态(Session)。

  • 分布式锁
    通过 SET key value NX EX 实现互斥操作。

  • 限流
    计数器(如每分钟允许 100 次请求)。

  • 分布式唯一id

3,你项目中的商城的分布式id是怎么做的?

使用的redis的incr制作的分布式id,先创建唯一key值,然后将值设为0,在插入商品时使用reids自增属性incr来进行商品id自增

方案优点缺点
UUID简单、全球唯一无序、长度长,不适合主键
数据库自增有序、简单性能低、单点故障
Redis INCR性能高、有序依赖 Redis 可用性
雪花算法高性能、趋势递增、去中心化依赖系统时钟(时钟回拨问题)

5、linux相关

1,如何判断一个端口在监听状态?

# 查看 TCP/UDP 监听端口
netstat -tuln | grep :8080
# 或
ss -tuln | grep :8080
# 或
lsof -i :8080
  • -t:TCP 协议。

  • -u:UDP 协议。

  • -l:仅显示监听状态的端口。

  • -n:以数字形式显示地址和端口

2,如何查询一个进程的id号?

# 根据进程名查找
ps aux | grep nginx
# 或使用 pgrep
pgrep -f nginx
# 或使用 pidof(仅适用于进程名)
pidof nginx
  • ps aux:显示所有进程详细信息。

  • pgrep -f:按完整命令行匹配。

6、操作系统相关

1,说一说进程和线程

特性进程线程
资源分配独立内存空间、文件句柄等共享进程资源(内存、文件)
切换开销高(需切换内存空间)低(共享地址空间)
通信方式管道、信号、共享内存、消息队列、套接字共享变量(需同步机制)
容错性进程崩溃不影响其他进程线程崩溃可能导致整个进程终止

2,协程有了解过吗?(没听过)

  • 定义:用户态的轻量级线程,由程序控制调度(而非操作系统)。

  • 优点

    • 切换成本极低(无内核切换)。

    • 适合高并发 IO 密集型任务(如网络服务器)。

  • 示例

    • Python 的生成器:通过 yield 挂起协程。

    • Go 的 goroutine:由 Go 运行时调度,配合通道(channel)通信。

3,进程间的通信方式有没有了解?        

回答到了消息队列,共享内存,tcp等远程调用,但是面试官更想了解的是操作系统相关的

  1. 管道(Pipe)

    • 单向通信,用于父子进程。

    • 示例:ls | grep .txt

  2. 命名管道(FIFO)

    • 有名称的管道,可用于无亲缘关系的进程。

  3. 信号(Signal)

    • 异步通知(如 kill -9 PID 发送 SIGKILL)。

  4. 共享内存

    • 多个进程访问同一块内存(需同步机制,如信号量)。

  5. 消息队列

    • 内核维护的链表,进程通过消息类型读写。

  6. 套接字(Socket)

    • 跨网络通信(如 TCP/UDP)。

4,说一说什么是信号量

  • 定义:用于控制多个进程/线程对共享资源的访问的计数器。

  • 操作

    • P(Proberen,尝试):若信号量 > 0,减 1;否则阻塞。

    • V(Verhogen,增加):信号量加 1,唤醒等待进程。

  • 示例:

sem_t sem;
sem_init(&sem, 0, 1); // 初始值 1(二进制信号量,即互斥锁)
sem_wait(&sem); // P 操作
// 临界区代码
sem_post(&sem); // V 操作

7、docker和k8s相关

1,docker和k8s有了解过吗?

  • Docker

    • 容器化平台,将应用及其依赖打包成镜像,实现 一次构建,到处运行

    • 核心概念:镜像(Image)、容器(Container)、仓库(Registry)。

  • Kubernetes(K8s):(没回答上)

    • 容器编排系统,管理容器化应用的部署、扩展、自愈等。

    • 核心概念:Pod(最小调度单元)、Service(网络访问)、Deployment(副本管理)。

2,dockerfile有写过吗?(没有写过)

3,k8s面试官强烈推荐了解使用

8、算法相关

1,描述一下快速排序

步骤

  1. 选择基准值(pivot):通常选第一个元素或随机元素。

  2. 分区(Partition)

    • 将数组分为两部分,左边 ≤ pivot,右边 ≥ pivot。

  3. 递归排序:对左右子数组重复上述过程。

示例

void quickSort(int[] arr, int low, int high) {
    if (low < high) {
        int pivot = partition(arr, low, high);
        quickSort(arr, low, pivot - 1);
        quickSort(arr, pivot + 1, high);
    }
}

int partition(int[] arr, int low, int high) {
    int pivot = arr[high];
    int i = low - 1;
    for (int j = low; j < high; j++) {
        if (arr[j] < pivot) {
            i++;
            swap(arr, i, j);
        }
    }
    swap(arr, i + 1, high);
    return i + 1;
}


数组 [5, 3, 8, 6, 2],选择 pivot=5:

  • 分区后 → [3, 2, 5, 8, 6]

  • 递归排序 [3, 2] 和 [8, 6]

2,快速排序的时间复杂度是多少?

  • 平均情况:O(n log n) → 每次分区大致平衡。

  • 最坏情况:O(n²) → 每次分区极不平衡(如数组已排序且选第一个元素为 pivot)。

  • 优化方法

    • 随机选择 pivot。

    • 三数取中法(选头、中、尾的中位数)。

四、你有什么问题?

1、贵公司招聘实习生,更想要招到什么样的人才?

面试官:精通底层原理的人才,不仅要涵盖项目技术,更希望具备丰富的计算机原理,操作系统,数据结构与算法等底层知识兼备的人才。

2、贵公司目前的项目发展方向是什么?

面试官:我们公司目前是做云计算,云服务器方向发展。

3、实习生一般负责什么样的任务?

面试官:实习生一般一进来需要先花一段时间属性公司业务,公司框架,然后进行一些环境的熟悉与部署,偶尔会分发一些能够三四天完成的小模块。

4、本次面试感觉我怎么样?请客观评价一下我

面试官:对知识的掌握还比较表面,不够深入,希望继续往底层多下功夫,Linux,git等多用命令行,少用图形化

5、公司目前使用的语言选型是哪些?

面试官:c++,python,PHP,go

                

                

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值