大厂秋招面经,特意分享大家

阿里

Java

  • JVM分区
  • 垃圾收集算法
  • synchronized原理
  • 双亲委派机制
  • 线程池参数
  • newFixedTheadPool底层,优缺点
  • springmvc
  • @Autowired原理
  • springboot原理
  • @OnConditionalClass实现原理
  • @OnMissingBean没有bean会怎么样,会classNotFound
  • HashMap 底层数据结构
  • HashMap 什么时候扩容?装载因子和临界值默认是多少?扩容成多大?为什么容量是2的幂次方?
  • 线程安全的Map?分段锁是如何实现的?JDK 1.8之后有哪些优化?
  • Lock和Synchronized区别
  • AQS实现
  • 锁优化
  • String StringBuilder StringBuffer区别,特点,场景
  • ConcurrentMap 源码
  • CMS
  • 线程生命周期(状态)
  • ReentrantLock与AQS同步框架
  • CAS原理是什么?
  • synchronize原理是什么?
  • springboot 和 spring 的区别是什么?
  • spring中bean的初始化过程
  • 谈一谈异常机制
  • Spring IOC和AOP
  • Arrays.sort()底层原理

场景题

  • 一个8G的服务器,堆的大小应该设置成多少
  • 海量数据求频率最多的100个
  • spring一个事务中调用另外一个事务,另一个- 事务发生异常会怎么样
  • 一个父类加载器能不能加载一个子类加载器,为什么
  • select * from A where id in (select id from B)怎么优化
  • 一个16G的内存堆分配多少,采用什么垃圾收集器,为什么用cms不用g1,为什么(面试官一直问为什么使用cms或者使用g1,回答了这两个的优缺点之后还是不满意)
  • 多线程解析一个超大文件怎么处理,如果文件切分的时候关键信息被分到了不同的解析线程中怎么办
  • hashset是如何判断两个对象相等的
  • 如何要两个对象相等equals和hashcode这两个方法要怎么重写
  • hash算法(最开始讲hash冲突算法,面试官说不是这个,我又说对hash值对质数取余,面试官也说不是这个,不知道他要我回答啥。。。)
  • 不使用任何优化,直接访问数据库,如何优化 (提示 redo、undo log的开销)(这里应该还可以答:批处理、连接池等)
  • 行锁锁的是索引,如果一个表没有主键怎么加锁?(锁表)
  • hashmap 为什么不直接用红黑树,还要用链表?
  • 红黑树的特性?各种操作的时间复杂度?最多旋转几次达到平衡?
  • finally 中 return 会发生什么?
  • 如何破坏双亲委派
  • 浏览器中用户信息和密码的安全有没有考虑过
  • 两个线程如何交替打印A和B
  • 100万个数,数据类型是int,给你8核CPU,8G内存,如何求数组的和?
  • 很多个不重复的数,假设用的数组来装,我希望你实现一个方法,每次调用这个方法给我随机返回100个不重复,记住是随机的。
  • 四个引用的具体应用场景
  • 垃圾回收器具体应用场景
  • 可达性分析算法具体应用场景
  • 垃圾回收器参数调优(给具体场景 大概就是并发低延时)
  • 高并发多连接jvm 线程池参数调优(顺着来)
  • 高并发系统调优(再顺一下)
  • 队列与栈的 应用场景
  • 点赞高并发怎么办?
  • 消息中间件用过么?怎么自己设计一个消息中间件?
  • 假设catch,final,catch中有return,那么final还会不会执行
  • 假设1亿的11位的手机号,运行空间128M,如果要进行排序,那么要怎么设计
  • jvm的设计角度,gc你怎么优化?
  • 你怎么设计md5函数?
  • cpu一直被占满,怎么排查?
  • 让你自己设计一个垃圾回收器,尽可能提高回收效率,你会怎么设计?(ZGC和香浓多,整就完事了)
  • MD5加密算法,不使用hashmap和映射,你自己来设计一个同类型的,给定字符串可以生成64位随机数的,你怎么设计
  • 利用java现有的东西,让你设计一个对象,实现类似synchronize的功能,使得多个线程不冲突,你如何设计?(ThreadLocal玩起来)
  • synchronize锁定.class和锁定一个实例有什么区别?
  • explain中的key字段的值等于ref时,有没有触发索引?
  • 如何实现单点登录,如何实现权限控制,用户密码泄露后如何保证安全性
  • spring中循环依赖如何解决?如果让你来实现你怎么做?
  • 如果我的服务器ip地址变了,客户端如何感知到呢?
  • 轮询的负载均衡的缺点是什么?如何改进?
  • 让你来实现真正的负载均衡,你如何做?(我回答记录每台服务器在最近的一段时间内接收的请求的数量,每次都把请求发送给数量最小的服务器,后来面试官提醒我还应当考虑每个请求耗费的时间)
  • 秒杀项目中静态资源CDN怎么做?
  • css文件能放到CDN上吗?
  • 秒杀缓存如何与数据库的数据保持一致性?
  • 通过广播的方式去更新每个节点的缓存,如果某个节点的缓存更新失败,那么如何排查是哪个节点呢?
  • 消费者消费失败是怎么处理的
  • 如何保证消息消费的顺序性
  • 如何保证消息不被重复消费
  • 项目中要进行分布式扩展应该怎么做
  • 缓存和mysql数据一致性如何保证
  • 微信步数排行,假设百万级用户,怎么排序,实时更新(我说排序就是海量数据排序的方式分组排序再归并,然后实时更新的话也是组内更新组内排序,但是每组的分度值可能不一样,比如0-2000可能一组,但2000-4000可能要分五组之类的,因为步数特别少和特别多的都是少数。)
  • 发生了OOM,应该怎么去分析解决?jvm调优
  • 什么时候发生线程的上下文切换?
  • CAS是硬件实现还是软件实现
  • 除了wait和notifyall,还有什么办法实现类似的功能
  • 微信抢红包设计(只讲了类似多线程抢、Semphore,缓存)、海量文件找重复次数最多的个数(分治)

MySQL

  • 索引怎么优化
  • 为什么用B+树
  • Innodb 和 Myisam 的区别
  • 聚集索引和非聚集索引 创建以后的文件大小
  • 为什么不用哈希索引?
  • 有几种事务隔离级别?
  • Innodb 行锁是如何实现的?
  • mysql怎么分页
  • 索引为什么查找快
  • 慢查询如何优化
  • mvcc原理

Redis

  • redis基本数据类型
  • redis集群?切片
  • 为什么用Redis,Redis宕机了怎么办,数据呢?怎么保持热点数据?过期机制,淘汰机制?
  • redis是单线程么?为什么快?io模型什么怎么样的,具体是怎么个流程?
  • 缓存穿透、雪崩,redis持久化机制

计网

  • tcp三次握手
  • HTTP 和RPC区别?还有呢?
  • JWT流程,安全?Session?
  • 盐有单独保存起来么
  • HTTP 和 HTTPS的区别
  • https的加密证书怎么获取
  • 加密后客户端保留的是公钥还是私钥
  • 讲一下ftp
  • cookies
  • http以及https 以及加密手段
  • 浏览器输入url后的一系列操作
  • HTTP状态码
  • 为什么用Jwt,cookie,session有什么好处?
  • TCP怎么确保可靠性的?丢包和串包怎么办?
  • DNS说一下?

操作系统

  • 上下文切换
  • 内核态用户态
  • 多路复用IO模型,select,poll,epoll

分布式

  • 怎么实现分布式锁
  • redis分布式锁有什么缺点,怎么解决
  • 单体应用和微服务区别,为什么要有微服务?好处?还有呢?
  • 微服务流程?
  • 分布式缓存?
  • 分布式session原理
  • SpringCloud及其组件你了解哪些?

算法

  • n个线程顺序循环打印0-100
  • 手写LinkedList的数据结构并写出add和remove算法
  • 微信红包算法实现
  • 链表如何找环
  • 有序链表合并
  • 共计9个苹果,有2只猴子,一个猴子每次拿2个苹果,一个猴子每次拿3个苹果,如果剩余的苹果不够猴子每次拿的数量,则2只猴子停止拿苹果,请用java多线程模拟上面的描述,要求性能尽可能高效(这个题开始是用可重入锁写的,结束之后自己本地测试发现程序不会自动结束,后来改成用AtomicInteger和cas来实现了)
  • 设计一个多线程打印程序,第i个线程只打印i-1数字,比如第1个线程打印数字0,第2个线程只打印数字1,依次类推。任意给定一个数字序列,比如3382019835830,能够使用该程序打印出来。

腾讯

算法

  • 判断树是否对称:1
  • 在一个大数组里求第100大的数字:1
  • 找出A[1000]、B[1000]、C[1000]中的重合的数字:1
  • 给出25亿个QQ号,找出其中重复的?如果不用bitmap且只有一台机器怎么做?:1
  • 你了解哪些排序?:1
  • 快排什么时候复杂度不好?:1
  • 红黑树的特点?如果给红黑树插入数据,红黑树是怎么做的?:1
  • 写一个栈:1
  • 两个特别大的数相乘:1
  • 求两个已排序数组合并后的中位数:1
  • 设计栈,使得getMin()和getMax()的时间复杂度为O(1):1
  • 一个数组中只有一个数字出现了奇数次,其他数字出现了偶数次,找到出现了奇数次的那个数:1
  • 100层楼和2个玻璃杯,怎样用最少的次数找出杯子在哪一层会碎:1
  • 哈希表是如何实现的?:1
  • 1TB的数据如何进行排序:1
  • 对100TB的数据进行排序?(拆分多个数据段进行排序,然后归并):1
  • 判断链表有环,找环入口:2
  • 100万个数找最小的10个(大顶堆):1
  • 旋转数组找出最小值:1
  • 找链表中间节点:1
  • 找链表倒数第k节点:1
  • 微信发红包 m块钱发给n个人 你怎么设计算法:1
  • 很多数中有俩数重复了咋判断:1
  • 单调栈问题:1
  • 分组反转单向链表:1
  • 非递归实现后序遍历:1
  • 把数组排成最小的数:1
  • 找第k大元素:1
  • 链表循环右移动k位置:1
  • 如何自己实现一个kv结构的,你有哪几种方式:1
  • 用hash表有什么问题,和解决了什么问题?:1
  • 用树解决了什么问题,红黑树和hash分别是有序还是无序的呢?:1
  • 为什么是有序还是无序?具体怎么实现的呢?:1

MySQl

  • mysql慢查询如何优化?:2
  • 优化器是什么时候起作用的?:1
  • MVCC的原理?:1
  • InnoDB和myISAM的区别?:2
  • InnoDB的聚集索引和MyISAM的非聚集索引的区别?:1
  • B+树、B树、红黑树的区别:2
  • 辅助索引的叶子上有什么内容?辅助索引和主键索引性能差距在哪里?:1
  • 数据库事务性质,并发一致性问题:1
  • 数据库存储过程,视图,函数的使用,几种连接方式:1
  • 索引:2
  • 事务的ACID:2
  • 数据库的join操作实际上是MySQL底层是怎么做的呢:1
  • limit a,b是什么意思,会有什么性能上的问题:1(limit之前的数据先查出来、a代表起点、b代表数量,如果a很大的话,那么MySQL需要先去遍历前a条数据而不是直接定位,所以这里存在性能问题)
  • 数据库容灾方面问题,数据库挂了怎么办:1
  • 数据库集群怎么实现数据一致性:1

java

  • 从java代码到.class文件,中间经历实现你了哪些过程?:1
  • Java数据类型,大小:1
  • instanceof和getClass:1
  • JMM:2
  • 介绍项目中的SpringIOC DI MVC AOP:1
  • JVM数据区:1
  • GC相关:1
  • OOM情况:1
  • 多态的实现:1
  • Java类的分类:1
  • 普通类,接口,抽象类的区别:1
  • Java创建线程的方式:1
  • 线程的状态:1
  • 单例模式:1
  • 类加载过程:1
  • 双亲委派模型:1
  • Java会出现内存泄露吗:1
  • 如何定位和解决OOM:1
  • Java的GC中什么场景下使用CMS和G1:1
  • hashmap:1
  • JVM参数调优:1
  • Minor GC和Full GC:1
  • 线程池:1
  • spring bean的什么周期:2
  • spring 单例的bean是否线程安全:1
  • 有状态的bean和无状态的bean区别:1
  • spring事务了解么:1
  • 如何实现HashMap取出的顺序和放入顺序一致?:1
  • HashMap的扩容的时间复杂度,如何优化?:1
  • JDK8添加了哪些特性?:1
  • java为什么说它即是解释型语言,又是编译型语言:1
  • 面向对象和面向过程的区别?:1
  • java的类和c++的类有什么区别:1
  • java语言的三大特性:1
  • 怎么拼接多个string:1
  • 讲讲异常:1
  • 深拷贝和浅拷贝:1
  • java的包装类的了解?为啥要有包装类:1
  • Java的集合:1
  • 乐观锁和悲观锁:1
  • synchronize和Lock区别:1
  • synchronized的底层是怎么实现的?:1
  • ReentrantLock的区别:1
  • ThreadLocal的原理是什么:1
  • CountdownLatch:1

redis

  • redis在你项目中怎么用的?防止重复提交是怎么做到的?:1
  • Redis五种数据类型:1
  • Hash底层:1
  • redis跳表的优势:1
  • reactor模式:1
  • redis持久化:1

计网

  • HTTP还是HTTPS请求?有什么区别?:3
  • HTTP过程的四次挥手?:2
  • TIME_WAIT的作用?:2
  • cookie的作用?:1
  • 腾讯和百度两个网页能获取对方的cookie吗?:1
  • 在百度里搜索abc的过程?:1
  • 搜索的时候,数据包是怎么交给网卡的?(7层 5层网络模型)层层封包都加的是什么内容?:1
  • 网卡怎么知道数据是发送给百度服务器的,怎么找到服务器的?:1
  • 计算机网络分层,各层的协议:1
  • http流量控制,拥塞避免如何实现:1
  • 多少种请求方式,get和post区别:1
  • Https端口443以及怎么的实现流程:1
  • Session和Cookie区别:1
  • TCP和UDP的区别:1
  • TCP三次握手:1
  • CLOSE_WAIT:1
  • DNS解析的过程:1
  • HTTP长连接和短连接:1
  • TCP拥塞控制:1
  • 了解粘包吗,怎么设置不粘包:1
  • sql注入如何防范:1
  • xss如何防范:1
  • udp的最大包长度,为什么这么大?:1
  • 傻瓜窗口了解吗?怎么解决?:1
  • socket去写的时候你会怎么写?考虑什么?:1
  • http常见头部信息有哪些:1
  • 你知道https的非对称加密和对称加密使用了哪些算法么:1

os

  • 内核态和用户态的区别?:1
  • 用户态通过什么样的接口调用内核?
  • 进程在内存中是如何分配的?(段页式及其细节、数据段、栈段、代码段):1
  • 操作系统进程同步方式:1
  • 进程怎样通信:2
  • 套接字:1
  • 线程通信机制:1
  • CPU密集型任务适合多进程还是多线程?:1
  • 进程的同步机制,你在什么时候用:1
  • 向一个进程发出kill信号接下来发生什么?:1
  • 共享内存的坏处:1
  • 操作系统中中断的分类:1
  • 操作系统页置换算法:1
  • 僵尸进程问题:1
  • 页式和段式的区别,优缺点,应用场景。:1
  • 讲一下虚拟内存、页表:1
  • 为什么顺序io比随机io快?:1
  • 随机io的过程是什么?:1
  • 用户态和内核态的区别?如何切换?:1
  • 原子操作的意义:1
  • i++为什么不是原子操作,如何去保证是原子操作?:1

分布式

  • 高并发系统大量请求如何优化:1
  • 分布式系统CAP:1
  • 秒杀系统解决超卖问题,(数据库排它锁和乐观锁CAS版本号机制):1
  • base理论:1
  • 两阶段提交:1
  • redis分布式锁的注意事项,实现过程?:1

亮点

  • Netty,NIO通信框架:1
  • BIO、NIO、AIO:1
  • NIO又可以分为三种,基于轮询、基于多路复用、基于事件回调:1
  • 如何指定使用哪种方式:1
  • 知道他底层怎么实现的吗:1
  • Netty底层Buffer的实现:1
  • 日志清理如何解决:1
  • 日志合并如何解决:1
  • reactor模式:1
  • 讲讲netty的io模型:1
  • 讲讲多路复用机制,你觉得什么时候多路复用性能会比较好?

字节

算法(好多树)

  • 每K个节点翻转链表(链表k个一旋转):2
  • 二叉搜索树转链表:1
  • 负载均衡算法:1
  • 排序算法哪些是稳定的:1
  • 二叉树求和:1
  • 序列化和反序列化二叉树:1
  • 如何判断一颗树是否是完全二叉树:1
  • 求数组的极值点:1
  • 最大连续子序列:1
  • 回文链表:1
  • 链表反转:1
  • 对称二叉树:1
  • 二叉树右视图:1
  • 移动零:1
  • 给定链表,确定中间数:1
  • 链表奇数位升序、偶数位降序:1
  • 二叉树的左视图:1
  • 一致性hash:1
  • 旋转数组的最小值:1
  • 判断两个链表是否交叉?:1
  • 三数之和:1
  • 两个链表相加:1
  • 给一个序列判断是不是二叉搜索树的后序遍历:1
  • 单词翻转
  • 二叉树层序遍历:1
  • 最长连续子串:1
  • 岛屿:1
  • 无重复字符的最长字串:1
  • 设计一个数据结构 list: rpush rpop lpush lpop index 五种方法的时间复杂度均为 O(1),数据量上限是100w(我回答使用双端队列+hashMap, 面试官说可以用两个数组实现)
  • 求集合的子集:1
  • 字符串全排列:1

Java(所有谈谈的,老哥我最喜欢了,狂吹)

  • 常见的GC回收器,越详细越好:1
  • SpringMVC的请求过程:1
  • 常见的GC回收器,越详细越好:1
  • 线程池(所有你知道的),原理尽量详细些:2
  • HashMap底层实现:1
  • concurrenthashmap:1
  • ConcurrentHashMap的扩容机制:1
  • LinkedHashMap 底层数据结构?使用场景? :1
  • Spring AOP怎么实现,围绕bean生命周期去讲:1
  • 三大特性:1
  • 谈谈多态:2
  • 接口和抽象类的区别:1
  • 谈谈集合:1
  • Arraylist和LinkedList的区别:1
  • Hashmap底层:1
  • ==跟equals的区别:1
  • 有界无界队列:1
  • 线程的创建方法:1
  • 深拷贝、浅拷贝:1
  • sychronized:1
  • GC算法:1
  • JVM内存结构:1
  • 谈谈cas:1
  • 谈谈JVM:1
  • JDK动态代理:1
  • 类加载的过程:1
  • 说说Object类,作用,有什么方法:1
  • Treeset Treemap的底层实现:1
  • volatile:1
  • 谈谈反射:1

字节问的Java没啥难度,简单的一批

计算机网络

  • https通信过程:1
  • https加密过程,怎么判断证书的有效性:1
  • tcp、udp区别
  • tcp(所有):1
  • TCP拥塞控制:1
  • TCP滑动窗口:1
  • http 头部有哪些key:1
  • http状态码有哪些:1
  • DNS服务器怎么处理域名请求的,了解原理吗:1
  • GET、POST:1
  • HTTP2.0有哪些改动:1
  • 路由器怎么工作的:1
  • 七层协议讲一下:1
  • http是否无状态?如何有状态?session和Cookies的区别:1

MySQL

  • 聚簇索引和非聚簇索引底层实现:1
  • 隔离级别:2
  • mysql在业务中怎么实现乐观锁:1(MVCC各种吹)
  • MVCC原理,和for update有什么区别:1
  • Innodb\myisam区别:1
  • 谈谈B+树前世今生以及所有:1
  • ACID:1
  • 联合索引底层结构:1
  • SQL里where having分别是做什么的,有什么区别,什么时候用:1
  • MySQL索引类别:1
  • 左连接和内连接的区别:1
  • 谈谈binlog和redolog :1

题:

  • 获取所有课程得分均大于80分的学生的平均得分:2

Redis

  • 分布式锁怎么实现,Redis加锁过程:1
  • Redis的setnx有哪些注意点,比如宕机时会发生什么:1
  • zset底层原理:(吹它的跳跃表和压缩列表):3
  • Redis中的哨兵:1
  • 谈谈Redis集群 Redis Cluster,以及主从复制原理:1
  • redis的hashmap和java的hashmap有何异同:1
  • 持久化策略:1
  • 利用redis的可重入锁如何设计:1
  • redis分布式锁是否公平锁?

操作系统

  • 进程间通信有哪些,各个优缺点:2
  • select/poll/epoll:2
  • 用户态、内核态:1
  • 信号量 同步 互斥的区别:1
  • 页面的置换算法:1
  • 进程间的同步方式用过哪些:1

linux

  • linux如何查找CPU故障

RocketMQ

  • RocketMQ有哪些组件:1

Mybatis

  • mybatis的缓存:1

项目

  • Jmeter压测的时候为什么会丢包

感觉字节基本没有Spring,可惜了,问的Java也比较基础!! 如果有中间件的话,多熟悉熟悉。 其次就是计算机网络和操作系统的知识多熟悉熟悉,最后就是大家都知道的算法!!!

以上还有各个大厂总结的面经,都在链接:https://github.com/DreamCats/Dc-Notes

#面经##Java##校招##字节跳动##阿里巴巴##腾讯#
全部评论
过了吗?
点赞 回复
分享
发布于 2021-03-27 23:15
记录下搜到的答案: 1.分段锁:容器里有多把锁,每一把锁用于锁容器其中一部分数据,那么当多线程访问容器里不同数据段的数据时,线程间就不会存在锁竞争,从而可以有效的提高并发访问效率,这就是ConcurrentHashMap所使用的锁分段技术,首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。 2.HashMap 底层数据结构:jdk1.8的HashMap底层是数组、链表、红黑树。HashMap通过key的hashCode经过扰动函数处理后得到hash值,然后通过(n-1)&hash判断当前元素存放的位置(n是指当前数组的长度,在初始化一个HashMap的时候,如果是无参构造函数,则规定这个HashMap数组的长度为16,0-15,;如果为hashmap提供了长度,在经过函数tableSizeFor处理后,变成大于等于它的一个最小2**n,数组容量不足时,会扩充,数组扩充因素为0.75,每当数组容量达到当前数组容量的最大容量*0.75时,这个数组就会扩容一倍。数组的最大容量为2的30次方,),如果当前位置存在元素的话,就判断该元素的hash值以及key是否相同,如果相同的话,直接覆盖,否者,就通过拉链法解决冲突。当链表长度大于阈值(8)时,会调用treeifyBin方法。如果大于等于阈值,就会将链表转化为红黑树,当红黑树中节点小于等于6时,会转换为链表(只有数组长度大于等于64的情况下,才会执行链表与红黑树的转换,否者只是执行resize方法对数组扩充)。首次put时,会判断是否为第一次put,如果为第一次put,会先进行hashmap的初始化,然后存入数据,最后判断是否要进行扩充。不是第一次时,先存入数据,在判断是否要进行扩充
点赞 回复
分享
发布于 2022-06-07 23:15
联想
校招火热招聘中
官网直投
3.HashMap扩容:默认的容器大小是16,最大长度是2的30次方,load factor默认是0.75,扩充的临界值是16*0.75=12;数组大小为16,那么当hashmap中元素个数超过16*0.75=12的时候,就把数组的大小扩展为2*16=32,即扩大一倍,然后重新计算每个元素在数组中的位置;当我们使用HashMap(int initialCapacity)来初始化容量的时候,jdk会默认帮我们计算一个相对合理的值当做初始容量。当HashMap的容量值超过了临界值(threshold)时就会扩容,threshold = HashMap的容量值*0.75。 4.Synchronized原理:Monitor 被翻译为监视器或管程,每个 Java 对象都可以关联一个 Monitor 对象,如果使用  synchronized 给对象上锁(重量级)之后,该对象头的 Mark Word 中就被设置指向 Monitor 对象的指针。刚开始  Monitor 中 Owner 为 null,当 Thread-2 执行 synchronized(obj) 就会将 Monitor 的所有者 Owner 置为 Thread-2 ,Monitor中只能有一个 Owner,在 Thread-2 上锁的过程中,如果 Thread-3,Thread-4,Thread-5 也来执行  synchronized(obj),就会进入EntryList BLOCKED,Thread-2 执行完同步代码块的内容,然后唤醒 EntryList 中等待 的线程来竞争锁,竞争的时是非公平的,WaitSet 中的 Thread-0,Thread-1 是之前获得过锁,但条件不满足进入  WAITING 状态的线程。其实wait/notify等方法也依赖于monitor对象,这就是为什么只有在同步的块或者方法中才能调 用wait/notify等方法,否则会抛出java.lang.IllegalMonitorStateException的异常的原因。
点赞 回复
分享
发布于 2022-06-07 23:16
5.Lock和Synchronized区别: 1).synchronized是一个关键字而lock是一个接口(lock、lockInterruptibly、tryLock、unlock、newCondition)。 2).synchronized是隐式的加锁,lock是显示的加锁。 3).synchronized可以作用在方法和代码块上,而lock只能作用在代码块上。 synchronized作用在静态方法上锁的是当前类的class,作用在普通方法上锁的是当前类的对象。 在javap反编译成字节码后,synchronized关键字需要有一个代码块进入的点monitorenter,代码块退出和代码块异常的出口点monitorexit。 4).synchronized是阻塞式加锁,而lock中的trylock支持非阻塞式加锁。 5).synchronized没有超时机制,而lock中的trylcok可以支持超时机制。 6).synchronized不可中断,而lock中的lockInterruptibly可中断的获取锁。(ReentrantLock.lockInterruptibly允许在等待时由其它线程调用等待线程的Thread.interrupt方法来中断等待线程的等待而直接返回,这时不用获取锁,而会抛出一个InterruptedException。ReentrantLock.lock方法不允许Thread.interrupt中断,即使检测到Thread.isInterrupted,一样会继续尝试获取锁,失败则继续休眠。只是在最后获取锁成功后再把当前线程置为interrupted状态,然后再中断线程) 7).synchronized采用的是monitor对象监视器,lock的底层原理是AQS(抽象队列式同步器) 8).synchronized只有一个同步队列和一个等待队列,而lock有一个同步队列,可以有多个等待队列。 同步队列:排队取锁的线程所在的队列。等待队列:调用 wait 方法后,线程会从同步队列转移到等待队列 9).synchronized是非公平锁,而lock可以是公平锁也可以是非公平锁 10).synchronized用object的notify方法进行唤醒,而lock用condition进行唤醒 11).lock有ReadWriteLock支持并发读
点赞 回复
分享
发布于 2022-06-07 23:17
6.AQS实现:AQS全称为AbstractQueuedSynchronizer,翻译过来就是抽象队列同步器。AQS是一个用来构建锁和其他同步组件的基础框架,使用AQS可以简单且高效地构造出应用广泛的同步器,例如我们后续会讲到的ReentrantLock、Semaphore、ReentrantReadWriteLock和FutureTask等等。AQS核心思想是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制AQS是用CLH队列锁实现的,即将暂时获取不到锁的线程加入到队列中。CLH(Craig,Landin,and Hagersten)队列是一个虚拟的双向队列(虚拟的双向队列即不存在队列实例,仅存在结点之间的关联关系)。AQS是将每条请求共享资源的线程封装成一个CLH锁队列的一个结点(Node)来实现锁的分配。AQS中的共享资源是使用一个int成员变量来表示同步状态,通过内置的FIFO队列来完成获取资源线程的排队工作。AQS使用CAS对该同步状态进行原子操作实现对其值的修改。状态信息通过procted类型的getState,setState,compareAndSetState进行操作。
点赞 回复
分享
发布于 2022-06-07 23:19
7.锁优化:锁优化的思路和方法1)减少锁持有时间,只需要在有线程安全要求的程序代码上加锁,能锁区块就不锁方法体,能用对象锁就不用类锁。2)减小锁粒度,将大对象(这个对象可能会被很多线程访问),拆成小对象,大大增加并行度,降低锁竞争。降低了锁的竞争,偏向锁,轻量级锁成功率才会提高,例如ConcurrentHashMap。3)锁分离,最常见的锁分离就是读写锁ReadWriteLock,根据功能进行分离成读锁和写锁,这样读读不互斥,读写互斥,写写互斥。即保证了线程安全,又提高了性能。4)锁粗化,通常情况下,为了保证多线程间的有效并发,会要求每个线程持有锁的时间尽量短,即在使用完公共资源后,应该立即释放锁。只有这样,等待在这个锁上的其他线程才能尽早的获得资源执行任务。但是,凡事都有一个度,如果对同一个锁不停的进行请求、同步和释放,其本身也会消耗系统宝贵的资源,反而不利于性能的优化。5)锁消除,在即时编译器时,如果发现不可能被共享的对象,则可以消除这些对象的锁操作。这些锁并不是程序员所写的,有的是JDK实现中就有锁的,比如Vector和StringBuffer这样的类,它们中的很多方法都是有锁的。当我们在一些不会有线程安全的情况下使用这些类的方法时,达到某些条件时,编译器会将锁消除来提高性能。 8.CMS: CMS全称Concurrent marke sweep,中文是并发标记清除算法。CMS出现的目的是:尽可能的减少STW(stop the world)的时间。CMS工作分7步,分别是:1、初始标记;2、并行标记; 3、预清理;4、可终止预清理;5、重新标记;6、并发清理 7、并发重置。缺点:收集的堆会产生空间碎片,需要更多的CPU资源和堆空间。应用场景:应用程序对停顿比较敏感,老年对象比较多,同时应用程序运行在较大资源CPU和较大的堆的情况下使用。
点赞 回复
分享
发布于 2022-06-07 23:19
9.ReentrantLock与AQS同步框架: 对于ReentrantLock来说,其执行逻辑如下所示: 1):尝试获取锁的对象,如果获取不到(意味着其它线程已经持有了锁,尚未释放),那么它就会进入到AQS的阻塞队列中 2):如果获取到,根据锁是公平锁还是非公平锁来进行不同的处理,如果是公平锁,线程会直接放到AQS阻塞队列的末尾,如果是非公平锁,那么会尝试进行cas计算,如果成功,则会直接获取到锁,如果失败,则与公平锁的处理方式一样 3):当锁被释放时(调用了unlock方法),那么底层会调用release方法对state进行减1操作,如果减1后,state值不为0,则release操作就执行完毕,如果减1操作后,state值为0,则调用LockSupport的unpark方法唤醒该线程后等待队列中的第一个后继线程,使之能够获取到对象的锁(release时,对于公平锁和非公平锁处理逻辑都是一致的),之所以调用release方法后state值不为0,原因在于ReentrantLock是可重入锁,表示线程可以多次调用lock方法,state值都会加1 4):对于ReentrantLock来说,所谓的上锁,就是对AQS中state成员变量加1,释放锁就是对state减1
点赞 回复
分享
发布于 2022-06-07 23:21
10.CAS原理:CAS的全称是: Compare And Swap(比较相同再交换)。是现代CPU广泛支持的一种对内存中的共享数据进行操作的一种特殊指令。CAS的作用:CAS可以将比较和交换转换为原子操作,这个原子操作直接由CPU保证。CAS可以保证共享变量赋值时的原子操作。CAS操作依赖3个值:内存中的值V,旧的预估值X,要修改的新值B,如果旧的预估值X等于内存中的值V,就将新的值B保存到内存中。 通过AtomicInteger的源码我们可以看到,Unsafe类提供了原子操作方法getAndAddInt。Unsafe类使Java拥有了像C语言的指针一样操作内存空间的能力,同时也带来了指针的问题。过度的使用Unsafe类会使得出错的几率变大,因此Java官方并不建议使用的,官方文档也几乎没有。Unsafe对象不能直接调用,只能通过反射获得。 悲观锁从悲观的角度出发: 总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞。因此synchronized我们也将其称之为悲观锁。JDK中的ReentrantLock也是一种悲观锁。性能较差! 乐观锁从乐观的角度出发: 总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,就算改了也没关系,再重试即可。所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去修改这个数据,如何没有人修改则更新,如果有人修改则重试。CAS这种机制我们也可以将其称之为乐观锁。综合性能较好! CAS获取共享变量时,为了保证该变量的可见性,需要使用volatile修饰。 结合CAS和volatile可以实现无锁并发,适用于竞争不激烈、多核 CPU 的场景下。 1. 因为没有使用 synchronized,所以线程不会陷入阻塞,这是效率提升的因素之一。 2. 但如果竞争激烈,可以想到重试必然频繁发生,反而效率会受影响。 CAS的compareAndSwap方法原理: CAS需要3个值:主内存中的当前值V,主内存中旧的快照值A,要修改的新值B,如果当前内存地址V值和旧的快照值A相等就修改内存地址的值为B,不一致就不会写入。
点赞 回复
分享
发布于 2022-06-07 23:22
11.springboot 和 spring 的区别是什么: 1)Spring Boot提供极其快速和简化的操作,让 Spring 开发者快速上手。 2)Spring Boot提供了 Spring 运行的默认配置。 3)Spring Boot为通用 Spring项目提供了很多非功能性特性,例如:嵌入式 Serve、Security、统计、 4)以下是Spring Boot的一些功能:持约定优于配置的“starter”依赖关系,以简化构建和应用程序配置,嵌入式服务器避免了应用程序部署的复杂性度量、运行状况检查和外部化配置,自动配置-只要可能。 12.spring中bean的初始化过程: Spring Bean 的初始化主要实现在bean.factory包下的AbstractAutowireCapableBeanFactory类中 具体实现流程为这个类里的三个初始化流程,分别为: 1)实例化createBeanInstance【里面包含了推断构造方法,简单来说就是对bean进行实例化】 2)属性赋值populateBean 【填充属性,处理@AutoWried,调用bean的实例化后的方法】 3)Bean的初始化initializeBean【调用bean的初始化方法】, 同时initializeBean前后还会对aware进行调用处理【BeanNameAware、BeanClassLoaderAware、BeanFactoryAware】和【EnvironmentAware、ApplicationContextAware(BeanPostProcessor before)】,之后调用【invokeInitMethods 就是initializeBean的流程】,之后会调用一次【BeanPostProcessor的另一个调用点 after】 4.DisposableBean 生命周期的销毁, ConfigurableApplicationContext#close()方法作为入口,实现是通过循环取所有实现了DisposableBean接口的Bean然后调用其destroy()方法
点赞 回复
分享
发布于 2022-06-07 23:24
13.Spring IpC 和AOP:IoC: Inversion of Control (控制反转/反转控制),它是一个技术思想而不是一个技术实现,在Java开发领域他所描述的事情是对象的创建和管理的问题。与传统开发方式相比在IOC的思想开发方式下,当类A需要以来类B时,我们不要自己去new对象了,而是由IOC容器帮我们实例化对象并且去管理它,我们需要什么对象直接从IOC容器中获取即可,由此我们可以省去创建和管理对象的一系列事情,也丧失了创建、管理对象的权力。 控制反转解释:控制:指的是对象创建(实例化、管理)的权利,反转:控制权交给外部环境了(spring框架、IoC容器) IoC解决对象之间的耦合问题,例如当service层调用dao层时,传统方式下我们需要在service中new出dao层的具体实现类,这时当我们实现类需要改变时,service层也需要做相应的改变,这就造成了service层和dao层的强耦合。而使用IOC实例化对像时,我们只需要关注调用的dao层的接口,在service中声明接口属性,具体的实现类在IOC容器中进行切换,因此也不会产生对象中强耦合的情况 AOP: Aspect oriented Programming 面向切面编程,AOP是OOP的延续。 OOP的三大特征: 封装、继承和多态,让原有的类继承顶级父类,这样子类中就可以不再重复写这些共有方法了,同样子类下的子类依然可以通过继承父类来避免代码的重复。但是当顶级父类中的多个方法中的相同位置出现重复代码时,OOP的思想就无法解决了。此时我们就需要用到AOP的思想了。 首先解释此类重发代码被称为“横切逻辑代码”,即在多个纵向(顺序)流程中出现的多个相同子流程代码。此类代码的使用场景通常有:性能监控、事务控制、权限校验和打印日志中。
点赞 回复
分享
发布于 2022-06-07 23:35
14.Arrays.sort()方法底层原理: 1) 进入Arrays.sort()方法 2) 进入DualPivotQuicksort类内部的静态方法sort 3)走sort的流程 3.1. 排序范围小于286的数组使用快速排序 3.2. 进入sort方法,判断数组长度是否小于47,小于则直接采用插入排序,否则执行3。 3.3. 用公式length/8+length/64+1近似计算出数组长度的1/7。 3.4. 取5个根据经验得出的等距点。 3.5.将这5个元素进行插入排序 3.6. 选取a[e2],a[e4]分别作为pivot1,pivot2。由于步骤5进行了排序,所以必有pivot1 <=pivot2。定义两个指针less和great,less从最左边开始向右遍历,一直找到第一个不小于pivot1的元素,great从右边开始向左遍历,一直找到第一个不大于pivot2的元素。 3.7. 接着定义指针k从less-1开始向右遍历至great,把小于pivot1的元素移动到less左边,大于pivot2的元素移动到great右边。这里要注意,我们已知great处的元素小于pivot2,但是它于pivot1的大小关系,还需要进行判断,如果比pivot1还小,需要移动到到less左边,否则只需要交换到k处。 3.8. 将枢轴交换到它们的最终位置 3.9. 递归排序左右部分,不包括已知的枢轴 3.10. 对于中间的部分,如果大于4/7的数组长度,递归中间部分
点赞 回复
分享
发布于 2022-06-07 23:46
15.索引优化原则:1)全值匹配,查询语句尽量使用全值匹配。2)左前缀原则,如果一个索引是组合索引,索引了多列,要遵循左前缀原则,即查询从索引的左前缀开始,不能跳过索引中间的列。3)不要在索引列上操作,操作包括:计算、函数、自动或手动的类型转换,不要在索引列上做上述任何操作,否则索引失效并转为全表扫描。4)范围条件右边的列索引全失效,当组合索引中出现范围条件,那么该范围条件右边的列索引全部失效,例如not in,in > ,<。因此在设计和使用索引时,应把经常进行范围查询的列作为索引的最右列。5)按需取数据,少用select ***,在查询中少用select *,否则MySQL需要遍历结果列存在哪些字段。同时,应尽量使用覆盖索引,能避免二次查表。6)避免使用 != 或 <>,在使用不等于(!= 或 <>)时,无法使用索引,导致全表扫描。7)避免is null 或 is not null,判断空值的查询条件索引失效,导致全表扫描。8)避免like以通配符开头,查询条件like以通配符%开头,如 name like ("%abc"),索引失效,导致全表扫描,XXX%右模糊查询是可以使用索引的。那么如果业务需要必须要用通配符%开头怎么办?答案是:使用覆盖索引(覆盖索引是select的数据列只用从索引中就能够取得,不必读取数据行,换句话说查询列要被所建的索引覆盖)。
点赞 回复
分享
发布于 2022-06-08 00:59
15.索引优化原则:9)少用or,使用or来连接查询条件时,索引失效。10)尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可,建立不必要索引会增加MySQL空间。11)如果确定有多少条数据,使用 limit 限制一下,MySQL在查找到对应条数的数据的时候,会停止继续查找。12)join 语法,尽量将小的表放在前面,在需要on的字段上,数据类型保持一致,并设置对应的索引,否则MySQL无法使用索引来join查询。13)=和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式。14)字段类型不匹配,常见的隐式数据类型转换,mobile=1356不会走索引,会转换为字符串可以查询但是,mobile='1356'会走索引。
点赞 回复
分享
发布于 2022-06-08 01:00
16)为什么mysql要使用B+树:一、首先我们的一个表的数据在磁盘上由于插入顺序的原因肯定不是顺序存放,如果按照表字段内容顺序查找,如果一个500万条数据的表,要找的刚好是第500万个值,则需要与磁盘做500万次IO,效率低下。二、为什么不用二叉树,如果将一个乱序的数据放入二叉树中,效率会高,但是如果数据是有顺序的,比如1、2、3、4、5,则二叉树将会编程一个链表的样式,失去了二叉树的优势。三、为什么不用红黑树,红黑树也叫二叉平衡树,红黑树可以有效解决掉顺序数据一次放入二叉树而导致的形成链表的结果,但是红黑树一个节点只能存储一个数据,就导致如果是大量的数据,红黑树的高度就不可控,如果一个红黑树是20的高度,要查询的数据在叶子结点,则表示需要需磁盘20次IO,效率还是不高。四、为什么不用B树,B树比红黑树的优势是,B树是一个节点上存储多个数据,比如磁盘的一页数据,这样的横向扩展,相同的数据量就可以比红黑树减少更多的高度,从而减少了磁盘的IO次数,下面开始对比B树和B+树,就会发现B+树在查询数据方面要比B树有很多便捷的地方 B树:data为数据的磁盘地址,还可能是整条列的数据 1、数据是分散在每个结点上的,所有结点元素不重复, 2、结点元素从左到右递增 3、叶子结点具有相同的深度,叶子结点的指针为空 B+树:data为数据的磁盘地址,还可能是整条列的数据 1、叶子结点包含了所有的索引字段,以及数据的磁盘地址,而非叶子结点不在存储data数据,作用只是便于查找的冗余索引 2、非叶子结点是从子结点选取一页的开头来作为自己的值,指针为子结点那页的地址 3、每一个结点里的值都是排好序的 4、叶子结点之间还有指针可以互相访问,这样方便了范围查找,比如where col > 10,这是mysql对B+的变种,也是对比B树的一个优势 5、由于data可能会很大,非叶子结点在不存储data后,非叶子可以存储的元素则会变多,还可以降低树的高度,提高了查询的效率,这是与B树对比,B+树的一个优势 (注:内存里二分查找数据的范围要比一个IO快的多,所以一次IO加载更多的数据,可以提高查询的效率,一页为多大也可以sql查询与设置)
点赞 回复
分享
发布于 2022-06-08 01:09
17.Innodb 和 Myisam 的区别:一:存储引擎:InnoDB和MyISAM的区别 1、InnoDB支持事务,MyISAM不支持,这一点是非常之重要。事务是一种高级的处理方式,如在一些列增删改中只要哪个出错还可以回滚还原,而MyISAM就不可以了。 2、MyISAM适合查询以及插入为主的应用,InnoDB适合频繁修改以及涉及到安全性较高的应用 3、InnoDB支持外键,MyISAM不支持 4、MyISAM是默认引擎,InnoDB需要指定 5、InnoDB不支持FULLTEXT类型的索引 6、InnoDB中不保存表的行数,如select count(*) from table时,InnoDB需要扫描一遍整个表来计算有多少行,但是MyISAM只要简单的读出保存好的行数即可。注意的是,当count(*)语句包含where条件时MyISAM也需要扫描整个表 7、对于自增长的字段,InnoDB中必须包含只有该字段的索引,但是在MyISAM表中可以和其他字段一起建立联合索引 8、清空整个表时,InnoDB是一行一行的删除,效率非常慢。MyISAM则会重建表 9、InnoDB支持行锁(某些情况下还是锁整表,如 update table set a=1 where user like '%lee%&(29400)#39; 二:存储引擎:InnoDB和MyISAM的比较 MyISAM存储引擎: 优点:查询数据相对较快,适合大量的select,可以全文索引。 缺点:不支持事务,不支持外键,并发量较小,不适合大量update InnoDB存储引擎: 优点:支持事务,支持外键,并发量较大,适合大量update 缺点:查询数据相对较面,不适合大量的select【影响速度的主要原因是AUTOCOMMIT默认设置是打开的】
点赞 回复
分享
发布于 2022-06-08 01:14
18.为什么不用哈希索引: 1)Hash索引仅仅能满足“=”,“IN”,不能支持范围查询 2)对于排序操作Hash索引也满足不了 3)Hash索引不能避免表扫描 4)当有大量数据的Hash值相等的时候Hash索引的性能大打折扣
点赞 回复
分享
发布于 2022-06-08 01:17
19.事务的隔离级别有以下几种: 1、第一种隔离级别:Read uncommitted (读未提交) 一个事务在写数据时,不允许另外一个事务进行写操作,但允许读操作。这样避免了更新丢失,却可能出现脏读,也就是说(事务A读到了事务B未提交的数据,事务B修改了内容后,又进行了回滚,那么此时事务A读取到的数据就成为了脏数据)。 解决了更新丢失,但还是可能会出现脏读。 2、第二种隔离级别:Read committed (读提交) 写事务提交之前不允许其他事务的读操作,可以解决脏读问题。但会出现一个事务范围内两个相同的查询却返回了不同数据(事务A,读取了数据后,事务B修改了数据并进行了提交,那么此时事务A再次读取时,就会出现数据不一致的情况),这就是不可重复读。 解决了更新丢失和脏读问题,但是可能出现不可重复读。 3、第三种隔离级别:Repeatable read(可重复读) 在开始读取数据(事务开启)时,不再允许修改操作,这样就可以在同一个事务内两次读到的数据是一样的,因此称为是可重复读隔离级别,但是有时可能会出现幻读。 (事务在操作过程中进行两次查询,第二次查询的结果包含了第一次查询中未出现的数据或者缺少了第一次查询中出现的数据(这里并不要求两次查询的SQL语句相同)。 这是因为在两次查询过程中有另外一个事务插入数据造成的。) 解决了更新丢失、脏读、不可重复读、但是还会出现幻读。 4、第四种隔离级别:Serializable(可序化) 要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行,如果仅仅通过“行级锁”是无法实现序列化的,必须通过其他机制保证新插入的数据不会被执行查询操作的事务访问到。 序列化是最高的事务隔离级别,同时代价也是最高的,性能很低,一般很少使用,在该级别下,事务顺序执行,不仅可以避免脏读、不可重复读,还避免了幻读。
点赞 回复
分享
发布于 2022-06-08 01:21
20.innodb行锁的实现 1)innodb的行锁是通过给索引的索引项加锁来实现的 2)innodb按照辅助索引进行数据操作时,辅助索引和主键索引都将锁定指定的索引项 3)通过索引进行数据检索时,innodb才使用行级锁,否则innodb将使用表锁
点赞 回复
分享
发布于 2022-06-08 01:27
21.MySQL分页方法  MySQL的分页似乎一直是个问题,有什么优化Mysql分页方法吗?下面总结了一些Mysql分页方法 方法1:直接使用数据库提供的SQL语句   语句样式:MySQL中,可用如下方法:SELECT * FROM 表名称 LIMIT M,N。   适应场景:适用于数据量较少的情况(元组百/千级)。   原因/缺点:全表扫描,速度会很慢 且 有的数据库结果集返回不稳定(如某次返回1,2,3,另外的一次返回2,1,3)。Limit限制的是从结果集的M位置处取出N条输出,其余抛弃。 方法2:建立主键或唯一索引,利用索引(假设每页10条),语句样式:MySQL中,可用如下方法:   代码如下:SELECT * FROM 表名称 WHERE id_pk > (pageNum*10) LIMIT M。   适应场景:适用于数据量多的情况(元组数上万)。   原因:索引扫描,速度会很快。有朋友提出因为数据查询出来并不是按照pk_id排序的,所以会有漏掉数据的情况,只能方法3。 方法3:基于索引再排序   语句样式:MySQL中,可用如下方法:SELECT * FROM 表名称 WHERE id_pk > (pageNum*10) ORDER BY id_pk ASC LIMIT M。   适应场景:适用于数据量多的情况(元组数上万). 最好ORDER BY后的列对象是主键或唯一所以,使得ORDERBY操作能利用索引被消除但结果集是稳定的(稳定的含义,参见方法1)。   原因:索引扫描,速度会很快. 但MySQL的排序操作,只有ASC没有DESC(DESC是假的,未来会做真正的DESC,期待)。 方法4:基于索引使用prepare(第一个问号表示pageNum,第二个表示每页元组数)   语句样式:MySQL中,可用如下方法:   代码如下:   PREPARE stmt_name FROM SELECT * FROM 表名称 WHERE id_pk > (?* ?) ORDER BY id_pk   ASC LIMIT M。   适应场景:大数据量。   原因:索引扫描,速度会很快. prepare语句又比一般的查询语句快一点。
点赞 回复
分享
发布于 2022-06-08 01:34
22.索引为什么查找快: 使用索引的好处:         创建索引可以大大提高系统的性能。第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因。第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。第四,在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。 索引的原理: 数据在磁盘上是以块的形式存储的。为确保对磁盘操作的原子性,访问数据的时候会一并访问所有数据块。磁盘上的这些数据块与链表类似,即它们都包含一个数据段和一个指针,指针指向下一个节点(数据块)的内存地址,而且它们都不需要连续存储(即逻辑上相邻的数据块在物理上可以相隔很远)。 鉴于很多记录只能做到按一个字段排序,所以要查询某个未经排序的字段,就需要使用线性查找,即要访问N/2个数据块,其中N指的是一个表所涵盖的所有数据块。如果该字段是非键字段(也就是说,不包含唯一值),那么就要搜索整个表空间,即要访问全部N个数据块。 然而,对于经过排序的字段,可以使用二分查找,因此只要访问log2 N个数据块。同样,对于已经排过序的非键字段,只要找到更大的值,也就不用再搜索表中的其他数据块了。这样一来,性能就会有实质性的提升。
点赞 回复
分享
发布于 2022-06-08 01:45

相关推荐

8 56 评论
分享
牛客网
牛客企业服务