1.抽象类与接口
接口的出现:
- 有时候,必须从多个类中派生出一个类,但是java中的类是单继承的
- 从几个类中抽取出一些共同的行为特征,但是他们之间没有is-a的关系,仅仅是具有相同的行为特征而已
相同点
- 都不能被实例化
- 接口的实现类和抽象类的子类只有全部实现了接口或者抽象类中的方法后才可以被实例化
不同点
- 抽象类中可以有普通成员变量,接口中没有
- 抽象类中有非抽象的普通方法,接口中只有抽象方法
- 抽象类中的抽象方法的访问类型可以是public,protected,接口中的抽象方法只能是public的
- 抽象类和接口中都可以包括静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型的,接口中都是常量
- 一个类可以实现多个接口,但是只能集成一个抽象类
2.多态
3.四种引用
- 强引用:java默认的引用,垃圾回收器永远不会回收被引用的对象,内存不足会抛出异常
- 软引用:内存足够,不会被回收,内存不足,系统会回收软引用对象,如果回收了软引用之后仍然没有足够的内存,才会抛出内存溢出异常,常被用来实现缓存技术
SoftReference<byte[]> sr = new SoftReference<>(buff);
java.lang.ref.SoftReference类来表示软引用
- 弱引用:无论内存是否足够,只要JVM开始进行垃圾回收,弱引用关联的对象都会被回收
WeakReference<byte[]> sr = new WeakReference<>(buff)
用 java.lang.ref.WeakReference 来表示弱引用
- 虚引用:随时可能被回收,和没有任何引用一样,查看源码发现它只有一个构造函数和一个 get() 方法,而且它的 get() 方法仅仅是返回一个null,也就是说将永远无法通过虚引用来获取对象必须和引用队列ReferenceQueue 一起使用
用 PhantomReference 类来表示
4.锁,并发怎么处理
加锁防止并发
-
共享锁,读锁,可以查看但无法修改和删除数据,当数据库被别人增加了读锁的时候,其他新来的事务可以读数据,但是不能写,也就是,如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排他锁,获得共享锁的事务只能读数据,不能修改数据
-
排他锁,写锁,既能读数据,也能修改数据。如果数据库已经被别人加了排他锁,那么后面的事务无法在数据库上加任何锁
-
悲观锁,借助数据库锁机制,在修改数据之前先锁定,一个事务如果锁定了某行数据,其他事务必须等待该事务处理完才可以处理那行数据。
- 在对记录修改前,先尝试为该记录加上排他锁
- 如果加锁失败,说明该记录正在被修改
- 如果枷锁成功,就可以对该记录做修改
- 其间如果有其他事务要对该记录做加锁的操作,都要等待或者抛异常
-
乐观锁,不会使用数据库提供的锁机制,记录数据版本
5.进程和线程的区别
- 程序:一段静态的代码
- 进程:在系统中正在运行的一个应用程序,程序一旦运行就是进程,进程是资源分配的最小单位,支持多线程,同一时间并行执行多个线程
- 线程:系统分配处理器时间资源的基本单位,进程之内独立执行的一个单元执行流,线程是程序执行的最小单位,一个程序内部的一条执行路径,
- 一个程序至少一个进程,一个进程中至少有一个线程
- 进程要分配一大部分的内存,线程只需要分配一部分栈就可以了
6.shuffle机制 mapreduce流程
- shuffle是map之后,reduce之前的操作,在map task端和reduce task端都有,首先map处理之后的结果进入到shuffle阶段,在进入到环形缓冲区之前,先进行分区,环形缓冲区相当于内存,map之后的数据写到缓冲区,当到80%的时候开始反向溢写,可以看做又开了一个线程,之前的继续写到缓冲区,新的将缓冲区的溢写到磁盘,在溢写之前,进行一次快排,保证区内有序,当所有的文件都溢写到磁盘之后,再进行一次归并排序,保证区内有序,最后都保存到了磁盘上,这时reduce来拉取对应分区的数据,并进行一次归并排序,按照相同的key分组,相同的key进入到同一个reduce中。
- mapreduce,首先提交job,向yarn提交三份东西,split,jar,xml,开启mrAppmaster,根据切片数开启map task的个数。
7.JVM虚拟机,为什么需要虚拟机
- java虚拟机(java virtual machine JVM) 来负责java程序在该系统中的运行
- 通过java语言编写的应用程序在不同的系统平台上都可以运行
8.内存区域,五部分。栈和堆区别,具体存放的东西?String在哪里?字符串池或者内存中新开辟(应该是这样)。线程在哪里?(是不是堆中?)
- 程序计数器
- 虚拟机栈:局部变量
- 本地方法栈
- 堆:new的对象和成员变量
- 方法区:类信息、静态变量和常量,常量池属于方法区(存放字面量和符号引用)
- String有两种定义方法,字面量定义存储在方法区的字符串常量池中,new的方法定义存储在堆中。
- 线程:共享一套堆和方法区,每个线程的栈是互相独立的。
- 进程:一个进程有一个堆,这个堆为本进程中所有线程共享。
总结
- 栈:为即时调用的方法开辟空间,存储局部变量、变量引用
- 堆:存放引用类型的对象,new出来的,数组值,类的非静态成员变量值(基本数据类型)
- 方法区:存放class二进制文件,包括类信息、静态变量、常量池(string字符串和final修饰的常量值),类的版本号
- 堆用来存放对象,栈用来执行程序。栈的存取速度快,但是大小和生成周期必须确定。
- 成员变量:静态的存在方法区,非静态的存在堆中。
9.ArrayList和LinkedList区别?底层实现?两者扩容机制
相同点
- 三个类都实现了list接口,存储数据的特点相同,存储有序的、可重复的数据
不同点
- Arraylist:底层使用Object[]数组存储
- Linkedlist:对于频繁的插入、删除操作,使用。底层使用双向链表存储
- Vector:底层使用Object[]数组存储
arraylist扩容
- 默认构造器长度是10,如果已经add了10个元素,添加第11个元素的时候,需要扩容
- 默认情况下,容量扩容为原来的1.5倍,
- 扩容之后,相当于新造了一个数组,需要将原来数组的元素copy过来
linkedlist扩容
- 新增一个node,node定义为pre,next,把pre指向last。
10.集合相关
set:无序不可重复的
list:有序可重复的
map:有映射关系的集合
queue
11.数仓分层
- ODS 原始数据层
- DWD 数据明细层,经过预处理,脱敏等。一行表示一个业务行为
- DWS 数据汇总层,按天进行轻度汇总,一行信息表示一个主题对象一天的汇总行为
- DWT数据主题层,对数据进行累积汇总,一行信息表示一个主题对象的累积行为
- ADS 数据应用层,为各种报表提供数据
- DIM 数据维度层,保存的维度信息,表示的是对业务事实描述信息
12.Hive的优化策略,分区,分桶
分区
- 分区针对的是数据的路径
- 分区字段不能在表中出现,分区字段存储在mysql的元数据中,在HDFS上是以路径形式存在
- 一个分区表的分区信息:有多少分区,说明在HDFS上上有多少子文件夹
- 在where语句中有分区信息,避免全表查询
- 可以进行二级分区,创建分区表时patitioned by(字段1,字段2),添加数据时load data local inpath*** into table ** patition(字段1= ,字段2=)
- 让分区表和数据关联
- 1.修复分区,检查hdfs上的分区信息,补充到元数据中 msck repair table 表名
- 2.alter table 表名 add partition(字段)
- 3.创建路径后直接load数据(load会修改元数据)load data local inpath*** into table ** patition(字段1= ,字段2=)
分桶
13hashmap的底层实现原理
- Map:双列数据,存储key-value对的数据
- jdk7之前,数据+链表;jdk8:数组+链表+红黑树
- key是用set存储,不能重复,无序;value可以重复,无序,使用collection存储所有的value
- 一个键值对key-value组成了一个entry
- map中的entry:无序的,不可重复的,使用set存储所有的entry
- key所在的类要重写equals和hashcode方法;value类要重写equals方法
底层实现原理
- 总结,hashmap是由数组+链表构成,数组是hashmap的主体,链表是为了解决哈希冲突。
- 数组是主干:当新增或查找某个元素时,通过把当前元素的关键字通过哈希函数映射到数组中某个位置,通过数组下标一次定位即可
- 哈希冲突:两个不同的元素,通过哈希函数定位到同一个实际存储地址。采用链地址法解决。即数组+链表
- 如果定位到的数组位置不含链表,next指向null,对于添加和查找仅需一次寻址
- 如果定位到的数组包含链表,对于添加操作,首先遍历链表,存在即覆盖,否则新增;对于查找操作,仍需遍历链表,然后通过key对象的equal方法逐一对比查找
14.Mysql索引
索引的本质:索引是一种数据结构。目的在于提高查询效率,类比字典。是排好序的快速查找的数据结构。
-
create [unique] index indexname on tablename(columnname(length))
-
alter tablename add [unique] index indexname on(columnname(length));
-
两大功能:排序和查找、影响where后面的查找和order by后的排序
-
索引会将该列按照一定的方法进行存储,这样在查找的时候,不需要从第一条记录开始读完整个表,而是可以直接到达一个位置去搜索,节省时间。底层使用的是B+树,索引的作用是做数据的快速检索,快速检索的本质是数据结构。
-
索引本身很大,不可能全部存储在内存中,因此索引以索引文件的形式存储在磁盘上。
-
哈希表:但是存在数据碰撞,哈希函数对不同的key计算出一个结果,为了解决哈希碰撞,用链表把碰撞的数据连起来,有则一直遍历到链表尾,直达找到真正的 key 对应的数据为止。为什么不使用哈希表:范围查找时,一次把数据找出来加载到内存,然后再从内存里筛选目标范围内的数据
-
二叉查找树:在极端情况下会退化为线性链表,时间复杂也从O(logn)退化为O(n),存在不平衡导致检索性能降低,不能直接用于实现Mysql底层索引。
-
红黑树,通过左旋右旋结点自动调整树的形态
-
自平衡二叉树AVL,查找性能O(logn)好,可以实现范围查找,但是考虑磁盘IO,每一个树的结点只存储了一个数据,因此一次磁盘IO只能取出来一个结点上的数据加载到内存,消耗时间(设计数据库索引需要首先考虑尽可能减少磁盘IO的次数,因为磁盘IO的特点时从磁盘读取1kb和1b数据消耗的时间差不多),因此改进思路:一个结点多存储数据,这样一次磁盘IO就可以多加载数据到内存
-
B树,每个结点限制最多存储两个key,B树一个结点里存储的数据,所以B树一个结点存不了很多个数据,但是B+树一个结点可以存很多索引,叶子结点存所有数据。时间复杂度是o(logn)
-
B+树,存储的是索引,地址,叶子结点存储数据,用链表串联,便于范围查找,因此Mysql数据库的索引用的就是B+树。时间复杂度O(logN)
优点
- 任意字段都可以设置索引
- 大大加快查询的速度
- 提高数据检索的效率,降低数据库的IO成本
- 通过索引列对数据进行排序,降低数据排序的成本,降低了cpu的消耗
缺点
- 创建索引和维护索引要耗费时间
- 索引占内存
- 对表中数据进行增删改查时,索引也需要动态的维护,降低更新表的速度
应用
- 经常更新的表避免过多索引
- 经常需要查询的字段应该设置索引
- 数据量小的表不要索引
- 一个字段的值少(男女)不要建索引,值多要建立索引
分类
- 单列索引:一个索引只包含单个列,一个表可以有多个单列索引
- 普通索引
- 唯一索引:索引列中的值唯一,允许为空
- 主键索引 :特殊的唯一索引,值不允许为空
- 组合索引
- 全文索引
- 空间索引
15.关系型数据库和非关系型数据库的区别
关系型数据库
- 依据关系模型来创建的数据库
- 关系模型是“一对一、一对多、多对多”等关系模型,关系模型就是二维表格模型,因而一个关系型数据库就是由二维表及其之间的联系组成的一个数据组织
- 关系型数据库可以很好地存储一些关系模型的数据,比如一个老师对应多个学生的数据,一本书对应多个多个作者,一本书对应一个出版日期
- 常见的关系型数据库:Oracle、DB2、PostgreSQL、Microsoft SQL Server、Microsoft Access、MySQL
- 存储在磁盘上(安全,断电也没关系),不节省空间
非关系型数据库
- 基于非关系模型的数据库
- 非关系模型包括:列模型(存储的数据是一列列的。关系型数据库以一行作为一个记录,列模型数据库以一列为一个记录。(这种模型,数据即索引,IO很快,主要是一些分布式数据库);键值对模型:存储的数据是一个个键值对,比如name:liming,那么name这个键里面存的值就是liming;文档类模型:以一个个文档来存储数据
- 常见的非关系型数据库:列模型:Hbase,键值对模型:redis,MemcacheDB,文档类模型:mongoDB
- 存储在内存中(效率高),不安全(断电丢失数据),但是很多非关系型数据库都开始转存到磁盘上。
16.HDFS分布式文件系统如何进行存储的
将一个文件放在多台服务器上存储,按照文件快的方式存储,不同block可以存储在不同的服务器上,由Datanode实际存储。
- 是文件系统,用来存储文件,通过目录树来定位文件,适合一次写入,多次多出。一个文件经过创建、写入和关闭之后就不需要改变,只能追加,不能修改
17.hive是什么
是基于Hadoop的一个数据仓库工具,相当于hadoop的客户端。将结构化的数据文件映射为一张表,并提供类sql查询功能
- 数据存储在HDFS上
- 分析数据底层的实现是MapReduce
- 执行程序是在yarn上
18.hive中外表和内表的区别
内表
- 内表数据由Hive自身管理,外表数据由HDFS管理
- 删除内表时会直接删除元数据和存储数据,删除外表时只删除元数据,HDFS上的文件不会删除。
- 删除内表,重新创建一个一样的内标,数据不会装载
外表
- 删除外表,重新创建一个一样的外表,数据会自动装载
- 外部表的数据生命周期不受hive控制,而且可以与其他外部表进行数据共享
总结
- 导入数据到外部表的时候,数据没有移动到这个表自己的数据仓库目录下,但是内部表移动了
- 删除内部表的时候,hive会把属于表的元数据和数据全部删除;而删除外部表的时候,hive仅仅删除外部表的元数据,数据没有删除
- 对内部表的修改会将修改直接同步给元数据,但是对外部表结构和分区进行修改,则需要修复
创建语句
- create table时,HDFS上就会有一个对应的文件夹,文件夹就是表名,当把文件移动到表文件夹下面才能解析成功
- load data会转移数据,load某文件夹下的数据到表中的时候,该文件夹下的数据会消失,因为这个数据到了表文件夹下
19.hive元数据中有什么
存储hive版本
hive数据库相关元数据表
- DBS:存储hive中所有数据库的基本信息,数据库ID,数据库名、数据HDFS路径、数据库所有者名字、所有者角色
- DATABASE_PARAMS:存储数据库的相关参数
hive表和视图相关的元数据表
- TBLS:该表中存储Hive表,视图,索引表的基本信息
- TABLE_PARAMS:该表存储表/视图的属性信息
- TBL_PRIVS:该表存储表/视图的授权信息
Hive文件存储信息相关的元数据表
- DS:该表保存文件存储的基本信息,如INPUT_FORMAT、OUTPUT_FORMAT、是否压缩等
- SD_PARAMS: 该表存储Hive存储的属性信息,在创建表时候使用STORED BY ‘storage.handler.class.name’ [WITH SERDEPROPERTIES (…)指定。
- SERDES:该表存储序列化使用的类信息
- SERDE_PARAMS:该表存储序列化的一些属性、格式信息,比如:行、列分隔符
hive表字段相关的元数据表
hive表分区相关的元数据表
- PARTITIONS:该表存储表分区的基本信息
- PARTITION_KEYS:该表存储分区的字段信息
- PARTITION_KEY_VALS:该表存储分区字段值
- PARTITION_PARAMS:该表存储分区的属性信息
20.MySQL有什么引擎,有什么区别?
逻辑架构:连接、服务、引擎、存储
存储引擎
- MyISAM:不支持外键,不支持事务,表锁,即使操作一条记录也会锁住整个表,不适合高并发的操作,只缓存索引,不缓存真实数据,表空间小,关注性能,在读取数据方面性能很高
- InnoDB:支持外键、支持事务,行锁,操作时只锁某一行,不对其他行有影响,适合高并发操作,不仅缓存索引还要缓存真实数据,对内存要求高,表空间大,关注事务
- MEMORY
- Archive
21.MySQL中char和varchar有什么区别?
char
- 长度固定,创建表时就固定了,在右边填充空格达到指定的长度,当检索到char值,尾部的空格被删除掉,对于MyISAM表,推荐char类型
varchar
- 长度可变,要在总长度上加1字符,用来存储位置,对于InnoDB表,推荐varchar类型
22.详细说下数据库事务的特点
23.hadoop中的shuffle机制
24.聚簇索引
聚簇索引
- 不是单独的索引类型,是一种数据存储方式
- 按照每张表的主键构造一棵B+树,叶子节点中存放的是整张表的行记录数据,叶子节点也成为数据页(磁盘块)
- 索引组织表中,数据也是索引的一部分,每张表只能有一个聚簇索引
- Innodb通过主键聚集数据,如果没有定义主键,innodb会选择非空的唯一索引代替。如果没有这样的索引,innodb会隐式的定义一个主键来作为聚簇索引。
辅助索引(二级索引)
- 在聚簇索引之上创建的索引为辅助索引
- 辅助索引的叶子节点存储的不是行的物理位置,而是主键值
- 通过辅助索引首先找到主键值,通过主键值找到数据行的数据页
- 叶子节点除了包含键值外,还包含了相应行数据的聚簇索引值。辅助索引的存在不影响数据在聚簇索引中的组织,所以一张表可以有多个辅助索引。在innodb中有时也称辅助索引为二级索引
总结
- 索引内部都是B+树
- 辅助索引是为了需要找主键索引的二级索引,先找到主键索引再通过主键索引找到数据
- 支持覆盖索引:指一个查询语句的执行只用从索引中就能够取得,不必从数据表中读取
InnoDB索引实现
- 表数据文件本身就是按照B+树组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录,索引的key是数据表的主键
- (1)主键索引
- (2)辅助索引
- 所有辅助索引都引用主键作为data域,辅助索引也包含主键列
- (3)如何通过索引查找数据
- 如果使用 "where id = 14"这样条件查找,直接按照B+树的检索算法即可查找到对应的叶节点,获得行数据
- 如果对name列进行条件搜索,第一步在辅助索引B+树中检索Name,到达叶子节点获取对应的主键;第二步使用主键在主索引B+树中再执行一次B+树检索操作,最终到达叶子节点即可获取整行数据。
24非聚簇索引
MyISAM引擎
- (1)主键索引
- 使用B+树作为索引结构,叶子节点存放的是数据记录的地址
- 通过key-buffer把索引先缓存到内存中,当通过索引访问数据时,在内存中直接搜索索引 ,然后通过索引找到磁盘相应数据
- (2)辅助索引
- 在结构上,辅助索引和主键索引在结构上没有区别,只是主键索引要求key是唯一的,而辅助索引的key可以重复
- 表数据存储在独立的地方,这两颗树的叶子节点都使用一个地址指向真正的表数据,对于表数据,这两个键没有任何差别
- 索引树是独立的,通过辅助键检索无需访问主键的索引树
- 也是一颗B+树,data域保存数据记录的地址,按照B+树搜索算法搜索索引,如果指定的key存在,则取出其data域的值,然后以data域的值为地址,读取相应数据记录
-
25.B-树索引和B+树索引
链接: link.
磁盘
- 系统从磁盘读数据到内存是以磁盘块(block)为基本单位得,位于同一个磁盘块得数据会被一次性读取出来,不是需要什么取什么
- 硬盘得最小存储单位是扇,硬盘本身没有block得概念,而文件系统不是一个扇区来读的,太慢,所以block是文件存储的最小单位,现在一个block是由8个连续扇区组成
InnoDB存储引擎
- 页是磁盘管理的最小单位,把数据从磁盘读入到内存中是以页为基本单位,在查询数据时,如果一个页中每条记录都能有助于定位数据记录的位置,这将会减少磁盘I/O次数,提高查询效率。
B-树
- 将一条记录定义为一个二元组[key, data],key是记录的键值,对应的是表中的主键值。data是一行记录中除主键外的数据,对于不同的记录,key值互不相同。
- 一个m阶的B-树特性
- 1.每个结点最多有m个孩子
- 2.除了根节点和叶子节点外,其他结点至少有m/2向上取整个孩子
- 3.如果根节点不是叶子结点,则至少有2个孩子
- 4.所有叶子结点在同一层,不包含其他关键字信息(可以是指针)
- 5.每个非终端结点包含n个关键字(P0,P1,…Pn, k1,…kn)
- 6.关键字的个数满足:ceil(m/2)-1 <= n <= m-1
- 7.ki(i=1,…n)为关键字,且关键字升序排序。
- 8.Pi(i=1,…n)为指向子树根节点的指针。P(i-1)指向的子树的所有节点关键字均小于ki,但都大于k(i-1)
- 每个节点占用一个盘块的磁盘空间,一个节点上有两个升序排序的关键字和三个指向子树根节点的指针,指针存储的是子节点所在磁盘块的地址。两个关键词划分成的三个范围域对应三个指针指向的子树的数据的范围域。
B+树
- 区别
- 非叶子节点只存储键值信息,key和指针,存储的不是真实数据
- 所有叶子节点都有一个链指针,存储的是真实数据和主键值
- 数据记录都存放在叶子节点中
-
聚集索引的B+Tree中的叶子节点存放的是整张表的行记录数据。辅助索引与聚集索引的区别在于辅助索引的叶子节点并不包含行记录的全部数据,而是存储相应行数据的聚集索引键,即主键。当通过辅助索引来查询数据时,InnoDB存储引擎会遍历辅助索引找到主键,然后再通过主键在聚集索引中找到完整的行记录数据。
26.Hash索引和B+Tree索引的区别
hash索引:包括哈希码和行记录指针
- 基于哈希表实现,只有查询条件精确匹配hash索引中的所有列的时候,才有效
- 对于每一行数据,存储引擎都会对所有索引列计算一个哈希码,哈希码是一个较小的值,不同键值的行计算出的哈希码也不一样
- 哈希索引将所有的哈希码存储在索引中,同时保存指向每个数据行的指针
- 如果多个列的哈希值相同,索引会以链表的方式存放多个记录指针到同一个哈希条目中去
- 哈希索引中,哈希码是顺序的,所以对应的数据行是乱序的
哈希索引和b树得区别
- 哈希索引只支持等值查询(=、 IN 、<=>),不支持范围查询(WHERE price > 100)。因为:hash索引比较的是进行hash计算之后的hash值,hash值大小关系和原数据没有进行hash运算前的大小关系不能保证完全一致;B+树索引,底层是多路查询平衡树,节点是天然有序的,左节点小于父节点,右节点大于父节点。叶子节点形成有序链表,便于范围查询。
- hash索引无法被用来避免数据的排序操作。因为hash索引中存放的是经过hash计算之后的hash值,而hash值得大小关系和hash运算前得键值不一定完全一致,所以数据库无法利用索引的数据来避免任何排序运算;B+树索引的叶子节点形成有序链表,可用于排序。
- hash索引不能利用部分索引键查询,对于组合索引,hash索引在计算hash值得时候是组合索引键合并后一起算的hash值,而不是单独计算hash值
- hash索引在任何时候都不能避免表扫描。hash索引是将索引键通过hash运算之后,将hash运算结果得hash值和所对应的行指针信息存放在一个hash表中,由于不同索引键存在相同得hash值,所以即使满足某个hash键值得数据得记录条数,也无法从hash索引中直接完成查询,还是要通过访问表中得实际数据进行相应的比较,并得到相应得结果
- hash索引遇到大量hash值相等得情况后性能并不一定会比b树高,哈希冲突(不同索引列会用相同的哈希码),此时需要遍历索引中的行指针,逐行进行比较。
27.手撕代码:求字符串的最长回文子序列
28.Hive避免数据倾斜有哪些优化手段
29.Hive中分桶技术
30.操作系统中进程和线程的定义和区别
进程
线程
- 是程序运行的最小单元,是进程内执行的一个单元执行流
一个程序至少一个进程,一个进程至少一个线程;进程分配内存,线程分配栈
31.数据库锁机制
定义:锁是计算机协调多个进程或者线程并发访问某一资源的机制
从对数据操作的类型分
- 读锁(共享锁):针对同一份数据,多个读操作可以同时进行而不会互相影响
- 写锁(排他锁):当前写操作没有完成前,会阻断其他写锁和读锁
从对数据操作的粒度分
- 表锁(偏读)
- 行锁(偏写)
32.锁相关 sync,lock类
33.线程和多线程的问题