字节大数据面试都在问什么?2026 高频题库 + 回答思路全整理

前言

最近很多通过来问我:“字节大数据面试到底考什么?”“Hadoop、Spark 源码要不要背?”“数据倾斜、Exactly Once 怎么答才加分?”

今天整理了 2026 字节大数据最新面试真题 + 标准答案,1.4W 字纯干货无废话!涵盖 Hadoop、Kafka、Hive、HBase、Spark、Flink、Java 基础、并发编程、算法 9 大模块

不管你是校招小白还是社招跳槽,收藏这篇,面试前突击 3 天,直接拿捏字节面试官!(建议转发给一起求职的朋友,组队上岸~)

核心技术篇(面试占比 60%)

一、Hadoop 篇(分布式存储与计算基石)

1.介绍一下Hadoop / hadoop是什么

Hadoop是一个由Apache基金会所开发的分布式系统基础架构,主要解决海量数据存储与计算的问题,主要包括HDFS、MapReduce和Yarn框架。

2.谷歌的三篇论文是否了解,三驾马车GFS、BigTable、MapReduce

  • GFS → HDFS(分布式文件系统)
  • MapReduce → Hadoop MapReduce(分布式计算框架)
  • BigTable → HBase(分布式列存储数据库)

3.hdfs源码你知道的话,讲讲元数据怎么管理的? 

Namenode对元数据的管理采用了三种形式:

  1. 内存元数据:基于内存存储元数据,元数据比较完整
  2. fsimage文件:磁盘元数据镜像文件,在NameNode工作目录中,它不包含block所在的Datanode 信息
  3. edits文件:数据操作日志文件,用于衔接内存元数据和fsimage之间的操作日志,可通过日志运算出元数据

4.你知道namenode的问题吗?怎么解决?应该就是联邦机制 

为了能够水平扩展Namenode,HDFS2.X提供了Federation架构。Federation架构的HDFS集群可以定义多个Namenode/Namespace,这些Namenode之间相互独立,各自分工管理自己的命名空间。HDFS集群中的Datanode提供数据块的共享存储功能,每个Datanode都会向集群中所有的Namenode注册,且周期性地向所有的Namenode发送心跳和块汇报,然后执行Namenode通过响应发回的Namenode指令。

5.hdfs写数据流程

  • 首先客户端会向namenode进行请求,然后namenode会检查该文件是否已经存在,如果不存在,就会允许客户端上传文件;
  • 客户端再次向namenode请求第一个block上传到哪几个datanode节点上,假设namenode返回了三个datanode节点;
  • 那么客户端就会向datanode1请求上传数据,然后datanode1会继续调用datanode2,datanode2会继续调用datanode3,那么这个通信管道就建立起来了,紧接着dn3,dn2,dn1逐级应答客户端;
  • 然后客户端就会向datanode1上传第一个block,以packet为单位(默认64k),datanode1收到后就会传给datanode2,dn2传给dn3
  • 当第一个block传输完成之后,客户端再次请求namenode上传第二个block。【写的时候,是串行的写入 数据块】

6.namenode如果挂掉了怎么办 【HA配置】

  • 当namenode发生故障宕机时,secondary namenode会保存所有的元数据信息,在namenode重启的时候,secondary namenode会将元数据信息发送给namenode。

7.说一下mapredeuce

  • map阶段:首先通过把输入目录下的文件进行逻辑切片,默认大小等于block大小,并且每一个切片由一个maptask来处理,同时将切片中的数据解析成<key,value>的键值对,k表示偏移量,v表示一行内容;紧接着调用Mapper类中的map方法。将每一行内容进行处理,解析为<k,v>的键值对,在wordCount案例中,k表示单词,v表示数字1 ;
  • shuffle阶段:map端shuffle:将map后的<k,v>写入环形缓冲区【默认100m】,一半写元数据信息(key的起始位置,value的起始位置,value的长度,partition号),一半写<k,v>数据,等到达80%的时候,就要进行spill溢写操作,溢写之前需要对key按照【分区算法默认是,分区号是根据key的hashcode对reduce task个数取模得到的。这时候有一个优化方法可选,combiner合并,就是预聚合的操作,将有相同Key 的Value 合并起来, 减少溢写到磁盘的数据量,只能用来累加、最大值使用,不能在求平均值的时候使用】;然后到文件中,并且进行(多个溢写文件);reduce端shuffle:reduce会同一分区的各个maptask的结果到内存中,如果放不下,就会溢写到磁盘上;然后对内存和磁盘上的数据进行(这样就可以满足将key相同的数据聚在一起);【Merge有3种形式,分别是内存到内存,内存到磁盘,磁盘到磁盘。默认情况下第一种形式不启用,第二种Merge方式一直在运行(spill阶段)直到结束,然后启用第三种磁盘到磁盘的Merge方式生成最终的文件。】
  • reduce阶段:key相同的数据会调用一次reduce方法,每次调用产生一个键值对,最后将这些键值对写入到HDFS文件中。

8.mapreduce哪个阶段最费时间,环形缓冲区的调优以及什么时候需要调

shuffle:排序和溢写磁盘  原则上说,缓冲区越大,磁盘 io 的次数越少,执行速度就越快

9.环形缓冲区了不了解?说一下它的那个阈值高低的影响

  • 环形缓冲区底层就是一个数组,默认大小是100M
  • 数组中存放着key和value的数据,以及关于key和value的元数据信息。每个key, value对应一个元数据,元数据由4个int组成,第一个int存放value的起始位置,第二个int存放key的起始位置,第三个int存放partition,第四个int存放value的长度。
  • key/value数据和元数据在环形缓冲区中的存储是由equator(赤道)分隔的,key/value按照索引递增的方向存储,元数据则按照索引递减的方向存储。将数组抽象为一个环形结构之后,以equator为界,key/value顺时针存储,元数据逆时针存储。

10.手写一个wordcount

public class WordcountMapper extends Mapper<LongWritable, Text, Text, IntWritable>{    Text k = new Text();    IntWritable v = new IntWritable(1);    @Override    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {        // 1 获取一行        String line = value.toString();        // 2 切割        String[] words = line.split(" ");        // 3 输出        for (String word : words) {            k.set(word);            context.write(k, v);        }    }}publicclass WordcountReducer extends Reducer<Text, IntWritable, Text, IntWritable>{    int sum;    IntWritable v = new IntWritable();    @Override    protected void reduce(Text key, Iterable<IntWritable> values,Context context) throws IOException, InterruptedException {        // 1 累加求和        sum = 0;        for (IntWritable count : values) {            sum += count.get();        }        // 2 输出           v.set(sum);        context.write(key,v);    }}

11.WordCount在MapReduce中键值对变化

<偏移量, 一行数据> => <单词1, 1> <单词2, 1> ....  => <单词1,10> <单词2,15>

12.map端为什么要排序? 

是为了通过外排(外部排序)降低内存的使用量:因为reduce阶段需要分组,将key相同的放在一起进行规约,使用了两种算法:hashmap和sort,如果在reduce阶段sort排序(内部排序),太消耗内存,而map阶段的输出是要溢写到磁盘的,在磁盘中外排可以对任意数据量分组(只要磁盘够大),所以,map端排序(shuffle阶段),是为了减轻reduce端排序的压力。

13.map端输出的文件组织形式是什么样的? 

多个溢写文件合并后的大文件

14.reduce怎么知道从哪里下载map输出的文件 

通过MRAPPMaster获取哪些节点有map输出,当map执行结束后,会汇报给MRAPPMaster。reduce中的一个线程会定期询问MRAPPMaster以便获取map输出的位置

15.如果map输出太多小文件怎么办 

开启combiner合并,但是在求平均值的时候是不能使用的

16.MapReduce优化的case

  • 输入端:合并小文件 combineinputformat
  • map端:提高环形缓冲区的大小,减少IO次数 开启combiner

二、Kafka 篇(高吞吐消息队列)

1.Kafka在项目中起到的作用,如果挂掉怎么保证数据不丢失,不使用Kafka会怎样

  • kafka提供了3种ack应答级别:ack=0,生产者发送过来的数据,不需要等数据落盘就会应答,一般不会使用;ack=1,生产者发送过来的数据,Leader收到数据后就会应答,因为这个级别也会丢失数据,所以一般用于传输普通日志;ack=-1(默认级别),生产者发送过来的数据,Leader和ISR队列里面的所有节点收到数据后才会应答,不会丢失数据,一般用于传输和钱相关的数据,那么为什么提出了这个ISR呢?因为如果我们等待所有的follower都同步完成,才发送ack,假设有一个follower迟迟不能同步,那怎么办呢?难道要一直等吗?因此就出现了ISR队列,这里面会存放和leader保持同步的follower集合,如果长时间(30s)未和leader通信或者同步数据,就会被踢出去。

2.Kafka怎么保证数据一致性

  • 分别从如何保证数据不丢失以及数据不重复两个方面来回答:
  • 数据不丢失:......
  • 数据不重复:0.11版本之后,kafka提出了一个非常重要的特性,幂等性(默认是开启的),也就是说无论producer发送多少次重复的数据,kafka只会持久化一条数据,把这个特性和至少一次语义(ack级别设置为-1+副本数>=2+ISR最小副本数>=2)结合在一起,就可以实现精确一次性(既不丢失又不重复)。我大致介绍一下它的底层原理:在producer刚启动的时候会分配一个PID,然后发送到同一个分区的消息都会携带一个SequenceNum(单调自增的),broker会对<PID,partition,SeqNum>做缓存,也就是把它当做主键,如果有相同主键的消息提交时,broker只会持久化一条数据。但是这个机制只能保证单会话的精准一次性,如果想要保证跨会话的精准一次性,那么就需要事务的机制来进行保证(producer在使用事务功能之前,必须先自定义一个唯一的事务id,这样,即使客户端重启,也能继续处理未完成的事务;并且这个事务的信息会持久化到一个特殊的主题当中)

3.Kafka通过哪些机制实现了高吞吐量?

  • kafka本身是分布式集群,并且采用分区技术,并行度高
  • 读数据采用稀疏索引,可以快速定位要消费的数据
  • 写log文件的时候,一直是追加到文件末端,是顺序写的方式,官网中说了,同样的磁盘,顺序写能达到600M/s,而随机写只有100K/s
  • 实现了零拷贝技术,只用将磁盘文件的数据复制到页面缓冲区一次,然后将数据从页面缓冲区直接发送到网络中,这样就避免了在内核空间和用户空间之间的拷贝

三、Hive 篇(数据仓库工具)

1.如何理解Hive,为什么使用Hive

  • hive就是一款构建数据仓库的工具,它可以将结构化的数据映射为一张表,并且可以通过SQL语句进行查询分析。本质上是将SQL转换为MapReduce或者spark来进行计算,数据是存储在hdfs上,简单理解来说hive就是MapReduce的一个客户端工具。

2.Hive的实现逻辑,为什么处理小表延迟比较高

  • 因为其计算是通过MapReduce,MapReduce是批处理,高延迟的。小文件也要执行MapReduce。Hive的优势在于处理大数据,对于处理小数据没有优势

四、HBase 篇(分布式列存储)

1.Hbase的架构

  • HBase主要包括region server和master,region server主要用于region的管理,而master主要用于管理region server,另外还有zookeeper和hdfs,zookeeper主要是用来保证master的高可用,hdfs提供存储服务。

2.Hbase的读写流程

  • 写流程:
  • 读流程:

3.blockcache的底层实现?你提到了LRU,那除了LRU还可以有什么方案?

  • 三种实现方案:

4.Hbase有哪几种写入方式,应用场景

  • 单条put:线上业务
  • 批量put:数据量较大
  • 使用Mapreduce:数据量非常大
  • bluckload:速度快

五、Spark 篇(快速分布式计算)

1.Spark有哪几种部署模式

  • 本地模式:常用于本地开发程序与测试
  • 集群模式:

2.spark on yarn的工作流程

  • 首先spark的客户端将作业提交给yarn的RM,然后RM会分配container,并且选择合适的NM启动ApplicationMaster,然后AM启动Driver,紧接着向RM申请资源启动executor,Executor 进程启动后会向 Driver 反向注册,全部注册完成后 Driver 开始执行main 函数,当执行到行动算子,触发一个 Job,并根据宽依赖开始划分 stage(阶段的划分),每个 stage 生成对应的 TaskSet(任务的切分),之后将 task 分发到各个 Executor 上执行。

3.怎样提高并行度,相关参数是什么

  • spark.defalut.parallelism

4.client和cluster模式的区别

  • client模式下,driver运行在客户端;
  • cluster模式下,driver运行在yarn集群

5.Spark shuffle的过程

  • spark的shuffle分为两种实现,分别为HashShuffle(spark1.2以前)和SortShuffle(spark1.2以后)
  • HashShuffle分为普通机制和合并机制,分为write阶段和read阶段,write阶段就是根据key进行分区,开始先将数据写入对应的buffer中,当buffer满了之后就会溢写到磁盘上,这个时候会产生mapper的数量reduer的数量的小文件,这样就会产生大量的磁盘IO,read阶段就是 reduce去拉取各个maptask产生的同一个分区的数据;HashShuffle的合并机制就是让多个mapper共享buffer,这时候落盘的数量等于reducer的数量core的个数,从而可以减少落盘的小文件数量,但是当Reducer有很多的时候,依然会产生大量的磁盘小文件。
  • SortShuffle分为普通机制和bypass机制

6.讲讲Spark为什么比Hadoop快

  • MapReduce需要将计算的中间结果写入磁盘,然后还要读取磁盘,从而导致了;而Spark不需要将计算的中间结果写入磁盘,这得益于Spark的RDD弹性分布式数据集和DAG有向无环图,中间结果能够以RDD的形式存放在内存中,这样大大减少了磁盘IO。(假设有多个转换操作,那么spark是不需要将第一个job的结果写入磁盘,然后再读入磁盘进行第二个job的,它是直接将结果缓存在内存中)
  • MapReduce在shuffle时需要花费大量时间排序,而spark在shuffle时如果选择基于hash的计算引擎,是不需要排序的,这样就会节省大量时间。
  • MapReduce是多进程模型,每个task会运行在一个独立的JVM进程中,每次启动都需要重新申请资源,消耗了大量的时间;而Spark是多线程模型,每个executor会单独运行在一个JVM进程中,每个task则是运行在executor中的一个线程。

7.RDD是什么,有什么特点

  • 它翻译过来就叫做,是一种数据结构,可以理解成是一个集合。在代码中的话,RDD是一个抽象类。还有一个非常重要的特点:RDD是不保存数据的,仅仅封装了计算逻辑,也就是你直接打印RDD是看不见具体值的。

8.RDD的血缘

  • 多个连续的RDD的依赖关系,称之为血缘关系;每个RDD会保存血缘关系

9.宽窄依赖

  • 宽依赖:父的RDD的一个分区的数据会被子RDD的多个分区依赖,涉及到Shuffle
  • 窄依赖:父的RDD的一个分区的数据只会被子RDD的一个分区依赖

10.stage划分

  • 对于窄依赖,不会进行划分,也就是将这些转换操作尽量放在在同一个 stage中,可以实现流水线并行计算。对于宽依赖,由于有 shuffle 的存在,只能在父 RDD 处理完成后,才能开始接下来的计算,也就是说需要要划分 stage(从后往前,遇到宽依赖就切割stage)

11.Transform和Action算子分别列举一些常用的,他们的区别是什么

  • 转换算子主要是将旧的RDD包装成新的RDD,行动算子就是触发任务的调度和作业的执行。
  • 转换算子:map flatMap filter reducebykey union
  • 行动算子:collect foreach take

12.Spark 能产生shuffle的算子

  • reduceByKey、sortByKey
  • repartition、coalesce
  • join、cogroup

13.Spark里的reduce by key和group by key两个算子在实现上的区别并且说一下性能

  • groupByKey只能分组,不能聚合,而reduceByKey包含分组和聚合两个功能
  • reduceByKey会在shuffle前对分区内相同key的数据进行预聚合(类似于MapReduce的combiner),减少落盘的数据量,而groupByKey只是shuffle,不会进行预聚合的操作,因此reduceByKey的会高一些

14.Spark内存管理

  • spark分为堆内内存和堆外内存,堆内内存由JVM统一管理,而堆外内存直接向操作系统进行内存的申请,不受JVM控制 spark.executor.memory和spark.memory.offHeap.size
  • 堆内内存又分为存储内存和执行内存和其他内存和预留内存,存储内存主要存放缓存数据和广播变量,执行内存主要存放shuffle过程的数据,其他内存主要存放rdd的元数据信息,预留内存和其他内存作用相同。

15.有没有看过Spark底层源码

  • 看过,比如spark shuffle源码,...

16.Spark 数据倾斜

  • 见之前的文章 / 大数据开发面试笔记V7.0

17.用Spark遇到了哪些问题

  • 聚合函数导致内存溢出
  • 广播join导致内存溢出
  • 数据倾斜

18.Spark join的有几种实现 *

  • 包括 broadcast hash join,shuffle hash join,sort merge join,前两种都是基于hash join;broadcast 适合一张很小的表和一张大表进行join,shuffle适合一张较大的小表和一张大表进行join,sort适合两张较大的表进行join。
  • 先说一下hash join吧,这个算法主要分为三步,首先确定哪张表是build table和哪张表是probe table,这个是由spark决定的,通常情况下,小表会作为build table,大表会作为probe table;然后构建hash table,遍历build table中的数据,对于每一条数据,根据join的字段进行hash,存放到hashtable中;最后遍历probe table中的数据,使用同样的hash函数,在hashtable中寻找join字段相同的数据,如果匹配成功就join到一起。这就是hash join的过程
  • broadcast hash join分为broadcast阶段和hash join阶段,broadcast阶段就是 将小表广播到所有的executor上,hash join阶段就是在每个executor上执行hash join,小表构建为hash table,大表作为probe table
  • shuffle hash join分为shuffle阶段和hash join阶段,shuffle阶段就是 对两张表分别按照join字段进行重分区,让相同key的数据进入同一个分区中;hash join阶段就是 对每个分区中的数据执行hash join
  • sort merge join分为shuffle阶段,sort阶段和merge阶段,shuffle阶段就是 将两张表按照join字段进行重分区,让相同key的数据进入同一个分区中;sort阶段就是 对每个分区内的数据进行排序;merge阶段就是 对排好序的分区表进行join,分别遍历两张表,key相同就join输出,如果不同,左边小,就继续遍历左边的表,反之,遍历右边的表

19.背压机制应用场景 底层实现

  • 背压机制就是根据JobScheduler 反馈作业的执行信息来动态调整receiver的数据接收率

20.spark RDD持久化

  • 因为RDD实际上是不存储数据的,那么如果RDD要想重用,那么就需要重头开始再执行一遍,所以为了提高RDD的重用性,就有了RDD持久化
  • 分类:缓存和检查点

六、Flink 篇(流批一体实时计算)

1.Flink的组成

  • jobmanager:相当于一个集群的Master,是整个集群的协调者,负责接收job
  • taskmanager:实际负责的Worker
  • client:flink程序提交的客户端,当用户提交一个Flink程序时,会首先创建一个Client

2.Flink流批一体解释一下

  • Flink 使用一个引擎就支持了DataSet API 和 DataStream API。其中DataSet API用来处理有界流,DataStream API既可以处理有界流又可以处理无界流,这样就实现了流批一体

3.Flink和SparkStreaming区别

  • 第一,计算速度的不同,flink是真正的实时计算框架,而sparkstreaming是一个准实时微批次的计算框架,也就是说,sparkstreaming的实时性比起flink,差了一大截。
  • 第二,架构模型的不同,Spark Streaming 在运行时的主要角色包括:Driver、Executor,而Flink 在运行时主要包含:Jobmanager、Taskmanager。
  • 第三,时间机制的不用,Spark Streaming 只支持处理时间,而Flink支持的时间语义包括处理时间、事件时间、注入时间,并且还提供了watermark机制来处理迟到数据。

4.那Flink shuffle呢?你了解吗?

  • 其实就是redistribute,一对多

5.watermark用过吗

  • 它就是一种特殊的时间戳,作用就是为了让事件时间慢一点,等迟到的数据都到了,才触发窗口计算
  • 当watermark等于窗口时间的时候,就会触发计算

6.checkpoint Chandy-Lamport算法

  • flink应用在启动的时候,flink的JobManager创建CheckpointCoordinator
  • CheckpointCoordinator(检查点协调器) 周期性的向该流应用的所有source算子发送 barrier(屏障)。
  • 当某个source算子收到一个barrier时,便暂停数据处理过程,然后将自己的当前状态制作成快照,并保存到指定的持久化存储(hdfs)中,最后向CheckpointCoordinator报告自己快照制作情况,同时向自身所有下游算子广播该barrier,恢复数据处理
  • 下游算子收到barrier之后,会暂停自己的数据处理过程,然后将自身的相关状态制作成快照,并保存到指定的持久化存储中,最后向CheckpointCoordinator报告自身快照情况,同时向自身所有下游算子广播该barrier,恢复数据处理。
  • 每个算子按照 上面这个操作 不断制作快照并向下游广播,直到最后barrier传递到sink算子,快照制作完成。
  • 当CheckpointCoordinator收到所有算子的报告之后,认为该周期的快照制作成功; 否则,如果在规定的时间内没有收到所有算子的报告,则认为本周期快照制作失败。

7.如何用checkpoint和watermark防止读到乱序数据

  • watermark设置延迟时间
  • checkpoint进行持久化

8.Kafka和Flink分别怎么实现exactly once,问的比较深入,我只回答了一些用法,二阶段提交说了流程,没说出来机制。

  • kafka:ack=-1+幂等性
  • flink利用checkpoint检查点保证精准一次性【超级重点,checkpoint的细节需要知道】

Java 基础 + 并发编程篇(面试占比 30%)

一、Java 基础

1.java限定词(private那些)

  • public > protected > default > private

2.ArrayList原理,为什么初始是10,为什么扩容1.5倍

  • ArrayList是基于动态数组的数据结构;
  • 因为对于1.2倍来说,它的扩容空间很小,很容易就会被装满,就需要不停的去扩容,而对于2倍来说,它的扩容空间很大,反而很难被装满,就很难被扩容。所以最终选择了1.5倍最为扩容的倍数。

3.hashmap的实现原理

  • 在jdk1.8之前,hashmap由 数组-链表数据结构组成,在jdk1.8之后hashmap由 数组-链表-红黑树数据结构组成;当我们创建hashmap对象的时候,jdk1.8以前会创建一个长度为16的Entry数组,jdk1.8以后就不是初始化对象的时候创建数组了,而是在第一次put元素的时候,创建一个长度为16的Node数组;
  • 当我们向对象中插入数据的时候,首先调用hashcode方法计算出key的hash值,然后对数组长度取余((n-1)&hash(key)等价于hash值对数组取余)计算出向Node数组中存储数据的索引值;
  • 如果计算出的索引位置处没有数据,则直接将数据存储到数组中;
  • 如果计算出的索引位置处已经有数据了,此时会比较两个key的hash值是否相同,如果不相同,那么在此位置划出一个节点来存储该数据(拉链法);如果相同,此时发生hash碰撞,那么底层就会调用equals方法比较两个key的内容是否相同,如果相同,就将后添加的数据的value覆盖之前的value;如果不相同,就继续向下和其他数据的key进行比较,如果都不相等,就划出一个节点存储数据;如果链表长度大于阈值8(链表长度符合泊松分布,而长度为8个命中概率很小),并且数组长度大于64,则将链表变为红黑树,并且当长度小于等于6(不选择7是防止频繁的发生转换)的时候将红黑树退化为链表。

4.实现单例模式

  • 饿汉式(静态常量):在类中定义一个静态常量,然后在静态方法中返回这个常量对象
  • 饿汉式(静态代码块):将new对象放到了一个静态代码块里面,其他都是一样的
  • 懒汉式(线程不安全):直接在静态方法中进行对象的创建的判断 if(instance==null) new
  • 懒汉式(线程安全,同步方法):直接在静态方法之上加上了synchronized,来保证线程安全
  • 懒汉式(线程安全,同步代码块):直接在创建对象上加了同步代码块,并不能保证线程安全
  • 双重检查:通过两次判断instance对象是否为空,并且在第二次判断之前加了同步代码块
  • 静态内部类:写一个静态内部类,该类中有一个静态属性用来new对象
  • 枚举:写一个枚举,instance作为一个枚举值

5.多路复用,NIO这些了解过吗?

  • BIO是同步阻塞的IO模型,NIO是同步非阻塞的IO模型,IO多路复用是异步阻塞的IO模型,AIO是异步非阻塞的IO模型

6.100M的数组 随机查快还是顺序查快 解释为什么?

  • CPU内部的数据预取机制,会假设短时间内的读取最可能就会发生在下一个(或后边离得不远)的地址上。顺序读取最有利于命中CPU的一二三级缓存。

二、并发编程

1.如何实现多线程,写过多线程吗

class RunnableDemo implements Runnable {        private String threadName;        public RunnableDemo(String name) {                threadName = name;        }        @Override        public void run() {                System.out.println(threadName);        }}publicclass Main {        public static void main(String[] args) {                RunnableDemo thread01 = new RunnableDemo("thread01");                new Thread(thread01).start();                RunnableDemo thread02 = new RunnableDemo("thread02");                new Thread(thread02).start();                RunnableDemo thread03 = new RunnableDemo("thread03");                new Thread(thread03).start();        }}

2.4种线程池功能

  • 通过ThreadPoolExecutor构造函数实现(推荐)
  • CachedThreadPool:返回一个可根据实际情况调整线程数量的线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程
  • FixedThreadPool:返回一个固定线程数量的线程池,可控制线程最大并发数,超过的线程会在队列中等待
  • SingleThreadExecutor:返回一个只有一个线程的线程池,它只会用唯一的线程来执行任务,保证所有任务按照执行顺序执行。

3.java内存模型

  • java内存模型是一套规范,描述了java程序中各种变量(线程共享变量)的访问规则,其规定所有的共享变量都存储在主内存中,每一个线程都有自己的工作内存,工作内存中只存储该线程对共享变量的副本,线程对变量的所有操作都必须在工作内存中完成,而不能直接读写主内存的变量。

4.volatile的作用

  • 保证可见性:如果变量被 volatile 修饰,那么每次修改之后,接下来在读取这个变量的时候一定能读取到该变量最新的值
  • 保证有序性:因为编译器或 CPU会对代码的执行顺序进行优化,导致代码的实际执行顺序可能与我们编写的顺序是不同的,在多线程的场景下就会出现问题,利用volatile可以禁止这种重排序的发生

5.synchronized和volatile的区别

  • volatile只能修饰变量,synchronized可以用来代码块或者方法
  • volatile不能保证数据的原子性,synchronized可以保证原子性
  • volatile不会造成线程的阻塞,synchronized会造成线程的阻塞
  • volatile主要用于解决变量在多个线程之间的可见性,synchronized主要用于解决多个线程之间访问资源的同步性

6.公平锁与非公平锁的区别

  • 公平锁:每个线程获取锁的顺序是按照线程访问锁的先后顺序获取的,最前面的线程总是最先获取到锁。
  • 非公平锁:每个线程获取锁的顺序是随机的,并不会遵循先来先得的规则,所有线程会竞争获取锁。

7.lock是公平的还是非公平的

  • 可以根据逻辑自己实现是否公平

8.sychornized怎么优化

  • 减少synchronized的范围:同步代码块中尽量短
  • 降低synchronized锁的粒度:将一个锁拆分为多个锁提高并行度 (HashTable -> ConcurrentHashMap)
  • 读写分离:读取时不加锁,写入和删除时加锁 (ConcurrentHashMap)

9.volatile可以保证原子性吗?

  • 不能

10.reentrantlock底层原理

  • ReentrantLock先通过CAS尝试获取锁,如果获取了就将锁状态state设置为1(state=0表示无锁),但是如果锁已经被占用,先判断当前的锁是否是自己占用了,如果是的话就将锁计数器会state++(可重入性),如果是被其他线程占用,那么将该线程加入AQS队列并wait()

11.synchronize底层实现

  • synchronized的锁对象会关联一个monitor(监视器,它才是真正的锁对象),这个monitor不是我们主动创建的,是JVM的线程执行到这个同步代码块,发现锁对象没有monitor就会创建monitor,monitor内部有两个重要的成员变量owner:拥有这把锁的线程,recursions:记录线程拥有锁的次数,当一个线程拥有monitor后,其他线程只能等待。当执行到monitorexit时,recursions会减1,当计数器为0时,这个线程会释放锁

算法篇(面试占比 10%,字节必考)

以下题目均为字节高频算法题,建议手写实现!

  1. 数组 / 矩阵类:岛屿问题、矩阵最小路径和、搜索旋转排序数组
  2. 二叉树类:镜像对称判断、二叉排序树判定、Z 字形遍历、非递归中序遍历、第 k 个节点查找;
  3. 链表类:k 个一组反转、重排链表、链表归并排序;
  4. 动态规划:最长回文子串、股票交易(1/2);
  5. 数据结构设计:LRU 缓存、O (1) min 函数的栈、哈希表设计;
  6. 其他:二分查找、堆排序、桶排序、String 转 int。
#你觉得哪一届的校招最难?##数据人offer决赛圈怎么选##数据人的面试交流地#
大数据开发面试笔记 文章被收录于专栏

包括大数据篇、计算机语言篇、计算机基础篇、算法刷题篇、面试经验篇等五大篇章: 大数据篇包括框架原理、源码解析、调优技巧、大数据场景题、项目实战、数仓理论等模块;计算机语言篇包括Java、Linux、大厂常考SQL面试题等模块;计算机基础篇包括计算机网络、操作系统、数据库、数据结构等模块;算法刷题篇包括大厂高频算法题、刷题速成计划等模块 面试经验篇包括BAT、美团、字节、快手、京东等大厂的面经合集

全部评论

相关推荐

评论
点赞
1
分享

创作者周榜

更多
正在热议
更多
# 春招至今,你的战绩如何? #
11764次浏览 102人参与
# 你的实习产出是真实的还是包装的? #
2051次浏览 43人参与
# 巨人网络春招 #
11396次浏览 223人参与
# 军工所铁饭碗 vs 互联网高薪资,你会选谁 #
7718次浏览 43人参与
# 简历第一个项目做什么 #
31813次浏览 344人参与
# 重来一次,我还会选择这个专业吗 #
433645次浏览 3926人参与
# 米连集团26产品管培生项目 #
6184次浏览 216人参与
# 当下环境,你会继续卷互联网,还是看其他行业机会 #
187289次浏览 1122人参与
# 牛客AI文生图 #
21463次浏览 238人参与
# 不考虑薪资和职业,你最想做什么工作呢? #
152540次浏览 888人参与
# 研究所笔面经互助 #
118986次浏览 577人参与
# 简历中的项目经历要怎么写? #
310519次浏览 4227人参与
# AI时代,哪些岗位最容易被淘汰 #
64049次浏览 837人参与
# 面试紧张时你会有什么表现? #
30528次浏览 188人参与
# 你今年的平均薪资是多少? #
213232次浏览 1039人参与
# 你怎么看待AI面试 #
180298次浏览 1266人参与
# 高学历就一定能找到好工作吗? #
64348次浏览 620人参与
# 你最满意的offer薪资是哪家公司? #
76633次浏览 374人参与
# 我的求职精神状态 #
448229次浏览 3129人参与
# 正在春招的你,也参与了去年秋招吗? #
363673次浏览 2638人参与
# 腾讯音乐求职进展汇总 #
160718次浏览 1112人参与
# 校招笔试 #
471566次浏览 2964人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务