字节2面真题,你能答对几道?

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 字节2面真题,你能答对几道?

字节跳动的面试难度,放眼整个互联网都是“遥遥领先”!不能说有多难,就是看了都不会的哪种!当然,这句话是开玩笑的。

咱们先来看下字节二面的所有问题:
image.png
前半部分的问题比较简单,相信大部人都能搞定(如果你搞不定,可以偷偷去看磊哥的武林秘籍:https://www.javacn.site)。本文咱们就挑两个比较典型的问题来回答。

1.RDB 持久化会阻塞主线程吗?

注意这个问题有坑,这个问题千万别上来就说:“不会阻塞主线程”,这样回答只能拿到 50 分,压根都没过及格线,为什么呢?

因为 RDB 持久化是有可能会阻塞主线程的,因为 RDB 持久化有以下两种命令:

  • save:同步持久化 Redis。
  • bgsave:background save,后台保存的意思,也就是后台持久化 Redis。

默认情况下,如果不是手动执行“bgsave”命令,则会使用“save”命令来持久化 Redis,此时是会阻塞 Redis 主线程的。所以,这是一个不难,但很容易答错的问题。

2.说一下 Copy On Write 技术?

在市面上很少有面试官问 Java 程序员 COW(Copy On Write,写时复制)技术的,当然能回答上来的人也不多,那咱们就来看看什么是 COW?

Copy On Write(写时复制)是一种延迟复制的技术,用于在多个线程(或进程)之间共享资源时减少内存复制成本的。它的基本思想是,在创建拷贝或修改资源之前,不会真正的进行复制操作(懒汉模式),而是共享同一份资源的只读副本,直到某个线程(或进程)试图修改资源时,才会对资源进行复制操作。 这种延迟复制的策略可以减少资源复制的开销,一定程度提高了性能和效率。

那它的使用场景有哪些呢?咱们继续来看。

2.1 Redis 中的 Copy On Write

单线程的 Redis 想要解决一边响应主线程的任务,一边持久化数据,依靠的就是 COW 技术,具体来说就是依赖系统的 fork 函数的 COW 实现的。

具体来说,COW 技术的使用过程是这样的:

  1. 在执行 RDB 持久化时,Redis 进程会 fork 一个子进程来执行持久化,该过程是阻塞的。
  2. 当 fork 过程完成后,父进程会继续接收客户端的命令。
  3. 此时子进程与 Redis 主进程共享内存中的数据,但是子进程并不会修改内存中的数据,而是不断的遍历读取并写入数据到磁盘,也就是持久化数据的过程。
  4. 然而 Redis 主进程则不一样,它需要响应客户端的命令,如果收到写入数据的操作请求,主进程就会使用 COW 机制将数据先复制再修改。
  5. 而此时,子进程使用的数据页并不会发生任何改变,依然是 fork 时的数据,继续进行持久化。

这就是 COW 技术在 Redis 中的使用。

2.2 Java 中的 Copy On Write

Java 中使用 COW 技术实在并发容器中,这种技术的实现容器有两个:CopyOnWriteArrayList 和 CopyOnWriteArraySet。

这两个集合是这样使用 COW 技术的,当有数据写入操作时,会先复制一个新数组进行操作,等写完之后,再将原数组的地址赋值成新数组,以 CopyOnWriteArrayList 的 add 实现为了,它的实现源码如下:

public boolean add(E e) {
   
   
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
   
   
        // 获取老数组
        Object[] elements = getArray();
        int len = elements.length;

        // 复制出新数组
        Object[] newElements = Arrays.copyOf(elements, len + 1);

        // 添加元素到新数组中
        newElements[len] = e;

        // 把原数组引用指向新数组
        setArray(newElements);
        return true;
    } finally {
   
   
        lock.unlock();
    }
}

从上述代码可以看出,在添加的时候也会使用锁,如果不使用锁的话,在多线程写入时,可能会出现多个副本。

而加锁之后,会先复制一个新数组,进行写入操作,之后再将原数组指向新数组,整个添加操作执行完了。

当然,这两个容器只适合多读少写的场景,因为每次写入操作都要加锁和复制新数组进行操作,这些操作的性能开销都是很大的。

小结

都说字节的面试难,其实就难在底层知识问的多,以及有算法问题,所以想进大厂,这两项能力都要提升,勿在浮沙筑高台。愿好~

参考 & 鸣谢

www.cnblogs.com/chenssy/p/15142814.html

本文已收录到我的面试小站 www.javacn.site,其中包含的内容有:Redis、JVM、并发、并发、MySQL、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、设计模式、消息队列等模块。

相关文章
|
存储 安全 C语言
C语言中的数据类型
C语言中的数据类型
198 1
|
存储 缓存 Linux
【Linux】冯诺伊曼体系结构|操作系统概念理解
【Linux】冯诺伊曼体系结构|操作系统概念理解
|
缓存 Java Spring
学习Spring,@Autowired的这几个易错点你一定要知道!
前言 你是否懂得@Autowired注解在使用上的细节? 你是否在解决因@Autowired产生的异常而无处下手? 你是否了解@Autowired的基本原理? 我们在做项目的过程中,随着项目规模的增大、第三方服务的引入,项目中类与类之间的依赖关系错综复杂,而@Autowired作为在依赖注入中最常使用到的注解,若没有一定的知识储备,遇到问题就直接百度搜报错信息的话,很大程度会造成一杯茶一包烟,一个bug搞一天。 本篇文章我将从以上三个问题出发讲解@Autowired使用中容易出错的地方。 一.@Autowired的使用细节 1.依赖注入:@Autowired它可以对类成员变量、方法及构造函
155 0
|
9天前
|
存储 关系型数据库 分布式数据库
PostgreSQL 18 发布,快来 PolarDB 尝鲜!
PostgreSQL 18 发布,PolarDB for PostgreSQL 全面兼容。新版本支持异步I/O、UUIDv7、虚拟生成列、逻辑复制增强及OAuth认证,显著提升性能与安全。PolarDB-PG 18 支持存算分离架构,融合海量弹性存储与极致计算性能,搭配丰富插件生态,为企业提供高效、稳定、灵活的云数据库解决方案,助力企业数字化转型如虎添翼!
|
7天前
|
存储 人工智能 Java
AI 超级智能体全栈项目阶段二:Prompt 优化技巧与学术分析 AI 应用开发实现上下文联系多轮对话
本文讲解 Prompt 基本概念与 10 个优化技巧,结合学术分析 AI 应用的需求分析、设计方案,介绍 Spring AI 中 ChatClient 及 Advisors 的使用。
355 130
AI 超级智能体全栈项目阶段二:Prompt 优化技巧与学术分析 AI 应用开发实现上下文联系多轮对话
|
7天前
|
人工智能 Java API
AI 超级智能体全栈项目阶段一:AI大模型概述、选型、项目初始化以及基于阿里云灵积模型 Qwen-Plus实现模型接入四种方式(SDK/HTTP/SpringAI/langchain4j)
本文介绍AI大模型的核心概念、分类及开发者学习路径,重点讲解如何选择与接入大模型。项目基于Spring Boot,使用阿里云灵积模型(Qwen-Plus),对比SDK、HTTP、Spring AI和LangChain4j四种接入方式,助力开发者高效构建AI应用。
346 122
AI 超级智能体全栈项目阶段一:AI大模型概述、选型、项目初始化以及基于阿里云灵积模型 Qwen-Plus实现模型接入四种方式(SDK/HTTP/SpringAI/langchain4j)
|
20天前
|
弹性计算 关系型数据库 微服务
基于 Docker 与 Kubernetes(K3s)的微服务:阿里云生产环境扩容实践
在微服务架构中,如何实现“稳定扩容”与“成本可控”是企业面临的核心挑战。本文结合 Python FastAPI 微服务实战,详解如何基于阿里云基础设施,利用 Docker 封装服务、K3s 实现容器编排,构建生产级微服务架构。内容涵盖容器构建、集群部署、自动扩缩容、可观测性等关键环节,适配阿里云资源特性与服务生态,助力企业打造低成本、高可靠、易扩展的微服务解决方案。
1338 8