设计模式
面对对象三大特性封装、继承、多态
UML图
继承关系父子继承
实现接口实现接口
关联关系
聚合关系弱包含关系,B可以不是A的一部分
组合关系强包含关系,B是A的一部分
依赖关系强耦合
六大设计原则单一职责原则:一个类只负责一个功能
开放-封闭原则:对于拓展开放、对于更改封闭,只对需要频繁修改的那部分抽象(抽象类)
依赖倒转原则:细节依赖抽象(面向接口编程)
里氏代换原则:子类可以替换其父类,这让开放-封闭原则成为可能
迪米特法则:前提是类封装的思想,强调类间的松耦合
创建型模式隐藏创建类对象的过程,体现高内聚、低耦合
工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式
简单工厂模式比如要实现一个计算器功能,我们用 switch 或者 if 根据符号来判断用哪个工厂生成答案,如果需要增加复杂的运算,只需要 switch 多加一个选择,多加一个工厂类就可以了
工厂模式工厂模式是对简单工厂模式的抽象和拓展,每个产品都有相对应的工厂,避免了修改源代码(switch加分支)破坏开放-封闭原则,但是却需要增加产品类和工厂类
抽象工厂模式每个工厂可以生产不止一种产品,而是同一系 ...
spring源码
一些阅读的总结阅读源码的时候利用好断点和堆栈来 debug
思考一些常用功能(如 xml 或 注解 自动装配、根据名字或类型如何获取 bean)是如何实现的
Spring 使用了大量的设计模式,如模板模式
Spring 使用组合大于继承,一个类可能包含很多其他类或接口
注意一些关键的类就可以大致了解 Spring 的功能
由于途中会经常的使用 BeanDefinition,调试的时候在 RootBeanDefinition 的构造器打上断点
待解决的问题IoC是什么?
我们通常理解的IoC就是存储bean的容器,实际上IoC的本意是反转控制(把bean的管理交给Spring实现),存储bean的容器实际上是Spring框架里面的一个成员变量map<beanName, bean>
DI 依赖注入,是bean管理中的一个重要的环节,当初始化的注入属性环节需要使用,涉及到循环依赖问题的解决
优点:代码解耦(不用自己new),单例模式(如果需要),不用关注创建的细节(属性注入)
实现:从 xml 文件或者通过@xxx注解方式将bean注入到IOC容器内(一个HashMap,< ...
Sharding-JDBC
分库分表的几种方式垂直分表、垂直分库、水平分表、水平分库
垂直分表按照字段拆分,增加页内能存储的的行数据来减少IO的次数,以及减少对行锁竞争
垂直分库按照业务拆分,减少业务间的耦合,转库专用,不同业务的库可以部署在不同服务器减少对硬件资源的压力
水平分库解决单库数据量大问题,把单库数据平摊到多个库,可以用ID取模或者hash确定数据在哪个数据库,减小单库的压力
和垂直分库对比
垂直分库是根据业务把不同业务的表拆分到不同数据库
水平分库是把相同业务的表复制一份到不同数据库
水平分表解决单表数据量大问题,把单表数据平摊到多个表,减小单表数据量,减少IO
总结在系统设计的时候,就要根据需求,设计好垂直分库分表
在业务上线后,如果数据量增大,先考虑用缓存、读写分离、索引等方式优化,如果业务数据量持续增大,再考虑用水平分库分表
分库分表带来的一些问题事务一致性问题需要操作多个数据库的时候,需要分布式事务
跨界点关联查询由于表在不同数据库内,在写SQL语句的时候无法通过联表查询
跨节点分页、排序函数由于表在不同数据库内,在写SQL语句的时候需要查询多次,在内存中排序
主键避重不同数据库主键重复问 ...
leetcode
年度回顾力扣 Rewind’23 - 年度回顾 (leetcode.cn)
数组一维除自身以外数组的乘积238. 除自身以外数组的乘积 - 力扣(LeetCode)
12345678910111213141516171819public int[] productExceptSelf(int[] nums) { int len = nums.length; int[] ans = new int[len]; // 数组的含义是当前位置左边或者右边的乘积 int[] L = new int[len]; int[] R = new int[len]; L[0] = 1; for (int i = 1; i < len; i++) { L[i] = L[i - 1] * nums[i - 1]; } R[len - 1] = 1; for (int i = len - 2; i >= 0; i--) { R[i] = R[i + 1] * num ...
tomcat如何打破双亲委派模型
Tomcat是如何打破”双亲委派”机制的?-阿里云开发者社区 (aliyun.com)
(25 封私信 / 80 条消息) Tomcat为什么要JAVA破坏双亲委派机制? - 知乎 (zhihu.com)
1.5 tomcat是如何打破双亲委派机制的?-腾讯云开发者社区-腾讯云 (tencent.com)
tomcat为什么要打破双亲委派模型tomcat是一个web容器,里面可以部署很多应用程序app,每个app都可以依赖不同版本的第三方类库,根据双亲委派模型,可能导致冲突
tomcat如何打破双亲委派模型
tomcat自定义的类加载器
Common ClassLoader:web容器和app共有的类库,避免重复类加载
Catalina ClassLoader:web容器私有的类库,避免冲突
App的类库
ShareClassLoader:app之间共有的类库,避免重复类加载
WebAppClassLoader:app私有的类库,避免冲突
重写loadClass()loadClass()
先判断是否类被父加载器加载过了,避免加载到核心类(比如String)造 ...
简单了解HashMap和ConcurrentHashMap
MapHashMapjdk1.7与jdk1.8的区别
底层数据结构,jdk1.7为数组 + 链表,jdk1.8为数组 + 链表 + 红黑树
链表添加元素的位置,jdk1.7为头插法(循环引用问题),jdk1.8为尾插法
对于key==null的处理,jdk1.7为添加前独立判断,jdk1.8为综合到hash()函数里面
先添加再扩容还是先扩容再添加。jdk1.7为先扩容再添加,jdk1.8为先添加再扩容
hash()函数的异或次数,jdk1.7为4次,jdk1.8为1次(高16位和低16位异或)
jdk1.8要比jdk1.7多一步考虑红黑树的操作
比如插入考虑树化,删除考虑反树化,查找考虑树的递归查找
扩容的时候会把每个索引位置后边的链表或者红黑树都拆分成两个部分(i、i + oldcap),比如 1 和 17 在容量为 16 的hashmap都是在索引为1的位置,扩容后 1 还是在索引为 1 的位置,但是 17 到了索引为 17 的位置
jdk1.7实现底层是数组 + 链表
123456static class Entry<K,V> implem ...
git
git 结构工作区:电脑文件夹目录
版本库:.git文件夹,git add 添加到暂存区stage,git commit 添加到本地分支
1git checkout -- test.txt // 用暂存区的代替工作区的
git 分支操作看到分支合并图
1git log --graph
提交代码
1git commit -m "本次提交的代码功能概括"
创建分支
1git branch bugFix
切换分支
1git checkout bugFix
合并分支
1.merge:拿过来
把bugFix分支的所有提交合并到本分支
1git merge bugFix
2.rebase:放过去(线性的提交历史)
把当前分支的所有提交合并到main分支
1git rebase main
3.cherry-pick:拿你想要部分提交的拿过来
1git cherry-pick c1
HEAD
可以指向分支或者提交过的节点
12HEAD^ 往上一个提交HEAD~n 往上n个提交
修改分支节点的位置
12git branch -f 待修改分支 ...
tomcat和dubbo的线程池
本文主要探讨tomcat线程池以及dubbo线程池和JDK原生线程池的区别
SpringBoot内置tomcat线程池的实现类1org.apache.catalina.core.StandardThreadExecutor
初始化方法startInternal()
1234567891011121314151617181920protected void startInternal() throws LifecycleException { // 创建一个任务队列,容量为Integer.MAX_VALUE // TaskQueue继承了LinkedBlockingQueue this.taskqueue = new TaskQueue(this.maxQueueSize); // 线程工厂 TaskThreadFactory tf = new TaskThreadFactory(this.namePrefix, this.daemon, this.getThreadPriority()); // new一个tomcat自定义的Th ...