序列图
展示对象之间的交互顺序纵向是时间轴,时间沿竖线向下延伸。 横向轴代表了在协作中各独立对象的类元角色。类元角色用生命线表示。当对象存在时,角色用一条虚线表示,当对象的过程处于激活状态时,生命线是一个双道线。生命线代表一个类的特定实体。 生命线:每一个类元角色延伸出来的竖线 **同步消息:**发送人在它继续之前,将等待同步消息响应 **异步消息:**在发送方继续之前,无需等待响应的消息 注释 约束:格式是: [Boolean Test] 组合片段:解决交互执行的条件及方式,为任何生命线的任何部分定义特殊条件和子进程。 抉择Alt:在两个或更多的消息序列之间的互斥的选择,相当于经典的if..else..。 选项(Opt):包含一个可能发生或不发生的序列。 可以在临界中指定序列发生的条件。 **循环(Loop):**片段重复一定次数。 可以在临界中指示片段重复的条件。 并行(Par):
必先利其器,常用工具分享
Chrome 插件效率Workspaces网页有用但是要关闭浏览器了,想下次打开恢复现场,这个插件很合适。 借助工作空间的概念,可以不同窗口放置不同类型的内容。 GitHub加速 Octotree - GitHub code treegithub 目录 JSON-handlejson 格式化工具 Markdown Nice在线微信公众号 Markdown 排版工具 OneTab助长拖延症,不推荐使用,使用 Workspaces 就够了。 沙拉查词-聚合词典划词翻译 稀土掘金启动页 百度搜索 快捷打开 baidu.com 浏览器增强AdBlock — 最佳广告拦截工具Better History历史记录管理,比自带的更好用 暂停标签 (Tab Suspender)打开很多页面的时候电脑占用内存紧张 这个插件会将固定时间内没有浏览的网页暂停,避免消耗太多内存。 Clear Cache快捷清除浏览器缓存 EditThisCookie编辑cookie 图片助手(ImageAssistant) 批量图片下载 Neater Bookmarks方便的书签管理 Tampermonkey...
快速排序
题目连接: 912. 排序数组 代码 (三路快排)1234567891011121314151617181920212223242526272829303132333435class Solution: def sortArray(self, nums: List[int]) -> List[int]: self.quick_sort(nums, 0, len(nums) - 1) return nums def quick_sort(self, nums: List[int], left: int, right: int) -> None: if left >= right: return le, gt = self.partition(nums, left, right) self.quick_sort(nums, left, le - 1) self.quick_sort(nums, gt, right) def partit...
异步任务的坑
Spring Boot 中编写异步任务两个注解: @EnableAsync:开启当前项目的异步功能 @Async:当前方法标记为异步方法 注意一个规则:有没有返回值。 没有返回值的例子: 返回值实现了 Future 接口: 下 异步任务的线程池配置默认情况下,异步任务的线程池是怎么配置的,是否满足我们的需求呢? 配置线程池参数默认是启动下面的线程池: 线程池对应的自动配置类如下: 可以使用下面的参数配置异步任务线程池相关的参数: 异步任务返回超时对于异步任务有返回的情况,如果获取结果超时怎么办呢? get 有重载方法可以设置超时的时间,超时之后就会抛出 TimeOut 异常: 没有返回值的异步任务抛异常对于异步任务没有返回的情况(有返回的直接 get 的时候就会抛异常),但是下面的异步任务执行的时候抛出异常,但是没有任何的其他返回: Spring 默认的异步任务异常处理器,会将对应的异常打印到日志里面: 自定义异步线程池和异常处理器 自定义异步线程池的实现: 自定义异常处理器
抽象类和接口的选择
抽象类、接口的含义和特性抽象类是子类的通用特性,包含了属性和行为;接口是定义行为,并不关心谁去实现。 抽象类是对类本质的抽象,表达的是 is a 的关系;接口是对行为的抽象,表达的是 like a 的关系。 抽象类、接口的相同点都可以被继承,但是不能被实例化。 抽象类、接口的不同点使用时语法不同,抽象类使用 extends,接口则使用 implements。 接口中只能定义常量,所以,不能表达对象状态,而抽象类可以。 接口中的方法必须是 public 类型的,而抽象类则没有限制。 类可以同时实现多个接口(间接解决了 Java 不支持多继承的难题),但是只能继承一个抽象类。 适用场景所有类都有的基础属性或者方法定义在抽象类中。 特定子类有的方法定义在接口中。
持久化配置最佳实践
RDB 持久化配置 手动触发RDBsave:会阻塞当前 Redis 服务器,直到持久化完成,线上应该禁止使用 bgsave:该触发方式会 fork 一个子进程,由子进程负责持久化过程,因此阻塞只会发生在 fork 子进程的时候 定时触发RDB根据我们的 save m n 配置规则自动触发 从节点全量复制时,主节点发送rdb文件给从节点完成复制操作,主节点会触发 bgsave 执行 shutdown 时,如果没有开启 aof,也会触发 AOF 持久化配置 AOF 重写:当 AOF 文件的大小超过所设定的阈值时,Redis 就会启动 AOF文件的内容压缩,只保留可以恢复数据的最小指令集 触发机制:Redis 会记录上次重写时的 AOF 大小,默认配置是当 AOF 文件大小是上次 rewrite 后大小的一倍且文件大于 64MB 时触发 bgrewriteaof 可以手动触发 重写原理:将整个内存中的数据库内容用命令的方式重写了一个新的 AOF 文件,这点和快照有点类似 持久化数据恢复
指令集架构深入分析
雇主不是需要汇编语言程序员,而是需要有理解计算机体系结构的人来写出各高效的程序 指令的格式指令集设计的考虑因素?ISA设计考虑因素: 指令占用内存空间大小; 指令系统复杂程度,主要指指令执行所需要的译码数量和指令所执行任务的复杂性; 指令长度大小以及是否固定 指令系统中指令的总数目。 不同类型的寻址方法 字节存储的小端大端位序问题 ISA需要多少寄存器并如何组织这些寄存器 短指令的好处和缺点?指令一般越短越好,较短的指令占用较少的内存空间,并且提取指令速度更快。但采取短指令会限制指令的数量(受到能够编码的二进制数的位数限制),同样也会限制操作数的大小和数量。 为什么要按字节编址?存储器的组成会影响指令的格式。如果存储器为16或32位字,不按字节编址则很难访问到一个单一字符,因此有些16/32/64位机器也是按照字节编址。 什么是大端和小端?计算机存储多字节的方法,所有现代计算机都是按字节编址,大多数UNIX采用大端方式,个人计算机采用小端方式,大多数RISC架构采用大端方式。 注意:大端小端的方式只是字节顺序的颠倒,不是数字位的颠倒,在字节内部还是正常的顺...
接口幂等方案
对于一个接口而言,无论调用了多少次,最终得到的结果都是一样的。 幂等性的实现与判断需要消耗一定的资源,因此不应该给每个接口都增加幂等性判断,要根据实际的业务情况和操作类型来进行区分。 在进行查询操作和删除操作时就无须进行幂等性判断。查询操作查一次和查多次的结果都是一致的,因此我们无须进行幂等性判断。删除操作也是一样,删除一次和删除多次都是把相关的数据进行删除(这里的删除指的是条件删除而不是删除所有数据),因此也无须进行幂等性判断。 关键步骤 每个请求操作必须有唯一的 ID,而这个 ID 就是用来表示此业务是否被执行过的关键凭证 每次执行业务之前必须要先判断此业务是否已经被处理过 第一次业务处理完成之后,要把此业务处理的状态进行保存,比如存储到 Redis 中或者是数据库中,这样才能防止业务被重复处理。 前端拦截用户点击完“提交”按钮后,我们可以把按钮设置为不可用或者隐藏状态,避免用户重复点击。 数据库实现数据库实现幂等性的方案有三个: 通过悲观锁来实现幂等性 开启事务实现原子操作 id 字段一定要是主键或者是唯一索引,不然会锁表,影响其他业务执行。 通过唯一索引来实现...
指定哈希与相对引用
指定hash通过指定提交记录哈希值的方式在 Git 中移动不太方便。 用 git log 来查查看提交记录的哈希值。哈希值在真实的 Git 世界中也会更长(基于 SHA-1,共 40 位)。可以仅输入fed2 而不是 fed2da64c0efc5293610bdd892f82a58e8cbc5d8一长串字符。 通过哈希值指定提交记录很不方便,所以 Git 引入了相对引用。使用相对引用的话,你就可以从一个易于记忆的地方(比如 bugFix 分支或 HEAD)开始计算。 使用 ^ 向上移动 1 个提交记录 使用 ~<num> 向上移动多个提交记录,如 ~3 相对引用操作符 ^把这个符号加在引用名称的后面,表示让 Git 寻找指定提交记录的父提交。所以 master^ 相当于“master 的父节点”。master^^ 是 master 的第二个父节点 现在咱们切换到 master 的父节点 1git checkout master^ 1234git checkout C3git checkout HEAD^git checkout HEAD^git checkou...
持续集成和容器管理
DockerMaven插件微服务部署有两种方法: 手动部署:首先基于源码打包生成jar包(或war包),将jar包(或war包)上传至虚拟机并拷贝至JDK容器。 通过Maven插件自动部署。 自动部署 是企业实际开发中经常使用的方法。 Maven插件自动部署步骤:修改宿主机的docker配置,让其可以远程访问 1vim /lib/systemd/system/docker.service 其中ExecStart=后添加配置-H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock 刷新配置,重启服务 123systemctl daemon-reloadsystemctl restart dockerdocker start registry 在工程pom.xml 增加配置 12345678910111213141516171819202122232425262728<build> <finalName>app</finalName> <plugins> ...