同时设置:缓存ecache 和redis 缓存雪崩 设置单秒限流 UUID 不具有有序性 snowflack 雪花算法 用其中的 41 bit 作为毫秒数,用 10 bit 作为工作机器 id,12 bit 作为序列号
主库将变更写入 binlog 日志,然后从库连接到主库之后, 从库有一个 IO 线程,将主库的 binlog 日志 拷贝到自己本地, 写入一个 relay 中继日志中。 接着从库中有一个 SQL 线程会从中继日志读取 binlog, 然后执行 binlog 日志中的内容, 也就是在自己本地再次执行一遍 SQL,这样就可以保证自己跟主库的数据是一样的。
es 丢数据的问题,你可以在这里给面试官炫一把,你说,其实 es 第 一是准实时的,数据写入 1 秒后可以搜索到;可能会丢失数据的。 有 5 秒的数据,停留在 buffer、translog os cache、segment file os cache 中,而不在磁盘上,此时如果宕机,会导致 5 秒的数据丢失
rdb 对redis 对外提供读写服务,主线程只需要一个fork进程 让子线程执行磁盘IO操作来进行rdb的持久化。 这里有一个非常重要的一点,就是从库同步主库数据的过程是串行化的,也就是说主库上并行的操作,在从 库上会串行执行。所以这就是一个非常重要的点了,由于从库从主库拷贝日志以及串行执行 SQL 的特点, 在高并发场景下,从库的数据一定会比主库慢一些,是有延时的。 所以经常出现,刚写入主库的数据可能是 读不到的,要过几十毫秒,甚至几百毫秒才能读取到
cpu 调度权 分时调度系统和抢仓式调度系统 SynchronizedMap 一次锁住整张表来保证线程安全,所以每次只能有 一个线程来访为 map redis 队列优化 redis 分布式锁,基于zookper实现 分库 从业务角度来分库 从数据并发量来分库 并发支 撑情况 MySQL 单机 部署,扛不住 高并发
并发量 MySQL 从单机到多机,能承受的并发增加了多倍 磁盘使用量 磁盘使用情况 MySQL 单机 磁盘容量几 乎撑满 拆分为多个库,数据库服务器磁盘使用率大大降低 SQL 执行性能 单表数据量太大, SQL 越跑越慢 单表数据量减少,SQL 执行效率明显提升
mysql的半同步复制和并行复制 一个是半同步复制,用来解决主库数据丢失问题: how ? semi-sync复制 ACK 确认 指的就是主库写入 binlog 日志之后,就会将强制此时立即将数据同步到从库, 从库将日志写入自己本地的 relay log 之后,接着会返回一个 ack 给主库,主库接收到至少一个从库的 ack 之后才会认为写操作完成了 所谓并行复制,指的是从库开启多个线程,并行读取 relay log 中不同库的日志,然后并行重放不同库的 日志,这是库级别的并行。
一个是并行复制,用来解决主从同步延时问题: 一般来说,如果主从延迟较为严重,有以下解决方案: - 分库,将一个主库拆分为多个主库,每个主库的 写并发就减少了几倍,此时主从延迟可以忽略不计。 - 打开 MySQL 支持的并行复制,多个库并行复制。如 果说某个库的写入并发就是特别高,单库写并发达到了 2000/s, 并行复制还是没意义。 - 重写代码,写 代码的同学,要慎重,插入数据时立马查询可能查不到。 - 如果确实是存在必须先插入,立马要求就查询 到,然后立马就要反过来执行一些操作,对这个查询设置直连主库。 不推荐这种方法,你要是这么搞,读写 分离的意义就丧失了
mysql 抗2000 并发 每秒钟的多元化 系统拆分 将一个系统拆分为多个子系统,用 dubbo 来搞。然后每个系统连一个数据库,这样本来就一个库, 现在多 个数据库,不也可以扛高并发么。 缓存缓存,必须得用缓存。大部分的高并发场景,都是读多写少, 那你完全可以在数据库和缓存里都写一份,然 后读的时候大量走缓存不就得了。 毕竟人家 redis 轻轻松松单机几万的并发。所以你可以考虑考虑你的项 目里,那些承载主要请求的读场景,怎么用缓存来抗高并发。 MQMQ,必须得用 MQ。可能你还是会出现高并发写的场景,比如说一个业务操作里要频繁搞数据库几十次,增 删改增删改,疯了。 那高并发绝对搞挂你的系统,你要是用 redis 来承载写那肯定不行,人家是缓存,数 据随时就被 LRU 了, 数据格式还无比简单,没有事务支持。所以该用 mysql 还得用 mysql 啊。那你咋办? 用 MQ 吧,大量的写请求灌入 MQ 里, 排队慢慢玩儿,后边系统消费后慢慢写,控制在 mysql 承载范围之 内。 所以你得考虑考虑你的项目里,那些承载复杂写业务逻辑的场景里,如何用 MQ 来异步写,提升并发性。 MQ 单机抗几万并发也是 ok 的,这个之前还特意说过。
dubbo 第一层:service 层, 接口层,给服务提供者和消费者来实现的 第二层:config 层, 配置层,主要是对 dubbo 进行各种配置的 第三层:proxy 层, 服务代理层,无论是 consumer 还是 provider,dubbo 都会给你生成代理,代理之间进行网络通信 第四层:registry 层, 服务注册层,负责服务的注册与发现 第五层:cluster 层, 集群层,封装多个服务提供者的路由以及负载均衡,将多个实例组合成一个 服务 第六层:monitor 层, 监控层,对 rpc 接口的调用次数和调用时间进行监控 第七层:protocal 层, 远程调用层,封装 rpc 调用 第八层:exchange 层, 信息交换层,封装请求响应模式,同步转异步 第九层:transport 层,网络传输层,抽象 mina 和 netty 为统一接口 第十层:serialize 层,数据序列化层
dubbo 相关协议 rmi provider ->consumer hesssion 序列化协议 http 协议 webservice xml soap协议 Protocol Buffer,Protocol Buffer 其实是 Google 出品的一种轻量并且高效的结构化数据存储格式,性能比 JSON、XML 要高很多
nginx 负载均衡
dubbo 负载均衡 random loadbalance leastactive loadbalance 不活跃性能 consistanthash loadbalance 高工培训视频 dubbo的spi思想 对应的springboot的插件思想 链路追踪 zipkin 打如地址和请求参数,拦截sql执行 服务的调用链路 TP50/70/90 dubbo超时重试次数 timeout 超时时间 retries 超时次数 <dubbo:reference id="xxxx" interface="xx" check="true" async="false" retries="3" timeout="2000"/> kafka zookper 源码分析 动态代理 GcLib的动态代理 nginx的负载均衡算法和 eurka的loadBlance负载均衡算法 以及ribbon hystrix的原理 zookper的注册中心和分布式锁 你 A 系统发送个请求到 mq,然后 B 系 统消息消费之后处理了。那 A 系统如何知道 B 系统的处理结果? 用 zookeeper 就可以实现分布式系统之 间的协调工作。A 系统发送请求之后可以在 zookeeper 上对某个节点的值注册个***, 一旦 B 系统处理完 了就修改 zookeeper 那个节点的值,A 系统立马就可以收到通知,完美解决。 zookper的分布式监听器使用 www.bilibili.com/video/av823…
redis setnx setpx SET resource_name my_random_value NX PX 30000 redis 锁存在的弊端,不知道多长时间执行完,也不能能一直阻塞
这个方案,我们很少用,一般来说某个系统内部如果出现跨多个库的这么一个操作,是不合规的。我可以给 大家介绍一下, 现在微服务,一个大的系统分成几十个甚至几百个服务。一般来说,我们的规定和规范, 是要求每个服务只能操作自己对应的一个数据库。 如果你要操作别的服务对应的库,不允许直连别的服务的库,违反微服务架构的规范,你随便交叉胡乱访问, 几百个服务的话,全体乱套,这样的一套服务是没法管理的,没法治理的,可能会出现数据被别人改错,自己的库被别人写挂等情况
两段式提交/XA 形式 询问和提交 TCC方案 TCC的全称是: Try、Confirm、Cancel //
Try: 监测资源,对相应的资源进行锁定和预留 confirm 确认:这个阶段说的是各个服务中执行实际操作 cancel 补偿机制
数据分析 模型选择
数据清理 ->特征工程-》 =》模型融合
数据划分 模型实验
螺旋开发,很大程度上是一种风险驱动的方 法体系,因为在每个阶段之前及经常发生的 循环之前,都必须首先进行风险评估。 敏捷开发,相比迭代式开发两者都强调在较 短的开发周期提交软件,但是,敏捷开发的 周期可能更短,并且更加强调队伍中的高度 协作。有时候被误认为是无计划性和纪律性 的方法,实际上更确切的说法是敏捷方法强 调适应性而非预见性。
代码越早 push 出去,用户能越早用到,快就是商业价值; 用户越早用到就越早反馈,团队越早得到反馈,好坏都是有价值的输入;
这是工程初始化就已有或应有的分支,若不存
在, 请创建。
feature/根据功能尽量进行有意义的命名。
功能分支,卷宗的开发一般都会带上当前在开
发版本的版本号,e.g. feature/v1.0—xxx。
๏ release/** 用于稳定测试的分支。也称为预发布分支,从 develop 打出,不在
此分支上合并需求。只改测试bug。
hotfix/** 修改线上问题的分支。
bugfix/** 开发过程非线上问题修改的分支。
Tags 用于记录已发布的版本,hotfix分支基于此类分支创建。
看板系统
SonarQube
BlueOcean
www.cnblogs.com/xiao9873341…
UML类图
父类 | 子类 子类指向父类 实线
接口虚线 虚线三角形
虚线 临时用一下,若即若离
空心菱形聚合关系 隶属关系,一个属于另一个,例如 大雁和大雁群属于隶属关系 实心菱形,隶属于组合关系 大雁和飞行的关系 0..1 0..*
对象, 同步调用 ————————————————————————|> —————————————————————————> 异步调用 返回调用 <------------------------ 演进 抽象的设计模式
UML 基础 UML 类图 UML 时序图 UML 类关系 UML 记忆技巧
创建模式 结构模式 行为模式
- public -private #protected ~ defalut 下面是横线的是static属性 抽象方法和抽象类都属于斜体类 UML里面的类图 上面属性,下面方法 子类强转成父类 开闭原则 依赖倒置原则相关说明 高层不应依赖底层,高层和低层都应依赖抽象; 抽象不能依赖细节,细节依赖于抽象 针对接口编程,不依赖于实现 抽象制定的锲约比细节实现的更加准确 单一职责 强调职责 不要存在多余1个导致类变更的原因 类 接口 方法 设计成2个类,不会造成类影响 职责清晰 变更不影响 方法单一清晰 平衡。。。。 接口和方法做到订单已职责
接口隔离 细化接口 接口中的方法比较小 注意适度 可读,可扩展和可维护
迪米特原则,最小知道原则 强调补个陌生人说话
最少知道原则
抽象方法:实际业务场景,除了抽象方法,属性 接口
抽象产品镞 由虚拟类生成 ArrayList URLStream slf4j logger
建造者 创建和使用分离
需要创建很多步骤 简单的功能 builder builderV2 建造者 按需调用,链式调用 Guava imiutlbale 不可变类使用 mabtis XMLConfigBuilder 建造者 单例-定义与类型 保证一个类仅有一个实例,并且提供一个全局访问点 网站计数器 线程池,数据库连接 减少内存开销,资源多重占用
私有构造器 线程安全 延迟加载 序列化和反序列化 反射
单例模式的 Double Check jad 反编译 内存原理 多线程debug
性能和安全性有啥影响
单线程的重排序,对线程并没有什么影响
1.线程的可见性,2不允许线程的重排
volatile的原理
写操作时,会多出一些汇编代码
1.将当前内存cpu的数据缓存在内存中,这个操作会使其他缓存在cpu内存中的数据无效
因为无效了,其他缓存的数据从CPU中拉取数据,同步一致
饿汉式
初始化的加载号就行了
ELK elasticsearch
反射 invoke来进行定义 目标方法名
readReslove 方法
实例化对象了,没有返回
Eunm 相关学习 枚举类对于序列化不受影响 枚举类无法进行反射攻击
容器单例模式
hashTable sycheonize
静态的 concurentHashMap 不是绝对的线程安全
threadLocal 会为每一个线程提供一个独立的线程副本 ThreadlocalMap 线程会获取对象是唯一 为每一个线程提供一个对象
RunTime 属于饿汉式 Desktop java 桌面程序 容器单例 Spring 中作用域不同,容器:类加载器
原型模式--定义与类型 指原型实例指定创建对象种类 ,并且拷贝这些原型创建新的对象 不需要知道任何创建细节,不调用构造函数 创建型 clone 克隆不会调用构造器方法 但是克隆的地址都不相同 原型模式存在深克隆的bug
外观模式 提供一个总额接口调用,简化调用过程,无需深入了解子系统,防止带来风险 减少系统依赖,松耦合
划分接口层次
符合迪米特法则,最少知道原则 不符合开闭原则 外观和中介者系统 外观和单例模式
mybatis stateMent newMetaObject tomcat catalina 包底下的所有的以 facade结尾的所有的类
Facade结尾的类都属外观模式
装饰者模式(结构型) 在不改变原有的对象的基础上,将功能附加到对象上 比继承更有弹性的替代方案(扩展原有对想法功能)
代理模式??对象做代理 动态装饰,多层装饰会复杂 装饰着继承父类 装饰着和代理 装饰着在一个类上动态的添加方法 代理模式动态着重于在对类的动态控制,隐藏代理对象 装饰者模式一般着重于将对象作为参数传入 BufferReader BufferedInputStream BufferdOutputStream wrapper 装饰者或者适配器 mybtais cache decorators 适配器 一个类的接口转换成客户期望的另一个接口 JAXB
xmlAdpter dipatherServlet
享元模式 减少对象数量,从而改善应用所需的对象的结构方式 运用共享技术,有效的支持大颗粒度的对象
减少对象的创建数量,提高系统性能 底层开发,解决系统性能问题 系统存在大量相似对象,需要缓冲池
关注内外部状态,关注线程去年全问题 系统,程序的逻辑复杂化 Integer
扩展 内部状态 外部状态 integer cache //享元模式,运用共享技术,有效的支持大颗粒的对象 long cache generaickeyedObjectPool tomcat 创建对象连接池
组合模式 定义:将对象组合成树形结构以表示部分和整体的层次结构 组合模式使客户端单个对象和组合对象保持一致的方式处理
客户端忽略组合对象和单个对象的差异时 或者处理一个树形结构时
清楚的定义分层次的复杂对象 表示对象全部或者部分层次 让客户端忽略了层次差异,方便对整个层次结构进行控制 arteryUI awt putALL addALL SqlNode 叶子和组合对象一致处理 源码结构了解
桥接模式 组合建立2个类之间的关系 抽象和实现分开 2个维度进行扩展 不希望使用继承 组合优于继承 CopyOnWriteArrayList
模板方法 定义一个算法骨架, 并允许子类为一个或者多个步骤提供实现 行为型 一次性实现算法不可变的部分,将可变的行为留给子类 钩子方法 算法替换 策略 模板方法 业务模型应该抽象好定义成抽象的
模板方法模式应用 abStractList httpServlet doXXXX baseExcutor 迭代器设计场景 分离集合对象的遍历 存储和遍历分离 Iterator hasNext() 策略模式 定义了算法家族,分别封装起来 让他们之间相互替换, 算法的变化不会影响到使用算法的用户 if else 行为型 不同行为放在不同的类里面 一个系统需要动态在几种算法中选择
开闭、、、避免多重条件转移语句 提高算法的保密性和安全性 comparator resouce
InstationStartegry cglib Simple 解释器 给定一个语言,定义他的文法 解析一种语言,为语言创建的解释器 pattern 正则 EL表达式 开源框架提供的解释器模型 观察者模式 对象之间的一对多的依赖,让多个观察者同时监听某个主题对象,当主题对象发生变化时, 所有的依赖者都会收到通知并更新
观察者和被观察者之间建立一个抽象耦合 广播通信 课程 Couser 被观察对象 Observable setChanged 问题变化了 notifyObsers(question) 问题 useName questionName couserName update() cs程序 事件监听 Ecent Listenner EventBus Guava CopyOnwiteArraySet
备忘录 后悔药 保存和回复数据恢复 后悔回复某种状态 资源占用 利用STACK的先进后出和后进先出 WPS 文本编辑器 webflow 工作流
命令模式 请求封装成对象,以便使用不同的请求 发送者和接收者解耦 请求接收者者发送者 下达一组命令 runable junit.framework
中介者模式: 定义一个封装一组对象如何交互的对象 通过使对象明确的相互引用来促进松散耦合, 并允许独立的改变他们的交互 行为型
相互依赖关系混乱难以理解
交互的公共行为,如果需要改变行为则可以增加新的中介者类
将一对多转换成了一对一,降低了程序的复杂度
中介者模式过多,导致系统复杂
java util time 责任链模式 接受此次请求对象的链 dofilter 责任链 spring security
访问者 封装作用于某数据结构中个元素的操作
数据和操作分离 数据结构的元素某种 访问者 nio FileVistor BeanDefinitionVisitor 分解 状态模式 允许一个对象在内部改变时,改变他的行为