2026/6/9

发布时间:2026/7/16 23:55:21
2026/6/9 嚼嚼嚼。事务拦截器MySQL关键字where和having数据库索引和常见类型还是隔离级别hashmap底层原理扩容机制jdk1.7数组链表jdk1.8之后用数组链表红黑树hashmap为啥重写equals时必须重写hashcode一个hashcode用来找桶equals用来判断同一桶里多个元素是否为同一个key。反正就是hashcode用来找桶equals用来桶内判等。如果只改equals不改hashcode相等对象进不同桶存取全部错乱。多线程之线程创建啊吧啊吧闹心了。这回直接写吧。线程一共三种创建方式1.继承thread类并重写run方法这种就是很简单啊直接调start就启动了。如果在run方法内可以直接用this获取线程对象不然你就嘚用Thread.currentThread。Thread.currentThread.getName这个直接获取名字啦到时候输出调试的时候也能用上。不过这种创建方式的缺点呢就是java是单继承的继承Thread后不能继承其他父类了扩展性很差当任务和线程耦合在一起的时候多个线程执行同一任务无法复用。2.实现Runnable接口并重写run方法这个是接口实现的接口可以多接口任务和线程是分离的同一个Runnable对象可以交给多个线程执行资源共享。适合多线程处理同一任务。他有个缺点就是没有返回值、不能抛出受检异常。3.实现CallableFutureTask有返回、抛异常优点是线程任务有返回值任务内可以抛出checked受检异常。同样解耦任务与线程支持多线程复用任务。缺点是写法很繁琐需要FutureTask包装get()获取子线程执行结束后的返回值后会阻塞主线程。就是那个FutureTask.get()。sleep()和wait()的区别sleep()和wait()所属的类是不同的。sleep()是Thread类静态方法wait()是Object类实例方法所有对象都有。sleep()和wait()的锁行为不一样。sleep休眠时不释放持有的同步锁其他线程无法进入同步块wait调用后立刻释放当前对象锁让其他线程竞争该锁。sleep()和wait()唤醒条件也不一样。sleep时间到自动苏醒中途不能被其他线程唤醒。抛出InterruptedException可打断休眠wait有三种唤醒方式1.等待时长结束自动醒wait(long)2.其他线程调用notify()随机唤醒一个处于WATING的线程3.其他线程调用notifyAll()唤醒全部无超时参数wait()会无限阻塞使用场景限制wait()/notify()/notifyAll()必须写在synchronized同步代码块/同步方法内否则抛出异常。sleep()无同步锁要求任意地方都能调用。状态sleep线程进入TIMED_WAITINGwait线程进入WAITNG/TIMED_WAITING设计目的sleep单纯让当前线程暂停一段时间不涉及线程间通信wait多线程协作、生产者消费者模型线程间等待通知还是索引创建joinSQL – 连接(内连接左连接右连接和全连接)|极客教程Mybatis一级缓存二级缓存我将用最直白最简洁的方式来说说mybatis一级缓存二级缓存。一级缓存是本地缓存默认自动开启的。只在同一个SqlSession里失效。简单说在一次数据库会话中重复查相同条件的数据不会重复访问数据库。一次会话里在第一次查的时候结果就存进一级缓存了再查的时候直接从缓存里拿数据不访问库。但是会话间是不共享的a会话查的东西b会话查不到缓存清空/失效1.同一张表执行insert/update/delete2.手动调用sqlSession.clearCache()清空缓存3.关闭/重新创建会话二级缓存是Mapper缓存默认关闭需要手动打开。同一个Mapper映射文件跨SqlSession共享缓存。就是同一个Mapper所有会话共享。缓存清空/失效1.都这个mapper下任意数据做增删改缓存全部清空二级缓存开启1.全局配置开启二级缓存总开关2.在对应Mapper.xml里加cache/3.实体类实现Serializable序列化接口执行顺序先看二级缓存有没有数据-没有再看一级缓存-还没有就查数据库java反射正常咱们进行操作嘚知道用的哪个类里的代码知道哪个类就创建这个类的对象直接调用方法。java反射你不提前知道这个类是啥但是在程序运行的时候它能反向找着那个类创建那个类的对象调用方法读写属性。是怎么实现的Java的每个类都自带一个class对象程序一运行的时候JVM自动给它生成一个唯一的户口本。这里面包含着这个以下信息这个类叫啥名儿里头有啥变量有哪些方法构造器是谁。这个户口本儿就是反射的根本第一步是要先拿到这个类的户口本使用类名.class直接拿然后第2种就是new类名().get class通过这个类的实例然后来拿户口本第3种就是class.forName后头接上接收一个完整类名输入它的类的名字加载类拿到户口本。平时大多数用的都是第3种方式然后第二步呢就是拿着你这个户口本调取里边所有的信息爱咋操作咋操作这个里头有所有的字段所有的方法还有构造方法。你如果是想调取构造器的话就可以凭空的造出来这个类对象如果想要调用成员方法就可以执行这个方法如果调取成员变量就读取修改变量的值就算你哪怕是私有private的内容加一句setAccessible(true)就可以跳过权限锁照样能访问嗯也就是说你普通的代码你在编译阶段的时候就把类方法都绑定死了。而这个反射呢在运行期间依靠class户口本动态地调取读取类的全部的元数据动态给执行操作索引失效嗯首先什么是索引失效索引失效就是你建了索引但是你Mysql没去用索引是用的全表扫描。这就是索引失效会导致你查询速度很慢索引失效的条件第一个就是索引字段他参与了计算调用了函数。这种情况肯定会失效的。因为索引你存的是原始字段值如果加工的话索引匹配不到了那个值它变了第2种就是隐式类型转换嗯。字符串索引字段查询值不能加单引号数据库强制转换字段整体数据索引会作废。反正就是你不加单引号是不行的你如果不加单引号那就失效了你加单引号才有效第3种就是like通配符%出现在了最左侧。出现在最左侧左模糊的话索引就会失效。如果是右模糊的话索引还是可以用的。name LIKE %老王这个就是左模糊它就失效了。name LIKE 老王%这个是有模糊还是可以用的第4就是联合索引他违反了最左前缀原则。复合索引(a,b,c)查询条件没有最左列的a整个索引他就会失效你少了一个最左边的a它就失效了第5种就是OR条件一侧没有索引。一个字段有索引另外一个字段是没索引你还用all拼接的这个整体索引它就失效了。他就全表扫描了第6种是使用了否定运算符比如!,,NOT IN,IS NOT NULL。数据库判定符合条件数据越多优化器他就直接放弃索引了第7种是MySQL优化器主动放弃索引。查询结果占了整张表数据的20%到30%以上全表扫描的速度比索引速度更快所以它就直接放弃用索引了第8种就是使用order by字段没有遵循联合索引顺序。联合索引(a,b)查询a等于1排序b以外的字段索引是无法支持排序的第9种是字段设置成null大量的数据为空。索引对null支持差筛选is not null大概率失效如何自己检查索引是否失效EXPLAIN SELECT * FROM 表 WHERE 条件type列显示ALL 索引失效ref/range 索引正常MySQL InnoDB索引底层实现设计模式拦截器