算法笔记
常见题目素数/质数判断单次判断:
12345678910bool isPrime(int n) { if (n < 2) return false; // 小于2的数不是质数 if (n == 2) return true; // 2是质数 if (n % 2 == 0) return false; // 排除偶数 for (int i = 3; i <= sqrt(n); i += 2) { // 只遍历奇数 if (n % i == 0) return false; } return true;}
多次判断:埃氏筛
12345678910111213vector<bool> sieve(int n) { vector<bool> isPrime(n + 1, true); isPrime[0] = isPrime[1] = false; // 0和1不是质数 for (int i = 2; i * i <= n; ++i) ...
设计模式 | Java后端
SOLID 原则单一职责原则 SRP
概念
一个类或者一个方法只做一件事
本质是接口单一职责原则,软件项目里几乎不可能实施类单一职责原则
单一职责原则不只是面向对象编程思想所特有的,只要是模块化的程序设计,都适用单一职责原则
优点
类的复杂性降低,代码可读性高
变更风险低,代码维护性高
提高代码的扩展性
开闭原则 OCP
概念
类、模块和函数等软件实体应该对扩展开放,对修改关闭
意为一个实体独立之后就不应该去修改它,而是以扩展的方式适应新需求
优点
单元测试可不变,代码可靠性高
代码复用性强
代码维护性高
里式替换原则 LSP
概念
所有基类出现的地方都可以用派生类替换而不会程序产生错误
里氏替换原是继承复用的基础,它反映了基类与子类之间的关系,是对开闭原则的补充,是对实现抽象化的具体步骤的规范
实现
子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法
子类中可以增加自己特有的方法
当子类的方法重载父类的方法时,方法的前置条件(即方法的输入参数)要比父类的方法更宽松
当子类的方法实现父类的方法时(重写/重载或实现抽象方法),方法的后置条件(即方 ...
JMM与线程安全 | Java后端
JMM概念
JMM 是 JVM 在计算机内存 RAM 中的工作方式,定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存中,每个线程都有一个私有的工作内存,工作内存中存储了该线程以读/写共享变量的副本(工作内存是 JMM 的一个抽象概念,并不真实存在)同时它规范了 JVM 如何提供按需禁用缓存和编译优化的方法,意在解决在并发编程可能出现的线程安全问题,确保了程序执行在多线程环境中的应有的原子性、可见性及有序性。具体来说,这些方法包括:
外部可使用的同步手段:volatile、synchronized 和 final 三个关键字
内置解决方案:Happens-Before 规则
JMM 还屏蔽掉各种硬件和操作系统的内存访问差异,以实现让 Java 程序在各种平台下都能达到一致的并发效果
JVM 描述的是 Java 虚拟机内部及各个结构间的关系
Java 内存模型所有的共享变量都存储在主内存中,包括实例变量、静态变量,但是不包括局部变量和方法参数每个线程都有自己的工作内存,线程的工作内存保存了该线程用到的变量和主内存的副本拷贝,线程对变量的操作都在工作内存中进行。线程 ...
Spring | Java后端
介绍Spring 是一个轻量级 Java 开发框架,设计目标是为开发者提供一个一站式轻量级应用开发平台,即简化 Java 开发,让 Spring 负责基础架构,使得 Java 开发者可以专注于应用的开发。
Spring 总共大约有 20 个模块,比较重要的有:
spring core:提供了框架的基本组成部分,包括控制反转和依赖注入功能。
spring beans:提供了 BeanFactory,是工厂模式的一个经典实现,Spring 将管理对象称为 Bean。
spring context:构建于 core 封装包基础上的 context 封装包,提供了一种框架式的对象访问方法。
spring aop:提供了面向切面的编程实现,可以自定义过滤器、切点等。
Spring 框架的核心是 IoC 容器和 AOP 模块。通过 IoC 容器组织和管理应用中各个组件及其关系,通过 AOP 以动态非侵入的方式增强服务。
Spring 优点:
方便解耦,简化开发(高内聚低耦合)
AOP 编程的支持
面向切面编程 → 对 Spring 容器中的实例做增强
声明式事务的支持
只需通过配置就可完 ...
消息队列 | Java后端
MQ选型
ActiveMQ
Java
社区活跃度很低
RabbitMQ
ErLang,实现定制化开发难度较大
并发性能好,延时达到微秒级(因为 ErLang)
对消息堆积的支持并不好,当大量消息积压时性能急剧下降
Kafka
Scala/Java
最大特点是仅提供较少的核心功能,但是提供超高的吞吐量、极高的可用性以及可靠性高,常用于大数据领域的实时计算、日志采集等场景
每秒钟消息数量没有那么多的时候,Kafka 的时延反而会比较高,所以 Kafka 不太适合在线业务场景
RocketMQ
Java
有阿里实际业务场景的实战考验
对在线业务的响应时延做了很多的优化
为什么要使用 MQ
通过异步处理提高系统性能,减少响应所需时间
上游系统对下游系统的调用若为同步调用,会大大限制系统的吞吐量与并发度,所以在中间添加一个 MQ,实现同步转异步
限流削峰
先将短时间高并发产生的事务消息存储在消息队列中,然后下游服务只需根据自己的能力去消费这些消息,这样就避免直接把下游服务打垮掉
降低系统耦合性
服务消费者对服务提供者直接调用,属于强耦合,如果服务提供者不可用,服务消费者也 ...
Redis | Java后端
NoSQL是什么NoSql 全称 Not Only SQL,泛指非关系型数据库,是对关系型数据库的一种补充
为什么使用
关系型数据库的缺点
高并发下 IO 压力大
数据按行存储,即使只针对其中某一列进行运算,也会将整行数据从存储设备中读入内存,使得 IO 代价较大
为维护索引付出的代价大
为了提供丰富的查询能力,通常热点表都会有多个索引,以提供丰富的查询能力。一旦有了索引,数据的新增必然伴随着所有索引的新增,数据的更新也必然伴随着所有索引的更新,这不可避免地降低了关系型数据库的读写能力,索引越多读写能力越差
为维护数据一致性付出的代价大
数据一致性是关系型数据库的核心,但是为了维护数据一致性的代价也是非常大的,只要提供的隔离级别越高,读写性能必然越差。
水平扩展后带来的种种问题难处理
随着企业规模扩大,当数据库产生性能瓶颈,就需要读写分离、分库分表。做了分库之后,数据迁移(1 个库的数据按照一定规则打到 2 个库中)、跨库 join、分布式事务处理都是需要考虑的问题
表结构扩展不方便
由于数据库存储的是结构化数据,因此表结构 schema 是固定的,扩展不方便,如果需要修改表 ...
内存管理 | OS
内存管理概念引入多道程序的并发执行后,进程之间共享的不仅仅是处理机,还有主存储器。然而,共享主存会形成一些特殊的挑战。若不对内存进行管理,则易导致内存数据的混乱,以至于限制进程的并发执行。因此,为了更好地支持多道程序并发执行,必须进行内存管理。
内存管理
操作系统对内存的划分和动态分配。
内存管理主要功能
有效的内存管理在多道程序设计中非常重要,它不仅可以方便用户使用存储器、提高内存利用率,还可以通过虚拟技术从逻辑上扩充内存。
内存空间的分配与回收
地址转换(逻辑 → 物理)
内存空间的扩充(利用虚拟存储技术在逻辑上扩充内存)
内存共享(支持多进程对内存共享区域进行受控访问)
存储保护(保证各个进程在各自的存储空间内运行,互不干扰)
程序的链接和装入将用户程序变为可在内存中执行的程序的步骤
编译
可细分为预处理、编译、汇编三个步骤,用来对每个模块(即源程序文件)生成可重定位目标文件。
链接
由链接程序(linker)将编译后形成的一组可重定位目标文件以及它们所需要的库函数链接在一起,形成一个完整的可执行目标文件,即装入模块(load module)。
装入
由装入程序( ...
拓展 | OS
协处理器
一种协助中央处理器完成其无法执行,或执行效率、效果低下的处理工作而开发和应用之处理器
这种中央处理器无法执行的工作有很多,比如设备间的信号传输、接入设备的管理等;而执行效率、效果低下的有图形处理、声频处理等
主要分类:各类处理芯片(如GPU、声频处理芯片等)、接口控制芯片(如SATA接口控制芯片)、桥接芯片
由于现在的计算机中,整数运算器与浮点运算器已经集成在一起,因此浮点处理器已经不算是辅助处理器。而内建于 CPU 中的协处理器,同样不算是辅助处理器,除非它是独立存在
内存管理部件 MMU
常见文件系统从 Windows 2000 之后的 Windows 默认文件系统为 NTFS;RHEL/CentOS 从 RHEL/CentOS 7 开始默认使用 XFS 文件系统;FAT32 和 exFAT 是目前 USB 闪存盘比较常用的文件系统。
Linux 支持各种各样的文件系统格式,如 ext 系列、FAT、NTFS 等。
FAT、FAT16、FAT32
FAT 是最早、最简单的文件系统之一。FAT 即文件分配表。FAT16 和 FAT32 都是 FAT 文件管理系统,二 ...
拓展 | CO
逻辑运算相关逻辑运算符&:按位与 |:按位或 ^:按位异或
&&:逻辑与 ||:逻辑或 !:逻辑非
逻辑表达式
逻辑门电路符号
CPU 架构名词x86
指 Intel 8086 处理器及其后续版本的架构系列。
最初是 16 位处理器,后来也包括了 32 位和 64 位版本。
x86 处理器均向下兼容。
Intel 为防止竞争对手的 x86 兼容处理器产品用相近的命名方式,并与它们作出区分,80486 以后不再采用 80( )86 的命名方式,本应被命名为 80586 或 i586 结构的处理器被命名为 Pentium,也被称为 P5 架构。
实际上在 80486 以后 Intel 推出的绝大数 CPU 也都是 x86 架构,并且使用 x86 架构的处理器制造商远非 Intel 一家,目前出售的的品牌或组装的 PC 很少不是 x86 CPU 的。可以说 x86 架构就是桌面级 CPU 的标准。不过虽说都是 x86 的,也只能说明使用的指令集是兼容 8086 的,除 8086 指令集之外的指令的支持情况就不一样,且指令的实现显然也是各 ...
输入输出系统 | CO
I/O 系统基本概念*输入/输出系统外部设备
包括输入/输出设备及通过输入输出接口才能访问的外存储设备。
接口
在各个外设与主机之间传输数据时进行各种协调工作的逻辑部件。
协调包括传输过程中速度的匹配、电平和格式转换等。
输入设备
用于向计算机系统输入命令和文本、数据等信息的部件。
键盘和鼠标是最基本的输入设备。
输出设备
用于将计算机系统中的信息输出到计算机外部进行显示、交换等的部件。
显示器和打印机是最基本的输出设备。
外存设备
除计算机内存及 CPU 缓存等以外的存储器,如硬磁盘、光盘等。
I/O 系统组成
一般来说,I/O 系统由 I/O 软件和 I/O 硬件两部分构成:
I/O 软件:包括驱动程序、用户程序、管理程序、升级补丁等。通常采用 I/O 指令和通道指令实现 CPU 和 I/O 设备的信息交换。
I/O 硬件:包括外部设备、设备控制器和接口(I/O 接口)、I/O 总线等。通过设备控制器控制 I/O 设备的具体动作;通过 I/O 接口与主机(总线)相连。
I/O 接口
I/O 接口 = I/O 控制器 = 设备控制器。
以前的 I/O 接口(芯片)会被集成在南桥芯 ...