字节跳动后端二面

📍1. 数据库的事务性质,InnoDB是如何实现的?

数据库事务具有ACID特性,即原子性、一致性、隔离性和持久性。InnoDB通过以下机制实现这些特性:

🚀 实现细节:

  • 原子性:通过undo log实现事务回滚。
  • 一致性:通过事务的ACID属性和数据库约束保证。
  • 隔离性:使用锁和MVCC(多版本并发控制)实现不同隔离级别。
  • 持久性:利用redo log确保数据在系统崩溃后能够恢复。

🔧 MySQL事务示例:

START TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;

📍2. MySQL中数据的存储结构?

MySQL中的数据存储结构涉及表空间、段、区、页和行。InnoDB使用B+树结构存储数据和索引,聚簇索引将数据和主键索引存储在一起。

🚀 存储层次:

  • 表空间:逻辑存储单元。
  • :表空间内的逻辑部分,如数据段、索引段。
  • :由连续的页组成。
  • :最小存储单位,通常16KB。
  • :实际数据记录。

🔧 InnoDB数据存储示例:

SHOW TABLE STATUS LIKE 'table_name';

📍3. MySQL的主从复制原理以及主从延迟的解决方案?

MySQL主从复制通过binlog和中继日志实现数据同步。主从延迟可通过以下方法解决:

🚀 复制原理:

  • 主库记录binlog。
  • 从库I/O线程获取binlog并写入中继日志。
  • SQL线程执行中继日志中的SQL。

🚀 延迟解决方案:

  • 优化网络和硬件。
  • 并行复制。
  • 减少主库负载。
  • 使用半同步复制。

🔧 主从配置示例:

[mysqld]
log-bin=mysql-bin
server-id=1

📍4. Kafka怎么保证消息不丢、重复发了怎么办?

Kafka通过生产者、broker和消费者的协调保证消息不丢失。重复消息通过幂等性和去重机制处理。

🚀 消息不丢:

  • 生产者:设置acks=all。
  • Broker:使用持久化和min.insync.replicas。
  • 消费者:手动提交偏移量。

🚀 重复消息处理:

  • 幂等性生产者。
  • 消息去重。

🔧 Kafka生产者配置示例:

acks=all
retries=3

📍5. 你的项目中,接口调用如何保证幂等?

接口幂等性通过唯一标识符、乐观锁、分布式锁、状态机和Token机制实现,确保重复请求产生相同结果。

🚀 幂等实现:

  • 唯一标识符:使用UUID和数据库唯一索引。
  • 乐观锁:版本号控制。
  • 分布式锁:Redisson或ZooKeeper。

🔧 幂等性示例代码:

// 使用UUID生成唯一标识符
UUID uuid = UUID.randomUUID();

📍6. 你的项目中,如何保证分布式事务的一致性?

分布式事务一致性可通过两阶段提交、补偿事务、基于消息的最终一致性、最大努力通知和Saga模式实现。

🚀 一致性策略:

  • 两阶段提交(2PC):XA协议。
  • 补偿事务(TCC):Try-Confirm-Cancel。
  • 基于消息的最终一致性:消息队列。

🔧 Seata分布式事务示例:

<dependency>
    <groupId>io.seata</groupId>
    <artifactId>seata-all</artifactId>
    <version>1.4.2</version>
</dependency>

📍7. 项目中的限流怎么做的,为什么这么做?

限流通过固定窗口、滑动窗口、令牌桶和漏桶算法实现,保护系统稳定性、防止资源耗尽和恶意攻击。

🚀 限流算法:

  • 固定窗口:Guava RateLimiter。
  • 滑动窗口:Redis滑动窗口。
  • 令牌桶:令牌生成和消耗。

🚀 限流原因:

  • 保护系统稳定性。
  • 防止资源耗尽。

🔧 Guava RateLimiter示例:

RateLimiter rateLimiter = RateLimiter.create(10.0); // 每秒10个请求
rateLimiter.acquire(); // 获取令牌

📍8. 如何设计群消息已读?

群消息已读通过存储已读状态、消息发送接收同步、已读列表展示和批量更新实现,优化使用分页加载和缓存。

🚀 设计思路:

  • 已读状态存储:数据库或缓存。
  • 消息发送和接收:更新已读状态。
  • 已读列表展示:展示已读成员。

🔧 已读状态更新示例:

// 更新消息已读状态
updateMessageReadStatus(userId, messageId, true);

📍9. 多线程题目:10个线程模拟赛马,所有马就绪后才能开跑,所有马到达终点后裁判宣布赛马成绩。

问题描述:
使用多线程模拟赛马比赛,要求所有马(线程)都准备好后才能开始比赛,所有马到达终点后裁判宣布比赛结果。

解题思路:

  • 使用sync.WaitGroup来同步多个线程。
  • 使用sync.Mutex来保护共享资源的访问。
  • 每个马(线程)在准备好后通知主线程,主线程在所有马都准备好后发出开始信号。
  • 所有马到达终点后,裁判宣布比赛结果。

代码实现(Golang):

package main

import (
	"fmt"
	"sync"
	"time"
)

type Horse struct {
	ID     int
	Ready  bool
	Finish bool
	mu     sync.Mutex
}

func (h *Horse) run(start, finish *sync.WaitGroup) {
	defer finish.Done()

	// 马准备好
	h.mu.Lock()
	h.Ready = true
	h.mu.Unlock()
	fmt.Printf("Horse %d is ready!\n", h.ID)

	// 等待所有马准备好
	start.Wait()

	// 模拟赛跑
	time.Sleep(time.Duration(h.ID) * time.Second)
	h.mu.Lock()
	h.Finish = true
	h.mu.Unlock()
	fmt.Printf("Horse %d has finished!\n", h.ID)
}

func main() {
	const numHorses = 10
	var start, finish sync.WaitGroup
	horses := make([]*Horse, numHorses)

	// 初始化马
	for i := 0; i < numHorses; i++ {
		horses[i] = &Horse{ID: i + 1}
	}

	// 设置WaitGroup
	start.Add(1)
	finish.Add(numHorses)

	// 启动赛马线程
	for _, horse := range horses {
		go horse.run(&start, &finish)
	}

	// 等待所有马准备好
	for {
		allReady := true
		for _, horse := range horses {
			horse.mu.Lock()
			if !horse.Ready {
				allReady = false
			}
			horse.mu.Unlock()
		}
		if allReady {
			break
		}
		time.Sleep(100 * time.Millisecond)
	}

	// 所有马准备好,开始比赛
	fmt.Println("All horses are ready! Start racing!")
	start.Done()

	// 等待所有马到达终点
	finish.Wait()
	fmt.Println("All horses have finished! Race is over!")
}

代码解析:

  • Horse结构体:包含马的ID、准备状态、完成状态和一个互斥锁。
  • run函数:每个马(线程)的执行函数,模拟马的准备、等待开始信号、赛跑和到达终点。
  • 主函数:初始化马、设置WaitGroup、启动线程、等待所有马准备好、发出开始信号、等待所有马到达终点并宣布比赛结果。

📍10. LeetCode 394,给定一个经过编码的字符串,返回它解码后的字符串。

问题描述:
给定一个编码字符串,格式为k[encoded_string],其中k是一个正整数,encoded_string是一个字符串。要求解码这个字符串,返回解码后的结果。

解题思路:

  • 使用栈来处理嵌套的编码字符串。
  • 遍历字符串,遇到数字、字母、[]时分别处理。
  • 遇到数字时,解析完整的数字并压入数字栈。
  • 遇到[时,将当前的字符串压入字符串栈,并重置当前字符串。
  • 遇到]时,弹出数字栈和字符串栈,将当前字符串重复相应次数后与弹出的字符串拼接。
  • 遇到字母时,直接拼接到当前字符串。

代码实现(Golang):

package main

import (
	"fmt"
	"strconv"
	"strings"
)

func decodeString(s string) string {
	var numStack []int
	var strStack []string
	var currentNum int
	var currentStr strings.Builder

	for i := 0; i < len(s); i++ {
		char := s[i]

		switch {
		case char >= '0' && char <= '9':
			// 解析数字
			num, _ := strconv.Atoi(string(char))
			currentNum = currentNum*10 + num
		case char == '[':
			// 将当前数字和字符串压入栈
			numStack = append(numStack, currentNum)
			strStack = append(strStack, currentStr.String())
			// 重置当前数字和字符串
			currentNum = 0
			currentStr.Reset()
		case char == ']':
			// 弹出数字和字符串
			num := numStack[len(numStack)-1]
			numStack = numStack[:len(numStack)-1]
			prevStr := strStack[len(strStack)-1]
			strStack = strStack[:len(strStack)-1]
			// 重复当前字符串并拼接到前一个字符串
			currentStr.WriteString(strings.Repeat(currentStr.String(), num))
			currentStr = strings.Builder{}
			currentStr.WriteString(prevStr)
		default:
			// 字母直接拼接到当前字符串
			currentStr.WriteByte(char)
		}
	}

	return currentStr.String()
}

func main() {
	encoded := "3[a2[c]]"
	decoded := decodeString(encoded)
	fmt.Println(decoded) // 输出: "accaccacc"
}

代码解析:

  • numStack:用于存储数字的栈。
  • strStack:用于存储字符串的栈。
  • currentNum:当前解析的数字。
  • currentStr:当前解析的字符串。
  • 遍历字符串:根据字符类型分别处理数字、[]和字母。
  • 解码过程:通过栈的压入和弹出操作,处理嵌套的编码字符串。

欢迎关注我的小红书一起来讨论。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/970210.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【个人开发】cuda12.6安装vllm安装实践【内含踩坑经验】

1. 背景 vLLM是一个快速且易于使用的LLM推理和服务库。企业级应用比较普遍&#xff0c;尝试安装相关环境&#xff0c;尝试使用。 2. 环境 模块版本python3.10CUDA12.6torch2.5.1xformers0.0.28.post3flash_attn2.7.4vllm0.6.4.post1 2.1 安装flash_attn 具体选择什么版本&…

19.4.9 数据库方式操作Excel

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 本节所说的操作Excel操作是讲如何把Excel作为数据库来操作。 通过COM来操作Excel操作&#xff0c;请参看第21.2节 在第19.3.4节【…

2024-2025年主流的开源向量数据库推荐

以下是2024-2025年主流的开源向量数据库推荐&#xff0c;涵盖其核心功能和应用场景&#xff1a; 1. Milvus 特点&#xff1a;专为大规模向量搜索设计&#xff0c;支持万亿级向量数据集的毫秒级搜索&#xff0c;适用于图像搜索、聊天机器人、化学结构搜索等场景。采用无状态架…

vue项目使用vite和vue-router实现history路由模式空白页以及404问题

开发项目的时候&#xff0c;我们一般都会使用路由&#xff0c;但是使用hash路由还是history路由成为了两种选择&#xff0c;因为hash路由在url中带有#号&#xff0c;history没有带#号&#xff0c;看起来更加自然美观。但是hash速度更快而且更通用&#xff0c;history需要配置很…

AI编程01-生成前/后端接口对表-豆包(或Deepseek+WPS的AI

前言: 做过全栈的工程师知道,如果一个APP的项目分别是前端/后端两个团队开发的话,那么原型设计之后,通过接口文档进行开发对接是非常必要的。 传统的方法是,大家一起定义一个接口文档,然后,前端和后端的工程师进行为何,现在AI的时代,是不是通过AI能协助呢,显然可以…

切换git仓库远程地址

1、首先可以先查看一下当前git库的远程地址 【cd .git】 切换到git目录【cat config】查看【cd ../】 返回项目目录 2、 切换到目标远程git地址 【git remote rm origin】 删除现有远程仓库 【git remote add origin url】添加新远程仓库 【cat .git/config】验证是否切换成功…

mapbox 从入门到精通 - 目录

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;mapbox 从入门到精通 文章目录 一、&#x1f340;总目录1.1 ☘️ mapbox基础1.2 ☘️…

前端包管理器的发展以及Npm、Yarn和Pnpm对比

在现代前端开发中&#xff0c;包管理器是不可或缺的核心工具。随着 JavaScript 生态的快速发展&#xff0c;开发者经历了从 npm 一统天下到 Yarn 挑战格局&#xff0c;再到 pnpm 创新突破的技术演进。这里将对三种主流包管理器&#xff08;npm/Yarn/pnpm&#xff09;进行全方位…

Qt QOpenGLWidget详解

1. 概述 QOpenGLWidget 是 Qt 框架中用于集成 OpenGL 渲染功能的类&#xff0c;它继承自 QWidget&#xff0c;允许开发者在 Qt 应用程序中轻松嵌入 OpenGL 图形。通过继承 QOpenGLWidget 并重写其虚函数&#xff08;如 initializeGL()、resizeGL() 和 paintGL()&#xff09;&a…

Webpack包

黑马程序员视频地址&#xff1a; Node.js与Webpack-16.Webpack简介以及体验 前言&#xff1a; 本篇中部分标题后标有数字&#xff0c;代表学习顺序 &#xff0c;同时也可以作为使用顺序参考 webpack包 基础认识 初步使用 下载webpack包和webpack-cli包 注意点&#xff1a; 1…

MySQL数据库入门到大蛇尚硅谷宋红康老师笔记 基础篇 part 10

第10章_创建和管理表 DDL&#xff1a;数据定义语言。CREATE \ALTER\ DROP \RENAME TRUNCATE DML&#xff1a;数据操作语言。INSERT \DELETE \UPDATE \SELECT&#xff08;重中之重&#xff09; DCL&#xff1a;数据控制语言。COMMIT \…

【DeepSeek】DeepSeek R1 本地windows部署(Ollama+Docker+OpenWebUI)

1、背景&#xff1a; 2025年1月&#xff0c;DeepSeek 正式发布 DeepSeek-R1 推理大模型。DeepSeek-R1 因其成本价格低廉&#xff0c;性能卓越&#xff0c;在 AI 行业引起了广泛关注。DeepSeek 提供了多种使用方式&#xff0c;满足不同用户的需求和场景。本地部署在数据安全、性…

【Pico】使用Pico进行无线串流搜索不到电脑

使用Pico进行无线串流搜索不到电脑 官串方式&#xff1a;使用Pico互联连接电脑。 故障排查 以下来自官方文档 请按照以下步骡排除故障&#xff1a; 确认电脑和一体机连接了相同的路由器WiFi网络(相同网段) IP地址通常为192.168.XX&#xff0c;若两设备的IP地址前三段相同&…

DeepSeek教unity------MessagePack-02

内置支持类型&#xff1a; 对象序列化 MessagePack for C# 可以序列化你自己定义的公共类或结构体类型。默认情况下&#xff0c;可序列化的类型必须用 [MessagePackObject] 属性进行注解&#xff0c;成员需要用 [Key] 属性进行注解。键可以是索引&#xff08;整数&#xff09;…

部门管理(体验,最原始方法来做,Django+mysql)

本人初学&#xff0c;写完代码在此记录和复盘 在创建和注册完APP之后&#xff08;我的命名是employees&#xff09;&#xff0c;编写models.py文件创建表 手动插入了几条数据 1.部门查询 urls.py和views.py在编写之前&#xff0c;都要注意导入对应的库 urls.py&#xff1a;…

爬虫实战:利用代理ip爬取推特网站数据

引言 亮数据-网络IP代理及全网数据一站式服务商屡获殊荣的代理网络、强大的数据挖掘工具和现成可用的数据集。亮数据&#xff1a;网络数据平台领航者https://www.bright.cn/?promoRESIYEAR50/?utm_sourcebrand&utm_campaignbrnd-mkt_cn_csdn_yingjie202502 在跨境电商、社…

C#windows窗体人脸识别

一、创建一个数据库&#xff0c;名为TestFaceDB 里面有一张表就OK了&#xff0c;表名Users,表里面有几个字段我说明一下&#xff1a; id--------------------bigint----------------------编号 name--------------varchar(50)-----------------用户名 phone--------------v…

opencv中minAreaRect函数输出角度问题

opencv中minAreaRect函数输出角度问题 新版opencv中minAreaRect函数计算最小外接矩形时&#xff0c;角度范围由旧版的[-90, 0]变为[0, 90]。 cv2.minAreaRect输入&#xff1a;四边形的四个点&#xff08;不要求顺序&#xff09;。 输出&#xff1a;最小外接矩形的中心点坐标x…

Eclipse:关闭多余的工具条

Eclipse默认的工具条非常多&#xff0c;可以通过如下方法选择关闭一些不常用的&#xff1a; 1.选择菜单Window -> Perspective -> Customize Perspective 2.根据需要勾选Toolbar Visbility下面的工具条项