程序员易忘基础知识
软件开发中的原则 - SOLID
- S 单一职责 (Single Responsibility Principle)
- O 开放封闭原则 (Open Closed Principle)
- L 里氏替换原则 (Liskov Substitution Principle)
- I 接口隔离法则 (Interface Segregation Principle)
- D 依赖倒置原则 (Dependency Inversion Principle)
- D 迪米特原则 (Law of Demeter)
里氏替换原则:继承必须确保超类所拥有的性质在子类中仍然成立,确保应用父类的地方替换为引用子类后功能不变。
依赖倒置原则:高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。
迪米特原则:一个对象应该对其他对象保持最少的了解,只与直接的朋友通信。
事务特性
- 原子性(Atomicity [ˌadəˈmisədē]):一个事务里面的所有数据操作,要么全部做完,要么全部不做(中间某个操作出了问题,所有操作回滚)。
- 一致性(Consistency [kənˈsistənsē]):事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。
- 隔离性(Isolation [ˌīsəˈlāSH(ə)n]):不同的事务根据不同的事务隔离级别进行隔离。A事务的操作不应该影响B事务的操作。
- 持久性(Durability [ˌd(y)o͝orəˈbilədē]):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。
隔离性的互不影响是理想状态,要维护该状态势必会造成读写性能的下降。例如mysql就设置了自己的四种隔离级别来配置mysql不同事务之间的隔离程度,在损失一定事务隔离性的结果下提升自己的读写效率。
SQL标准事务隔离级别
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
READ UNCOMMITTED | 是 | 是 | 是 |
READ COMMITTED | 否 | 是 | 是 |
REPEATABLE READ | 否 | 否 | 是 |
SERIALIZABLE | 否 | 否 | 否 |
- 读未提交(read-uncommitted):在A事务可以读到B事务里面未提交的数据操作结果
- 读已提交(read-committed):在A事务会收到B事务里面未提交的数据操作结果的影响,导致在A事务里面两次读的结果不一样
- 可重复读(repeatable-read):在A事务不会收到B事务里面未提交的数据操作结果的影响,在A事务里面两次读的结果一样
- 串行化(serializable):在A事务里面对数据的操作会锁表,B事务必须等待A事务提交后才能操作该表数据
Mysql 默认:可重复读;Oracle 默认:读已提交
分布式系统 CAP 理论
- 一致性(Consistency):所有节点在数据操作后,数据依然保持一致
- 可用性(Availability):能为用户提供高效的服务。
- 分区容错性(Partition Tolerance):系统容错,系统部分节点出错不影响系统正常提供服务(该性能与节点数成正线性相关)。
分布式系统指有多个节点系统构成的一个系统集合。
CAP 理论认为分布式系统只能兼顾其中的两个特性。eureka是AP、zookeeper是CP,nacos可通过配置选择AP或者CP
CA:所有节点数据保持一致,并且要能高效的相应用户请求。那么节点就不能太多,分区容错性降低。
CP:所有节点数据保持一致,有很多节点来保持高分区容错性。那么每次修改数据后的节点之间同步势必耗时增强。可用性降低。
AP:节点一大堆,还要能够高效的相应客户请求。那么就不能死死的等所有节点都同步确认数据一致后再响应一次数据操作,一致性降低。
分布式系统 BASE 理论
eBay 的架构师 Dan Pritchett 源于对大规模分布式系统的实践总结,在 ACM 上发表文章提出 BASE 理论,BASE 理论是对 CAP 理论的延伸,核心思想是即使无法做到强一致性(Strong Consistency,CAP 的一致性就是强一致性),但应用可以采用适合的方式达到最终一致性(Eventual Consitency)。
- Basically Available(基本可用) 分布式系统在出现不可预知故障的时候,允许损失部分可用性
- Soft state(软状态) 软状态也称为弱状态,和硬状态相对,是指允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据听不的过程存在延时。
- Eventually consistent(最终一致性) 最终一致性强调的是系统中所有的数据副本,在经过一段时间的同步后,最终能够达到一个一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性
分布式系统 康威定律
原文地址:微服务架构的理论基础 - 康威定律
- 第一定律 组织沟通方式会通过系统设计表达出来。
- 第二定律 时间再多一件事情也不可能做的完美,但总有时间做完一件事情。
- 第三定律 线型系统和线型组织架构间有潜在的异质同态特性。
- 第四定律 大的系统组织总是比小系统更倾向于分解。
康威定律如何解释微服务的合理性
了解了康威定律是什么,再来看看他如何在半个世纪前就奠定了微服务架构的理论基础。
-
人与人的沟通是非常复杂的,一个人的沟通精力是有限的,所以当问题太复杂需要很多人解决的时候,我们需要做拆分组织来达成对沟通效率的管理
-
组织内人与人的沟通方式决定了他们参与的系统设计,管理者可以通过不同的拆分方式带来不同的团队间沟通方式,从而影响系统设计
-
如果子系统是内聚的,和外部的沟通边界是明确的,能降低沟通成本,对应的设计也会更合理高效
-
复杂的系统需要通过容错弹性的方式持续优化,不要指望一个大而全的设计或架构,好的架构和设计都是慢慢迭代出来的
带来的具体的实践建议是: -
我们要用一切手段提升沟通效率,比如slack,github,wiki。能2个人讲清楚的事情,就不要拉更多人,每个人每个系统都有明确的分工,出了问题知道马上找谁,避免踢皮球的问题。
-
通过MVP的方式来设计系统,通过不断的迭代来验证优化,系统应该是弹性设计的。
-
你想要什么样的系统设计,就架构什么样的团队,能扁平化就扁平化。最好按业务来划分团队,这样能让团队自然的自治内聚,明确的业务边界会减少和外部的沟通成本,每个小团队都对自己的模块的整个生命周期负责,没有边界不清,没有无效的扯皮,inter-operate, not integrate。
-
做小而美的团队,人多会带来沟通的成本,让效率下降。亚马逊的Bezos有个逗趣的比喻,如果2个披萨不够一个团队吃的,那么这个团队就太大了。事实上一般一个互联网公司小产品的团队差不多就是7,8人左右(包含前后端测试交互用研等,可能身兼数职)。
再对应下衡量微服务的标准,我们很容易会发现他们之间的密切关系: -
分布式服务组成的系统
-
按照业务而不是技术来划分组织
-
做有生命的产品而不是项目
-
Smart endpoints and dumb pipes(我的理解是强服务个体和弱通信)
-
自动化运维(DevOps)
-
容错
-
快速演化
java 引用
名称 | 案例 | 说明 |
---|---|---|
强引用 | 默认等号赋值 | 永不回收,内存不足,抛出OutOfMemoryError |
软引用 | java.lang.ref.SoftReference | 内存足够时有效,内存不足时回收。 |
弱引用 | java.lang.ref.WeakReference | 不考虑内存足不足,GC开始就回收 |
虚引用 | java.lang.ref.PhantomReference | 随时可能被回收 |
二叉树三种遍历方式
看跟节点位置,在前边就是前序,中间就是中序,后面就是后续
- 前序遍历:根 左 右
- 中序遍历:左 根 右
- 后序遍历:左 右 根
Java访问控制符使用范围如下表所示,表格中值为1表示能访问,值为0表示不能访问。
本包 | 子类 | 外部包 | |
---|---|---|---|
public | 1 | 1 | 1 |
protected | 1 | 本包+外包子类 super调用 | 0 |
无修饰符(package-private) | 1 | 本包可以 | 0 |
private | 0 | 0 | 0 |
public 谁都能调用
protected 保护级别,不可以修饰类
无修饰符(包私有) 同包内可以调用
private 除了自己内部,外部无法调用
前端
闭包
参考地址:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures
闭包是一种特性
正式说法:一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)。
个人理解:我们知道在 JavaScript 即使是 funcation 也是一个对象。 闭包就是对 funcation 对象可操作哪些地方的对象的一种特征解释。
const、let 与 var
声明符号 | 操作状态 | 作用域 | 初始化时期 |
---|---|---|---|
const | 常量 | 代码块及子代码块级别 | 编译时 |
let | 变量 | 代码块及子代码块级别 | 编译时 |
var | 变量 | 整个封闭函数级别 | 声明时 |
var 声明的变量在相同作用域可以重复声明,但是后面声明的会覆盖前面的,这就是个问题,既然会覆盖,那直接重新赋值好了,重复声明可能会造成影响别的地方的逻辑处理。let 就不允许重复声明。
能用 const 的不用 let,能用 let 的不用 var。
<!DOCTYPE html> <html> <body> <h2>为什么要用 let 而不是 var JavaScript</h2> <p id="help">Helpful notes will appear here</p> <p>E-mail: <input type="text" id="email" name="email"></p> <p>Name: <input type="text" id="name" name="name"></p> <p>Age: <input type="text" id="age" name="age"></p> </body> <script> function showHelp(help) { document.getElementById('help').innerHTML = help; } function setupHelp() { var helpText = [ {'id': 'email', 'help': 'Your e-mail address'}, {'id': 'name', 'help': 'Your full name'}, {'id': 'age', 'help': 'Your age (you must be over 16)'} ]; for (var i = 0; i < helpText.length; i++) { // 此处用 var 的话就是整个 setupHelp 函数块声明,for循环后面声明的 item 会覆盖前面的。 let item = helpText[i]; document.getElementById(item.id).onfocus = function() { showHelp(item.help); } } } setupHelp(); </script> </html>
git指令
# 修改提交日志 git commit --amend # 回滚本地提交两次 git reset HEAD~2 # 回滚其他分支提交状态两次 git revert other~1 # 修改最近五次 git 日志状态 git rebase -i HEAD~5 # 锚点,确定位置,后面可接参数 git节点 hash值 git describe # git 摘取制定记录到当前位置后面 git cherry-pick [<hash值> ...] # 将 branchA 合并到 branchB 前面 git rebase branchA branchB
数据库
分页语法
-- oracle -- 表示从第20条开始取下10条记录 SELECT * FROM role ORDER BY role_name OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY; -- 跳过前 100 行,如果表少于 101 条记录,结果集将是空的 SELECT * FROM role OFFSET 100 ROWS; -- mysql -- 从 5 行开始取 10 行 SELECT * FROM role LIMIT 5,10; -- 从 0 行开始取 4 行 SELECT * FROM role LIMIT 4;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律