Interview Preparation

本文详细解析了递归在约瑟夫环问题中的应用,介绍了单链表两两反转的递归解法,涵盖了子数组、对称二叉树、逆序链表和树的子结构等算法实例。此外,还涉及了数学上的最大公约数算法,数据库的MySQL逻辑架构、日志机制,以及事务的ACID特性和分布式理论关键概念。
摘要由CSDN通过智能技术生成

算法

递归

考察抽象能力、定义函数方法,大问题化为子问题,递归出口

1. 约瑟夫环

题目:n个人围成一圈(编号从1到n),从第1个人开始报数,报到m的人出列,从下一个人再重新报数,报到m的人出列,如此下去,直至所有人都出列。求最后一个出列的人的编号(使用递归)

2. 单链表两两反转

单链表两两反转这种题,非常适合用递归的思想来解决,将每一步操作都封闭在一个小单元内,然后重复操作。递归能做的,通常循环也能做。

3. 子数组

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
https://leetcode-cn.com/problems/subsets/

4.对称二叉树

请实现一个函数,用来判断一棵二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
https://blog.csdn.net/gs_albb/article/details/115450988

5.逆序打印链表

https://www.nowcoder.com/practice/d0267f7f55b3412ba93bd35cfa8e8035?tab=answerKey

6.树的子结构

leetcode 26题

7.全排列(回溯)

剑指 offer

数学

a 求两个数的最大公约数gcd

lucene gcd算法


数据库

1. mysql逻辑架构图

架构图


2. mysql重要的日志redo-log

redo-log(重做日志)保证了mysql数据库crash-safe(mysql异常宕机重启不会丢失数据)的能力。
试想,如果mysql每update一条语句,都要取磁盘寻址找到数据,更新,刷磁盘,将会非常耗时;mysql将update语句操作的数据临时顺序写到redo-log文件里(顺序写,效率高),同时更新内存,在空闲时间innoDB引擎再将redo-log中记录的变更同步刷到磁盘上。redo-log是innoDB引擎特有的日志。

3.mysql重要的日志binlog

  1. binlog处在server层,所有引擎都可使用;redo-log是innoDB引擎所特有的机制。
  2. Binlog有两种模式,statement 格式的话是记sql语句, row格式会记录行的内容,记两条,更新前和更新后都有。
  3. redo log 是循环写的,空间固定会用完;binlog 是可以追加写入的。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志

4. 一条update语句的执行流程(两阶段提交)

  1. 执行器先找引擎取 ID=2 这一行。ID 是主键,引擎直接用树搜索找到这一行。如果 ID=2 这一行所在的数据页本来就在内存中,就直接返回给执行器;否则,需要先从磁盘读入内存,然后再返回。
  2. 执行器拿到引擎给的行数据,把这个值加上 1,比如原来是 N,现在就是 N+1,得到新的一行数据,再调用引擎接口写入这行新数据。
  3. 引擎将这行新数据更新到内存中,同时将这个更新操作记录到 redo log 里面,此时 redo log 处于 prepare 状态。然后告知执行器执行完成了,随时可以提交事务。
  4. 执行器生成这个操作的 binlog,并把 binlog 写入磁盘。
  5. 执行器调用引擎的提交事务接口,引擎把刚刚写入的 redo log 改成提交(commit)状态,更新完成。
    在这里插入图片描述

5.如何理解事务的ACID特性

官方文档

ACID代表原子性,一致性,隔离性和持久性的首字母缩写。这些属性在数据库系统中都是理想的,并且都与事务的概念紧密相关。 InnoDB的事务功能遵循ACID原则。

事务是可以提交或回滚的原子工作单元。当事务对数据库进行多次更改时,要么在提交事务后所有更改成功,要么在回滚事务后撤消所有更改。

在每次提交或回滚之后以及正在进行事务时,数据库始终保持一致状态。如果跨多个表更新相关数据,则查询将看到所有旧值或所有新值,而不是新旧值的混合。

事务在进行过程中相互保护(隔离);他们不能互相干扰,也不能看到彼此的未提交数据。这种隔离是通过锁定机制实现的。有经验的用户可以确定事务确实不会相互干扰时,可以调整隔离级别,权衡较少的保护以提高性能和并发性。

事务的结果是持久的:提交操作成功后,该事务所做的更改就不会出现电源故障,系统崩溃,竞争状况或许多非数据库应用程序容易受到的其他潜在危险。耐久性通常涉及到磁盘存储的写入,并具有一定数量的冗余以防止写入操作期间的电源故障或软件崩溃。 (在InnoDB中,双写缓冲区有助于持久性。)

6.隔离型和隔离级别

当数据库上有多个事务同时执行的时候,就可能出现脏读(dirty read)、不可重复读(non-repeatable read)、幻读(phantom read)的问题,为了解决这些问题,就有了“隔离级别”的概念。

脏读:读到其他事务未提交的数据;
不可重复读:前后读取的记录内容不一致;
幻读:前后读取的记录数量不一致。)==

SQL 标准的事务隔离级别包括:读未提交(read uncommitted)、读提交(read committed)、可重复读(repeatable read)

读未提交是指,一个事务还没提交时,它做的变更就能被别的事务看到。

读提交是指,一个事务提交之后,它做的变更才会被其他事务看到。

可重复读是指,一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。当然在可重复读隔离级别下,未提交变更对其他事务也是不可见的。

串行化,顾名思义是对于同一行记录,“写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。

7. 什么是覆盖索引

不用回表即可获取到目标查询字段,见 https://www.cnblogs.com/happyflyingpig/p/7662881.html

8. 最左前缀及索引下推

涉及到联合索引,最左前缀,MySQL 5.6 引入的索引下推优化(index condition pushdown), 可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数。

9. MVCC机制与undo-log

开启事务

begin/start transaction 命令并不是一个事务的起点,在执行到它们之后的第一个操作 InnoDB 表的语句,事务才真正启动。如果你想要马上启动一个事务,可以使用 start transaction with consistent snapshot 这个命令。

事务id概念

InnoDB 里面每个事务有一个唯一的事务 ID,叫作 transaction id。它是在事务开始的时候向 InnoDB 的事务系统申请的,是按申请顺序严格递增的。

而每行数据也都是有多个版本的。每次事务更新数据的时候,都会生成一个新的数据版本,并且把 transaction id 赋值给这个数据版本的事务 ID,记为 row trx_id。

同时,旧的数据版本要保留,并且在新的数据版本中,能够有信息可以直接拿到它。也就是说,数据表中的一行记录,其实可能有多个版本 (row),每个版本有自己的 row trx_id。

在这里插入图片描述
undo-log在哪

实际上,图 中的三个虚线箭头,就是 undo log;而 V1、V2、V3 并不是物理上真实存在的,而是每次需要的时候根据当前版本和 undo log 计算出来的。比如,需要 V2 的时候,就是通过 V4 依次执行 U3、U2 算出来。

一致性视图

在实现上, InnoDB 为每个事务构造了一个数组,用来保存这个事务启动瞬间,当前正在“活跃”的所有事务 ID。“活跃”指的就是,启动了但还没提交。
数组里面事务 ID 的最小值记为低水位,当前系统里面已经创建过的事务 ID 的最大值加 1 记为高水位。
这个视图数组和高水位,就组成了当前事务的一致性视图(read-view)。

数据版本可见性原则

一个数据版本,对于一个事务视图来说,除了自己的更新总是可见以外,有三种情况:版本未提交,不可见;版本已提交,但是是在视图创建后提交的,不可见;版本已提交,而且是在视图创建前提交的,可见。

当前读

更新数据都是先读后写的,而这个读,只能读当前的值,称为“当前读”(current read)。
除了 update 语句外,select 语句如果加锁(lock in share mode 或 for update),也是当前读。

两阶段锁协议

当前读必须要读最新版本 如果此时该行数据上有事物尚未提交,则当前事务必须等待锁。

分布式理论

1.分布式事务一致性

https://zhuanlan.zhihu.com/p/183753774

2.分布式锁

https://www.jianshu.com/p/9055ca856aaf
数据库、redis、zookeeper;
redis实现中为防止其他线程释放了自己的锁,锁的value最好是uuid,释放之前判断下缓存中值是否一致。

Java

1. SPI加载机制

https://zhuanlan.zhihu.com/p/67665359

2. 轻量级锁、偏向锁、重量级锁

结论语

如果说轻量级锁是在无竞争的情况下使用CAS操作去消除同步使用的互斥量,那偏向锁就是在无竞争的情况下把整个同步都消除掉,连CAS操作都不用了。
如果有两条以上的线程争用同一个锁,那轻量级锁就不再有效,要膨胀为重量级锁,锁标志的状态值变为10,Mark Word中存储的就是指向重量级锁(互斥量)的指针,后面等待锁的线程也要进入阻塞状态。

https://blog.csdn.net/lengxiao1993/article/details/81568130

3. 字节码增强技术

字节码增强技术探索

4.垃圾回收算法

标记-清除算法
复制算法
标记-整理算法

分代收集算法。新生代对象死多活少,宜采用复制算法;老年代对象存活率高,宜采用“标记-清除”或者“标记-整理"算法。

5.G1垃圾回收流程

Region区域概念,G1将整个Java堆划分为多个大小相等的独立区域(Region)。G1跟踪各个Region里面的垃圾堆积的价值大小(回收所获得的空间大小及回收所需时间),后台维护一个优先列表,根据允许的收集时间,优先回收价值大的Region(Garbage-First)的由来。

RememberSet。G1中每个Region都有一个与之相应的RememberSet,在GC根节点的枚举范围中加入Remember Set即可保证不对全堆扫描也不会有遗漏。

G1回收大致可以分为以下几个步骤
初始标记
并发标记
最终标记(暂停用户线程,将并发标记过程中产生的增量垃圾再标记一次)
筛选回收

ConcurrentHashMap实现原理

https://segmentfault.com/a/1190000039087868

缓存

redis

1.redis的三个主要特点

Redis数据库完全在内存中,使用磁盘仅用于持久性。
相比许多键值数据存储,Redis拥有一套较为丰富的数据类型。
Redis可以将数据复制到任意数量的从服务器。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值