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

大厂面试题

线程池的状态?


回答:running->shutdown->stop->tidyng->TERMINATED
线程池状态怎么流转2.
回答:变成shutdown,执行shutdown()函数变成stop,执行shutdownnow函数
变成tining,所有任务已处理完
变成TERMINATED,线程池调结束

RUNNING接收新任务,处理队列中的任务
SHUTDOWN不接受新任务,但继续处理队列中已有的任务
STOP不接受新任务,不处理队列中的任务,中断正在执行的任务
TIDYING所有任务都已终止,工作线程数量为0,即将执行 terminated() 钩子方法
TERMINATED

terminated() 方法执行完成,线程池彻底结束

线程状态的流转3.

回答:新建状态(New)线程对象被创建后
阻塞状态(Blocked):等待监视器锁。
等待状态(Waiting)。等待另外一个线程的特定操作
超时等待(timed waiting)。等待特定的时间
运行状态(Running):线程获取CPU权限进行执行。需要注意的是,线程只能从就绪状态进入到运行状态。
死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

NEW:当前 Thread 对象虽然有了,但是内核的线程还没有(还没调用 start)
TERMINATED:当前 Thread 对象虽然还在,但是内核的线程已经销毁了(线程已经结束了)
RUNNABLE:就绪状态,正在 cpu 上运行 或 随时可以去 cpu 上运行
BLOCKED:因为 锁竞争 引起的阻塞
TIMED_WAITNG:有超时时间的等待,比如 sleep 或者 join 带参数版本
WAITING:没有超时时间的等待 join /wait

.讲-下Redis跳表的数据结构

// 简化版 C 结构体(来自 Redis 源码)
typedef struct zskiplistNode {sds ele;          // 学生名字,比如 "xiaohong"double score;     // 分数,比如 90.0struct zskiplistNode *backward;  // ← 向后指针(用于倒着走)// 多层索引结构(每个节点有自己的层数)struct zskiplistLevel {struct zskiplistNode *forward;  // → 向前指针unsigned int span;              // 这一跳跨过了几个节点} level[];
} zskiplistNode;
ele存储成员名(Redis 用 sds 是它自己的字符串类型)
score排序依据,按分数从小到大排
backward指向前一个节点,实现 ZREVRANGE 倒序遍历
level[].forward每一层的“快车道”指针
level[].span

记录这一跳跳过了多少个底层节点(用于算排名)

typedef struct zskiplist {struct zskiplistNode *header;  // 头节点(不存真实数据)struct zskiplistNode *tail;    // 尾节点(最后一个真实节点)unsigned long length;          // 当前有多少个真实节点int level;                     // 所有节点中最高的层数
} zskiplist;

📌 想象这是一个“地铁控制中心”:

  • header:总站,所有线路从这里出发
  • tail:终点站,方便快速找到最后一个人
  • length:当前排行榜上有多少人
  • level:目前最高有几条快车道(Level 0 ~ Level N)

IO多路复用
LINUX有哪些IO机制、select poll epoll,底层实现等等
BIO NIO等。

最基础的 TCP 的 Socket 编程,它是阻塞 1/0 模型,基本上只能一对一通信,那为了服务更多的客户端,我们需要改进网络 I/O 模型。


比较传统的方式是使用多进程/线程模型,每来一个客户端连接,就分配一个进程/线程,然后后续的读写都在对应的进程/线程,这种方式处理 100 个客户端没问题,但是当客户端增大到 10000 个时,10000 个进程/线程的调度、上下文切换以及它们占用的内存,都会成为瓶颈。

服务器的主进程负责监听客户的连接,一旦与客户端连接完成,accept0 函数就会返回一个「已连接Socket」,这时就通过 fork()函数创建一个子进程,实际上就把父进程所有相关的东西都复制一份,包括文件描述符、内存地址空间、程序计数器、执行的代码等。

当服务器与客户端 TCP 完成连接后,通过 pthread_create()函数创建线程,然后将「已连接 Socket」的文件描述符传递给线程函数,接着在线程里和客户端进行通信,从而达到并发处理的目的。我们可以使用线程池的方式来避免线程的频繁创建和销毁,所谓的线程池,就是提前创建若干个线程,这样当由新连接建立时,将这个已连接的 Socket 放入到一个队列里,然后线程池里的线程负责从队列中取出「已连接 Socket 」进行处理。


为了解决上面这个问题,就出现了 !/0 的多路复用,可以只在一个进程里处理多个文件的 10,linux 下有三种提供 /O 多路复用的 API,分别是:select、poll、epoll。

select 和 poll 并没有本质区别,

select 使用固定长度的 BitsMap,表示文件描述符集合,而且所支持的文件描述符的个数是有限制的,在Linux 系统中,由内核中的 FD SETSIZE 限制, 默认最大值为 1024 ,只能监听 0~1023 的文件描述符。
poll 不再用 BitsMap 来存储所关注的文件描述符,取而代之用动态数组,以链表形式来组织,突破了select 的文件描述符个数限制,当然还会受到系统文件描述符限制。

它们内部都是使用「线性结构」来存储进程关注的 Socket 集合。
在使用的时候,首先需要把关注的 Socket 集合通过 select/poll 系统调用从用户态拷贝到内核态,然后由内核检测事件,当有网络事件产生时,内核需要遍历进程关注 Socket 集合,找到对应的 Socket,并设置其状态为可读/可写,然后把整个 Socket 集合从内核态拷贝到用户态,用户态还要继续遍历整个 Socket集合找到可读/可写的 Socket,然后对其处理。
很明显发现,select和 pol 的缺陷在于,当客户端越多,也就是 Socket 集合越大,Socket 集合的遍历和拷贝会带来很大的开销,因此也很难应对 C10K。


epoll 是解决 C10K 问题的利器,通过两个方面解决了 select/poll 的问题。


·epoll 在内核里使用「红黑树」来关注进程所有待检测的 Socket,红黑树是个高效的数据结构,增删改-般时间复杂度是 O(logn),通过对这棵黑红树的管理,不需要像 select/poll 在每次操作时都传入整个Socket 集合,减少了内核和用户空间大量的数据拷贝和内存分配。
epoll 使用事件驱动的机制,内核里维护了一个「链表」来记录就绪事件,只将有事件发生的 Socket 集合传递给应用程序,不需要像 select/poll 那样轮询扫描整个集合(包含有和无事件的 Socket),大大提高了检测的效率。


而且,epo 支持边缘触发和水平触发的方式,而 select/poll 只支持水平触发,一般而言,边缘触发的方式会比水平触发的效率高

这两个术语还挺抽象的,其实它们的区别还是很好理解的。
使用边缘触发模式时,当被监控的 Socket 描述符上有可读事件发生时,服务器端只会从 epoll wait 中苏醒一次,即使进程没有调用 read 函数从内核读取数据,也依然只苏醒一次,因此我们程序要保证-次性将内核缓冲区的数据读取完;
使用水平触发模式时,当被监控的 Socket 上有可读事件发生时,服务器端不断地从 epoll wait 中苏醒,直到内核缓冲区数据被 read 函数读完才结束,目的是告诉我们有数据需要读取;

索引失效的场景有哪些,你知道什么改进方法吗

我们查询语句对索引字段进行左模糊匹配、表达式计算、函数、隐式类型转换操作,或者联合索引没有遵循最左匹配原则,这时候查询语句就无法走索引了

java版本改动问题 1.7 1.8有哪些主要区别

Java 7新特性:钻石操作符,try-with-resource 语句、支持动态类型语言、Fork/Join 框架等。
Java8新特性:Lambda 表达式、Stream API、新的Date/Time API、 NashornJavaScript 引|擎等。如何找到需要回收的垃圾、引用等等

  • Java 8: 提供了Optional类来避免空指针异常,它是一个容器类,代表一个值存在或不存在的情况。
  • Java 7: 需要手动检查对象是否为null,并进行相应的处理。

整个索引查询的过程是怎样的、

http://www.dtcms.com/a/316777.html

相关文章:

  • React在使用create-react-app创建项目慢的解决办法
  • TanStack React Query 完全指南:从0到精通
  • Flux.1系列模型解析--Flux.1 Tools
  • 【模电笔记】—— 直流稳压电源——整流、滤波电路
  • 无线网络扫描工具 ‌WifiInfoView‌
  • 高通平台Wi-Fi Display学习-- 调试 Wi-Fi Display 问题
  • 人工智能领域、图欧科技、IMYAI智能助手2024年全年历史更新大事件汇总
  • 人工智能领域、图欧科技、IMYAI智能助手2025年6月更新月报
  • RHCA05--进程管理与文件系统管理
  • 基于SpringBoot的青少年网络安全教育系统
  • C语言:20250805学习(文件预处理)
  • 系统集成项目管理工程师【第十一章 规划过程组】项目管理计划、范围管理与收集需求篇
  • VUE丢失long类型精度,使用 json-bigint 库解析大整数
  • 基于腾讯iOA的企业安全防护体系融合升级指南:从边界防御到无边界纵深防护
  • 前端工程化:Vue3(二)
  • 在X86架构Linux中创建虚拟根目录并下载指定架构(如aarch64)的软件包(含依赖)
  • opencv 阈值分割函数
  • ASP3605I同步降压调节器的高频化设计与多相扩展技术优化方案
  • python的教务管理系统
  • Android中性能优化——白屏避免
  • Makefile基础
  • C/C++ 宏中 `do { ... } while (0)` 的“零次循环”技巧
  • Windows 远程管理 (WinRM)问题详解包括c#与python例子
  • vue - - - - 18n高级使用(插入变量)
  • Pycharm 2025.2 免登陆试用
  • Centos-Stream 10 安装教程(2025版图文教程)
  • [激光原理与应用-152]:光学器件 - 光栅,一种由周期性排列的等宽等间距结构组成的光学元件,通过衍射和干涉实现光的分光、调制或测量功能的光学元件
  • 详细讲述优雅草蜻蜓I即时通讯私有化中xmpp服务中的tigase的角色与作用深度分析-卓伊凡|bigniu
  • 【Istio系列--Istio基础理论和部署】
  • leetcode 104.二叉树的最大深度