面试题(二)

目录

一.集合

(1) LinkedHashMap(JDK 1.8)

(2) ArrayList

(3) HashMap

(4) ConcurrentHashMap

二. IO流

(1) 分类

(2) 应用

三.多线程

(1) 线程状态

(2) 死锁

(3) 应用

(4) 要点

(5) 线程池

返回

ThreadPoolExecutor 类分析

线程池原理分析

四. 数据库

(1) Mysql

1.MyISAM和InnoDB区别

2. 锁与事务

3. 高级

(2) Redis

1. redis 的线程模型

2. redis 内存淘汰机制

3. redis 持久化机制

4. 缓存雪崩和缓存穿透问题解决⽅案


一.集合

(1) LinkedHashMap(JDK 1.8)

鸿蒙OS LinkedHashMap

分析 java.util.LinkedHashMap  

LinkedHashMap 源码详细分析(JDK1.8)

Set集合元素不重复原因

集合不包含e1.equals(e2)的元素对e1和e2 ,并且最多包含一个空元素; 

更正式地说,如果集合不包含元素e2 ,则将指定的元素e添加到该集合中,使得(e==null ? e2==null : e.equals(e2)) 。如果此集合已包含该元素,则调用将保持集合不变并返回false 。结合对构造函数的限制,这确保了集合永远不会包含重复的元素。 

(2) ArrayList

ArrayList扩容机制的简单总结

https://www.cnblogs.com/ruoli-0/p/13714389.html (重点)

ArrayList的特点:

  1.ArrayList的底层数据结构是数组,所以查找遍历快,增删慢。

  2.ArrayList可随着元素的增长而自动扩容,正常扩容的话,每次扩容到原来的1.5倍。

  3.ArrayList的线程是不安全的。

ArrayList的扩容:

  扩容可分为两种情况:

  第一种情况,当ArrayList的容量为0时,此时添加元素的话,需要扩容,三种构造方法创建的ArrayList在扩容时略有不同:

    1.无参构造,创建ArrayList后容量为0,添加第一个元素后,容量变为10,此后若需要扩容,则正常扩容。

    2.传容量构造,当参数为0时,创建ArrayList后容量为0,添加第一个元素后,容量为1,此时ArrayList是满的,下次添加元素时需正常扩容。

    3.传列表构造,当列表为空时,创建ArrayList后容量为0,添加第一个元素后,容量为1,此时ArrayList是满的,下次添加元素时需正常扩容。

  第二种情况,当ArrayList的容量大于0,并且ArrayList是满的时,此时添加元素的话,进行正常扩容,每次扩容到原来的1.5倍。

(3) HashMap

Java 8系列之重新认识HashMap

HashMap集合技术点

Java HashMap的死循环 

(4) ConcurrentHashMap

ConcurrentHashMap实现原理及源码分析

JDK1.8 Node 数组+链表+红⿊树的数据结构来实现 synchronized 和 CAS 来操作

二. IO流

(1) 分类

 Java IO(面试题)

(2) 应用

@Overridepublic String importExcel(MultipartFile file) {try {String content = new String(file.getBytes(), "gb2312");//获取表头字段String csvheader = content.split("\r")[0];InputStreamReader reader = getDestContent(content);List<SppiImportEntity> entitylist = CsvUtil.getImportData(reader,SppiImportEntity.class);//临时表导入数据校验checkImportTmpData(entitylist, csvHeader);//2.导数据到临时表mktCbSppiMapper.insertTempList(entityList, 40000);//3.插入正式表//将临时表数据插入到正式表mkt_cb_sppi//导入用户String importUser = SessionUserHolder.getsessionUser().setusercode();String now = LocalDateTime.now().format(DeteTimeFormatter.ofPattern("yyyy-M-dd HH:mm:ss"));mktcbSppiMapper.insertSppiList(fileTp, importuser, now);} catch (Exception e) {e.getMessage();}}Pattern pattern = Pattern.compile("(\\d)(,)(\\d)");/*** 获取处理后目标字符串的输入流* @return 处理后字符申的输入流* @throws IOException* @param  content 要处理的字符串*/private InputStreamReader getDestContent(String content) throws IOException {StringBuilder destString = new StringBuilder();Arrays.asList(content.split("\n")).stream().forEach(s -> {StringBuilder stringBuilder = new StringBuilder(s);Matcher matcher = pattern.matcher(s);//该行字符串英文逗号已被替换掉的次数int count = 0;while (matcher.find()) {//去除英文逗号stringBuilder.replace(matcher.start(2) - count, matcher.end(2) - count, "");count++;}destString.append(stringBuilder.toString() + "\n");});byte[] bytes = destString.toString().getBytes("gb2312");InputStream inputstream = new ByteArrayInputStream(bytes);InputStreamReader inputStreamReader = new InputStreamReader(inputstream, "gb2312");return inputStreamReader;}

三.多线程

(1) 线程状态

(2) 死锁

(3) 应用

java.util.concurrent.Callable;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.kafka.core.KafkaTemplate;import java.util.List;
import java.util.concurrent.Callable;@Slf4j
public class InfoPublisherThread implements Callable<List<InfoPublisherRepVO>> {private KafkaTemplate<String, String> kafkaTemplate;private InfoPublisherApiMapper mapper;private int page;//分页indexprivate int size;//数量public InfoPublisherThread(KafkaTemplate<String, String> kafkaTemplate, InfoPublisherApiMapper mapper, int page, int size) {this.kafkaTemplate = kafkaTemplate;this.mapper = mapper;this.page = page;this.size = size;}@Overridepublic List<InfoPublisherRepVO> call(){log.info("单次5w条推送任务开始执行");long start = System.currentTimeMillis();List<InfoPublisherRepVO> list = mapper.pageList(page, size);list.forEach(repVO -> {kafkaTemplate.send(TopicConstant.INFO_PUBLISHER_TOPIC, JSON.toJSONString(repVO));});long end = System.currentTimeMillis();log.info("单次5w条推送任务耗时:{}",(end-start)/1000);return list;}}

java.util.concurrent.ThreadPoolExecutor
java.util.concurrent.LinkedBlockingQueue
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;public void batchDeal(List<InfoSecurityCustomType> models, int groupSize, BaseEntityEnum baseEntityEnum) {List<List<InfoSecurityCustomType>> groupList = ArrayUtils.splitGroup(models, groupSize);// 创建线程数 = 数据总数 / groupListint threadPoolSize = groupList.size();// 最多创建 4 个线程threadPoolSize = threadPoolSize >= 4 ? 4 : threadPoolSize;ThreadPoolExecutor executor = new ThreadPoolExecutor(threadPoolSize, threadPoolSize * 10, 30, TimeUnit.SECONDS, new LinkedBlockingQueue<>());try {for (int i = 0, length = groupList.size(); i < length; i++) {List<InfoSecurityCustomType> list = groupList.get(i);switch (baseEntityEnum) {case ADD:InfoSecurityCustomTypeBatchSaveThread saveThread = new InfoSecurityCustomTypeBatchSaveThread(list, mapper,kafkaTemplate);executor.execute(saveThread);break;case UPDATE:InfoSecurityCustomTypeBatchUpdateThread updateThread = new InfoSecurityCustomTypeBatchUpdateThread(list, mapper);executor.execute(updateThread);break;case DELETE:break;}}} catch (Exception e) {e.printStackTrace();throw new RuntimeException();} finally {executor.shutdown();}}

(4) 要点

1. 为了保证线程中的局部变量不被别的线程访问到,虚拟机栈和本地⽅法栈是线程私有的

2. 并发: 同⼀时间段,多个任务都在执⾏ (单位时间内不⼀定同时执⾏)

    并⾏: 单位时间内,多个任务同时执⾏。
3. 多线程问题:  内存泄漏、上下⽂切换、死锁还有受限于硬件和软件的资源闲置问题
4.  当前任务在执⾏完 CPU 时间⽚切换到另⼀个任务之前会先保存⾃⼰的状态,以便下次
再切换回这个任务时,可以再加载这个任务的状态。 任务从保存到再加载的过程就是⼀次上下⽂切换
5.  调⽤ start ⽅法⽅可启动线程并使线程进⼊就绪状态,⽽ run ⽅法只是 thread 的⼀个普通
⽅法调⽤,还是在主线程⾥执⾏。
6.  sleep() ⽅法和 wait() ⽅法区别和共同点
  • 两者最主要的区别在于:sleep ⽅法没有释放锁,⽽ wait ⽅法释放了锁
  • 两者都可以暂停线程的执⾏。
  • Wait 通常被⽤于线程间交互/通信,sleep 通常被⽤于暂停执⾏。
  • wait() ⽅法被调⽤后,线程不会⾃动苏醒,需要别的线程调⽤同⼀个对象上的 notify() 或者
  • notifyAll() ⽅法。sleep() ⽅法执⾏完成后,线程会⾃动苏醒。或者可以使⽤ wait(long
  • timeout)超时后线程会⾃动苏醒

(5) 线程池

返回

  • Runnable 接⼝不会返回结果或抛出检查异常,但是 Callable 接⼝可以。
  • execute() ⽅法⽤于提交不需要返回值的任务,所以⽆法判断任务是否被线程池执⾏成功与否;
  • submit() ⽅法⽤于提交需要返回值的任务。线程池会返回⼀个 Future 类型的对象,通过这Future 对象可以判断任务是否执⾏成功,并且可以通过 Future的 get() ⽅法来获取 返回值,get() ⽅法会阻塞当前线程直到任务完成,⽽使⽤ getlong timeout, TimeUnit unit) ⽅法则会阻塞当前线程⼀段时间后⽴即返回,这时候有可能任务没有执⾏完。

ThreadPoolExecutor 类分析

 /*** ⽤给定的初始参数创建⼀个新的ThreadPoolExecutor。*/public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler) {if (corePoolSize < 0 ||maximumPoolSize äã 0 ||maximumPoolSize < corePoolSize ||keepAliveTime < 0)throw new IllegalArgumentException();if (workQueue WX null || threadFactory WX null || handler WX
null)throw new NullPointerException();this.corePoolSize = corePoolSize;this.maximumPoolSize = maximumPoolSize;this.workQueue = workQueue;this.keepAliveTime = unit.toNanos(keepAliveTime);this.threadFactory = threadFactory;this.handler = handler;}

ThreadPoolExecutor 构造函数重要参数分析
ThreadPoolExecutor 3 个最重要的参数:
corePoolSize : 核⼼线程数线程数定义了最⼩可以同时运⾏的线程数量。
maximumPoolSize : 当队列中存放的任务达到队列容量的时候,当前可以同时运⾏的线程数 量变为最⼤线程数。
workQueue : 当新任务来的时候会先判断当前运⾏的线程数量是否达到核⼼线程数,如果达到 的话,新任务就会被存放在队列中。
ThreadPoolExecutor 其他常⻅参数 :
1. keepAliveTime : 当线程池中的线程数量⼤于 corePoolSize 的时候,如果这时没有新的任
务提交,核⼼线程外的线程不会⽴即销毁,⽽是会等待,直到等待的时间超过了
keepAliveTime 才会被回收销毁;
2. unit : keepAliveTime 参数的时间单位。
3. threadFactory :executor 创建新线程的时候会⽤到。
4. handler : 饱和策略。关于饱和策略下⾯单独介绍⼀下。
ThreadPoolExecutor 饱和策略
ThreadPoolExecutor 饱和策略定义 :
如果当前同时运⾏的线程数量达到最⼤线程数量并且队列也已经被放满了任务时, ThreadPoolTaskExecutor 定义⼀些策略 :
ThreadPoolExecutor.AbortPolicy :抛出 RejectedExecutionException 来拒绝新任务的处理。
ThreadPoolExecutor.CallerRunsPolicy :调⽤执⾏⾃⼰的线程运⾏任务。您不会任务请
求。但是这种策略会降低对于新任务提交速度,影响程序的整体性能。另外,这个策略喜欢增加队列容量。如果您的应⽤程序可以承受此延迟并且你不能任务丢弃任何⼀个任务请求的话,你可以选择这个策略。
ThreadPoolExecutor.DiscardPolicy 不处理新任务,直接丢弃掉。
ThreadPoolExecutor.DiscardOldestPolicy 此策略将丢弃最早的未处理的任务请求。
举个例⼦: Spring 通过 ThreadPoolTaskExecutor 或者我们直接通过 ThreadPoolExecutor
的构造函数创建线程池的时候,当我们不指定 RejectedExecutionHandler 饱和策略的话来配置线程池的时候默认使⽤的是 ThreadPoolExecutor.AbortPolicy 。在默认情况下, ThreadPoolExecutor 将抛出 RejectedExecutionException 来拒绝新来的任务 ,这代
表你将丢失对这个任务的处理。 对于可伸缩的应⽤程序,建议使⽤ ThreadPoolExecutor.CallerRunsPolicy 。当最⼤池被填满时,此策略为我们提供可伸缩队列。
public class ThreadPoolExecutorDemo {private static final int CORE_POOL_SIZE = 5;private static final int MAX_POOL_SIZE = 10;private static final int QUEUE_CAPACITY = 100;private static final Long KEEP_ALIVE_TIME = 1L;public static void main(String[] args) {//使⽤阿⾥巴巴推荐的创建线程池的⽅式//通过ThreadPoolExecutor构造函数⾃定义参数创建ThreadPoolExecutor executor = new ThreadPoolExecutor(CORE_POOL_SIZE,MAX_POOL_SIZE,KEEP_ALIVE_TIME,TimeUnit.SECONDS,new ArrayBlockingQueue<>(QUEUE_CAPACITY),new ThreadPoolExecutor.CallerRunsPolicy());for (int i = 0; i < 10; i++) {//创建WorkerThread对象(WorkerThread类实现了Runnable 接⼝)Runnable worker = new MyRunnable("" + i);//执⾏Runnableexecutor.execute(worker);}
//终⽌线程池executor.shutdown();while (!executor.isTerminated()) {}System.out.println("Finished all threads");}

线程池原理分析

四. 数据库

(1) Mysql

1.MyISAMInnoDB区别

MVCC   MySQL-InnoDB-MVCC多版本并发控制

2. 锁与事务

Mysql之锁与事务

3. 高级

Mysql高级

(2) Redis

1. redis 的线程模型

redis 内部使⽤⽂件事件处理器 file event handler ,这个⽂件事件处理器是单线程的,所以
redis 才叫做单线程的模型。它采⽤ IO 多路复⽤机制同时监听多个 socket ,根据 socket 上的事件
来选择对应的事件处理器进⾏处理。
⽂件事件处理器的结构包含 4 个部分:
  • 多个 socket
  • IO 多路复⽤程序
  • ⽂件事件分派器
  • 事件处理器(连接应答处理器、命令请求处理器、命令回复处理器)
多个 socket 可能会并发产⽣不同的操作,每个操作对应不同的⽂件事件,但是 IO 多路复⽤程序会监听多个 socket ,会将 socket 产⽣的事件放⼊队列中排队,事件分派器每次从队列中取出⼀个事件,把该事件交给对应的事件处理器进⾏处理。

2. redis 内存淘汰机制

3. redis 持久化机制

持久化数据也就是将内存中的数据写⼊到硬盘
Redis ⼀种持久化⽅式叫 快照(snapshotting RDB ),
另⼀种⽅式是只追加⽂件( append-only file,AOF

4. 缓存雪崩和缓存穿透问题解决⽅案

缓存雪崩
简介:缓存同⼀时间⼤⾯积的失效,所以,后⾯的请求都会落到数据库上,造成数据库短时间内承受⼤量请求⽽崩掉。

缓存穿透
缓存穿透说简单点就是⼤量请求的 key 根本不存在于缓存中,导致请求直接到了数据库上,根本没有经过缓存这⼀层。举个例⼦:某个⿊客故意制造我们缓存中不存在的 key 发起⼤量请求,导致⼤量请求落到数据库。

解决办法

1)缓存⽆效 key 表名:列名:主键名:主键值   尽量将⽆效的 key的过期时间设置短⼀点⽐如 1 分钟

2 )布隆过滤器   非法Key过滤        

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

0基础学习VR全景平台篇 第89篇:智慧眼-安放热点

一、功能说明 安放热点&#xff0c;是智慧眼成员们正式进入城市化管理的第一步&#xff0c;即发现问题后以安放热点的形式进行标记&#xff0c;再由其他的角色成员对该热点内容作出如核实、处理、确认完结等操作&#xff08;具体流程根据项目实际情况而定&#xff09;。 二、…

geacon_pro配合catcs4.5上线Mac、Linux

我的个人博客: xzajyjs.cn 一些链接 Try师傅的catcs4.5项目: https://github.com/TryGOTry/CobaltStrike_Cat_4.5&#xff0c;最新版解压密码见&#xff1a;https://www.nctry.com/2708.html geacon_pro: https://github.com/testxxxzzz/geacon_pro BeaconTool.jar: https:/…

BERT、ERNIE、Grover、XLNet、GPT、MASS、UniLM、ELECTRA、RoBERTa、T5、C4

BERT、ERNIE、Grover、XLNet、GPT、MASS、UniLM、ELECTRA、RoBERTa、T5、C4 ELMOBERTERNIE![在这里插入图片描述](https://img-blog.csdnimg.cn/274e31d0f8274c748d05abe2ec65fc73.png)GroverXLNetGPTMASSUniLMELECTRARoBERTaT5C4ELMO BERT

干货分享:可证明安全的隐私计算

“隐语”是开源的可信隐私计算框架&#xff0c;内置 MPC、TEE、同态等多种密态计算虚拟设备供灵活选择&#xff0c;提供丰富的联邦学习算法和差分隐私机制 开源项目&#xff1a;github.com/secretflowgitee.com/secretflow 以下文章来源于DataFunTalk &#xff0c;作者洪澄 D…

Typecho博客搭建 实现公网访问内网站点

文章目录 前言1. 环境安装2.安装Typecho3.安装cpolar内网穿透4. 固定公网地址5.配置Typecho 前言 Typecho是一款PHP语言编写的开源博客程序&#xff0c;它是一个轻量级的内容管理系统&#xff0c;专注于博客领域。支持多用户、多站点、多语言等功能&#xff0c;可以满足不同用…

Go 语言在 Windows 上的安装及配置

1. Go语言的下载 Golang官网&#xff1a;All releases - The Go Programming Language Golang中文网&#xff1a;Go下载 - Go语言中文网 - Golang中文社区 两个网站打开的内容只有语言不同而已&#xff0c;网站上清晰的标注了不同操作系统需要对应安装哪个版本&#xff0c;其中…

Ansible 临时命令搭建安装仓库

创建一个名为/ansible/yum.sh 的 shell 脚本&#xff0c;该脚本将使用 Ansible 临时命令在各个受管节点上安装 yum 存储库. 存储库1&#xff1a; 存储库的名称为 EX294_BASE 描述为 EX294 base software 基础 URL 为 http://content/rhel8.0/x86_64/dvd/BaseOS GPG 签名检查为…

【Python】强化学习:原理与Python实战

搞懂大模型的智能基因&#xff0c;RLHF系统设计关键问答 RLHF&#xff08;Reinforcement Learning with Human Feedback&#xff0c;人类反馈强化学习&#xff09;虽是热门概念&#xff0c;并非包治百病的万用仙丹。本问答探讨RLHF的适用范围、优缺点和可能遇到的问题&#xff…

如何更高效的写出更健全的代码,一篇文章教会你如何拥有一个良好的代码风格

前言&#xff1a;在平常的写代码的过程中&#xff0c;或多或少的遇到很多奇怪的 bug &#xff0c;尤其是一些大的程序&#xff0c;明明上一部分都是好好的&#xff0c;写下一块的时候突然多几百个 bug 的情况&#xff0c;然后这一块写完了后编译的时候直接傻眼了&#xff0c;看…

【Spring】一次性打包学透 Spring | 阿Q送书第五期

文章目录 如何竭尽可能确保大家学透Spring1. 内容全面且细致2. 主题实用且本土化3. 案例系统且完善4. 知识有趣且深刻 关于作者丁雪丰业内专家推图书热卖留言提前获赠书 不知从何时开始&#xff0c;Spring 这个词开始频繁地出现在 Java 服务端开发者的日常工作中&#xff0c;很…

Ubuntu 配置国内源

配置国内源 因为众所周知的原因&#xff0c;国外的很多网站在国内是访问不了或者访问极慢的&#xff0c;这其中就包括了Ubuntu的官方源。 所以&#xff0c;想要流畅的使用apt安装应用&#xff0c;就需要配置国内源的镜像。 市面上Ubuntu的国内镜像源非常多&#xff0c;比较有…

恒运资本:信创概念再度活跃,华是科技再创新高,南天信息等涨停

信创概念21日盘中再度活跃&#xff0c;截至发稿&#xff0c;华是科技涨超17%&#xff0c;盘中一度触及涨停再创新高&#xff0c;中亦科技涨超13%亦创出新高&#xff0c;久其软件、南天信息、新炬网络、英飞拓均涨停。 音讯面上&#xff0c;自8月3日以来&#xff0c;财政部官网连…