当前位置: 首页 > news >正文

某益网络面经总结

一、线程池相关

1.当主线程执行结束后,子线程还会继续执行下去吗?

取决于子线程的类型:

  • 用户线程:若子线程为用户线程,主线程结束后,用户线程会继续执行,直到全部用户线程执行完毕,JVM 才会退出。
  • 守护线程:若子线程是守护线程,主线程结束后,守护线程会随着 JVM 退出而结束执行。

2. 线程池核心参数

  • corePoolSize:核心线程数,线程池会一直保留这些线程。
  • maximumPoolSize:最大线程数,线程池允许创建的最大线程数量。
  • keepAliveTime:线程空闲时的存活时间。
  • unit:存活时间的时间单位。
  • workQueue:任务队列,用于存储待执行的任务。
  • threadFactory:线程工厂,用于创建线程。
  • handler:拒绝策略,当任务队列满且线程数达到最大时的处理方式。

3.线程池原理:

线程池启动后,当有任务提交:

  • 若核心线程未达corePoolSize,创建新线程执行任务。
  • 若核心线程已满,将任务放入workQueue等待。
  • 若任务队列已满,且线程数未达maximumPoolSize,创建新线程执行任务。
  • 若线程数达到maximumPoolSize,任务队列也满,执行handler拒绝策略。
  • 空闲线程超过keepAliveTime会被销毁,但核心线程默认不销毁。 

4. 拒绝策略

当线程池的线程数达到最大线程数时,需要执行拒绝策略。

  • AbortPolicy(默认):直接丢弃新提交的任务,并且抛出 RejectedExecutionException 异常来表明任务无法被处理。
  • CallerRunsPolicy:当触发拒绝策略时,将任务交还给调用线程,由调用线程来负责执行该任务。
  • DiscardPolicy:直接丢弃新任务,不会抛出任何异常。开发者可以基于此策略,自定义额外的处理逻辑。
  • DiscardOldestPolicy:丢弃任务队列中最早进入且尚未处理的任务,之后重新尝试执行新提交的任务。

5.线程池类型

类型池内线程类型池内线程数量处理特点应用场景
定长线程池(FixedThreadPool)核心线程固定核心线程空闲时不回收(除非关闭线程);所有线程活动时,新任务等待至有线程空闲;任务队列无大小限制(超出线程的任务在队列中等待)控制线程最大并发数
定时线程池(ScheduledThreadPool)核心 & 非核心线程核心固定,非核心无限制非核心线程空闲时立即回收执行定时 / 周期性任务
可缓存线程池(CachedThreadPool)非核心线程不固定(可无限大)优先复用闲置线程处理新任务;无线程可用时新建线程(任务立即执行,无需等待);空闲线程超 60s 回收(回收后几乎不占系统资源)执行数量多、耗时少的线程任务
单线程化线程池(SingleThreadExecutor)核心线程1 个保证任务按指定顺序在一个线程中执行(顺序执行任务);无需处理线程同步问题单线程场景(不适合并发,如可能引起 IO 阻塞或影响 UI 线程响应的操作,如数据库操作等)

6.线程池工作原理

二、HBase rowkey的设计原则(三大原则)

HBase 是三维有序存储的,通过 rowkey(行键),column key(column family 和 qualifier)和 TimeStamp(时间戳)这个三个维度可以对 HBase 中的数据进行快速定位。RowKey 是 HBase 中用来唯一标识一行数据的主键。以下是 HBase 的 RowKey 三大设计原则:

  • 唯一性原则:RowKey 在整个表中必须是唯一的,这是最基本的要求。因为 HBase 通过 RowKey 来定位和区分每一行数据,如果 RowKey 不唯一,就无法准确地获取到想要的数据,会导致数据的混淆和错误。例如,在一个存储用户信息的 HBase 表中,以用户 ID 作为 RowKey,每个用户的 ID 是唯一的,这样就能确保通过 RowKey 可以准确地查询到每个用户的相关信息。
  • 长度原则:RowKey 的长度应该尽可能短。因为 RowKey 会被频繁地读取和比较,过长的 RowKey 会占用更多的存储空间和网络带宽,影响查询性能。一般来说,RowKey 的长度最好控制在 10 到 100 字节之间。例如,如果存储的是一些时间序列数据,可以将时间戳转换为合适的短格式作为 RowKey 的一部分,而不是直接使用完整的长整型时间戳。
  • 散列原则:RowKey 的设计应该尽量保证数据在 HBase 表中均匀分布,避免数据热点问题。可以通过对 RowKey 进行散列处理,使得不同的 RowKey 能够均匀地分布在不同的 Region 上。例如,在设计 RowKey 时,可以在一些有规律的字段前加上随机的前缀,或者使用一些散列算法对原始的 Key 进行处理,让数据能够更均匀地存储在 HBase 集群中,提高系统的并发处理能力和整体性能。

三、HBase热点问题

  1. 热点定义:HBase 中行按 rowkey 字典序排序,糟糕的 rowkey 设计是热点源头。热点指大量 client 集中访问集群的一个或极少数节点,会致节点性能下降、region 不可用,还影响同 RegionServer 上其他 region。
  2. 避免热点方法及优缺点
    • 加盐:在 rowkey 前加随机数,依随机前缀分散到各 region 避热点,前缀数与分散 region 数一致。
    • 哈希:用确定哈希给同一行加固定前缀,可分散负载,且读可预测,客户端能重构 rowkey 精准获取数据。
    • 反转:反转固定长度或数字格式 rowkey,能随机 rowkey 但牺牲有序性,如手机号反转作 rowkey。
    • 时间戳反转:用 Long.Max_Value - timestamp 追加到 key 末尾,如 [key][reverse_timestamp],利于快速获取 [key] 最新值,scan [key] 的首条记录即最新录入数据。
  3. 其他建议:减少行键和列族大小,因 value 传输时 key、列名、时间戳会一同传输;列族越短越好,最好一个字符;短属性名比冗长属性名更适合存储在 HBase 中。

四、hashmap的底层原理,为什么hashtable可以保证线程安全

HashMap 的底层原理

  • 数据结构:HashMap 底层是基于数组和链表(或红黑树)实现的。数组的每个元素是一个链表的头节点,链表用于解决哈希冲突。当链表长度超过一定阈值(默认为 8)且数组大小大于等于 64 时,链表会转换为红黑树,以提高查找效率。
  • 哈希函数:通过对键对象的哈希码进行计算,得到在数组中的存储位置。通常使用 key.hashCode() 方法获取键的哈希码,然后对数组长度取模,得到数组索引。
  • 存储过程:当向 HashMap 中添加键值对时,先计算键的哈希值,根据哈希值确定在数组中的位置。如果该位置为空,则直接将键值对存储在该位置;如果该位置已有元素,说明发生了哈希冲突,会将新的键值对添加到链表的末尾(或根据红黑树的规则插入到红黑树中)。
  • 扩容机制:当 HashMap 中的元素数量达到负载因子(默认为 0.75)与数组长度的乘积时,会触发扩容操作。扩容会创建一个新的更大的数组,并将原数组中的元素重新哈希分配到新数组中。

Hashtable 保证线程安全的原因

  • 同步方法:Hashtable 中的几乎所有操作方法(如 putgetremove 等)都被 synchronized 关键字修饰,同一时刻仅一个线程可访问,其他线程需等待当前线程执行完并释放锁,从而保障线程安全。
  • 锁机制:Hashtable 利用对象锁对整体进行同步,所有操作均需获取该锁,确保任一时刻仅有一个线程能修改或访问,避免多线程下数据不一致 。

五、Hive内部表和外部表的区别

  • 未被external修饰的是内部表,被external修饰的为外部表。
  • 内部表数据由Hive自身管理,外部表数据由HDFS管理;
  • 内部表数据存储的位置是hive.metastore.warehouse.dir(默认:/user/hive/warehouse),外部表数据的存储位置由自己制定(如果没有LOCATION,Hive将在HDFS上的/user/hive/warehouse文件夹下以外部表的表名创建一个文件夹,并将属于这个表的数据存放在这里);
  • 删除内部表会直接删除元数据(metadata)及存储数据;删除外部表仅仅会删除元数据,HDFS上的文件并不会被删除

六、数据倾斜,怎么解决

在 Hive 处理千亿级数据时,数据倾斜问题需重点关注,其本质原因是大量相同 key 数据处理或读取不可分割大文件,常见于 reduce 阶段,map 阶段在特定情况下也会发生。以下是不同场景下的数据倾斜及解决方案:

  • 空值引发:大量 null 值参与 join 时,因 shuffle 阶段 hash 相同进入同一 reduce 导致倾斜。解决方法包括将 null 值过滤后再 union ,或给 null 值随机赋值,使其 hash 结果不同,分散到不同 reduce。
  • 不同数据类型:表连接字段类型不同,如 int 和 string 混合,默认按 int 型 hash 会使 string 类型集中到一个 reduce。可将 int 类型转为 string,统一 hash 分配规则。
  • 不可拆分大文件:使用 GZIP 等不支持分割的压缩方式,使大文件只能被一个 map 读取引发倾斜。应采用 bzip2、Zip 等支持分割的压缩算法。
  • 数据膨胀:多维聚合计算中分组字段多,数据膨胀易致内存溢出和数据倾斜。可拆分 SQL 语句,或通过参数hive.new.job.grouping.set.cardinality自动控制作业拆解,倾斜严重时调小该值。
  • 表连接:普通 repartition join 键倾斜会引发数据倾斜。可利用 MapJoin,将小表存到分布式缓存,在 Map 阶段完成 join,避免 Shuffle;Hive 0.11 后默认开启优化,可通过参数设置触发时机,必要时手动标记。
  • 无法减少数据量:如使用collect_list等函数且分组字段存在倾斜时,会导致内存溢出,hive.groupby.skewindata参数对此类场景无效。可直接调整mapreduce.reduce.memory.mb来增大 reduce 执行内存 。

七、算法手撕:有n级楼梯,你一次可以爬一级或两级,问爬上n级楼梯有多少种爬法?   

public class ClimbStairsRecursive {public static int climbStairs(int n) {if (n == 1) {return 1;}if (n == 2) {return 2;}return climbStairs(n - 1) + climbStairs(n - 2);}public static void main(String[] args) {int n = 5;System.out.println("爬上 " + n + " 级楼梯的方法数为: " + climbStairs(n));}
}
原文地址:https://blog.csdn.net/m0_62410190/article/details/147156028
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mrgr.cn/news/98294.html

相关文章:

  • leetcode-单调栈26
  • 深入剖析 Axios 的 POST 请求:何时使用 qs 处理数据
  • 抗干扰CAN总线通信技术在分布式电力系统中的应用
  • ASP.NET Core 性能优化:客户端响应缓存
  • golang-context详解
  • 3 VS Code 深度配置与优化指南:settings.json 详解、快捷键大全、实用插件推荐及离线安装方法
  • 3DGS之光栅化
  • mongodb 4.0+多文档事务的实现原理
  • 网络基础-路由技术和交换技术以及其各个协议
  • ubuntu 20.04 安装源码编译 ros humble过程
  • 深入详解MYSQL的MVCC机制
  • CAP理论 与 BASE理论
  • python——正则表达式
  • C++17模板编程与if constexpr深度解析
  • C# net CMS相关开源软件 技术选型 可行性分析
  • flutter 桌面应用之右键菜单
  • 【Python全栈】应用开发实战案例解析
  • 39.[前端开发-JavaScript高级]Day04-函数增强-argument-额外知识-对象增强
  • 【docker】--部署--安装docker教程
  • 【HD-RK3576-PI】Docker搭建与使用