CodeReview 规范及实施

优质博文:IT-BLOG-CN

一、为什么需要CodeReview

随着业务压力增大,引发代码质量下降,代码质量的下降导致了开发效率的降低,维护成功高等问题,开发效率下降后又加重了业务压力,最终陷入了死亡三角的内耗之中。只要解决掉死亡三角内耗中的任一一角,就能终止恶性循环,比如精简业务需求、增加开发人员、重构项目架构等,很多时候可能是多管齐下的。这篇文章主要目的是:通过代码评审(Code Review,简称CR)整治代码不规范和代码安全性/健壮性低等问题,从而提高代码和产品的质量和确保代码库整体代码健康状况随着时间的推移而完善,最终降低系统的维护成本和提高开发效率。

效果: Rebook项目有50万行代码,使用了代码检查(其中包含代码评审),结果是项目提前交付,并且只有通常预期错误的1%。一份对200多人组织的研究报告显示,在引入代码评审后,生产率提高了14%,缺陷减少了90%

代码评审(Code Review)可以带来以下好处: 不要吝啬你的赞赏和鼓励,如果你在CD中看到了不错的内容,也可以添加comments表示鼓励,并写清楚好的点并由开发者进行补充,或者直接告诉开发人员,尤其是当他们以出色的方式处理你的Comments时。Reviewers通常只关注错误,但他们也应该为良好实践提供鼓励和赞赏。有时,在指导方面,告诉开发人员他们做对了什么比告诉他们做错了什么更有价值。我们每周五都会组织会议对项目进行一次深度的Review,让大家工作对出现的问题和优秀的代码进行点评和学习,这里学习就达到了共同学习的目的。

【1】提高代码质量: 通过多个开发人员对代码进行审查,可以发现潜在的错误、缺陷和不规范的代码,从而改善代码质量。
【2】提升团队合作: 代码评审是团队成员之间的合作过程,可以促进团队成员之间的沟通和交流,增强团队合作意识。
【3】学习和知识分享: 代码评审是一个学习的机会,通过审查他人的代码,可以学习到新的编码技巧和最佳实践,同时也可以分享自己的知识和经验。
【4】减少维护成本: 通过及时发现和修复问题,可以减少后续维护和调试的成本,提高代码的可维护性。
【5】提高系统安全性: 代码评审可以帮助发现潜在的安全漏洞和风险,从而提高系统的安全性。
【6】增强代码一致性: 通过代码评审,可以确保代码符合团队或组织的编码规范和标准,提高代码的一致性和可读性。

总而言之,代码评审是一个重要的质量控制和团队协作的过程,可以提高代码质量、减少错误、促进团队合作,并提升整体开发效率。

二、CodeReview 标准

为什么需要指定规范: 当你尝试在团队中实施有效的代码审查流程时,会遇到许多挑战。例如:代码审查的comments是否被认同,是否是错的等,做不好甚至会损害你的人际关系。因此需要一套标准,SubmitterReviewers都需要一个指南针来进行建设性和尊重的代码审查。

CodeReview规范推荐: 阿里巴巴开发手册【泰山版】
书籍推荐:《代码整洁之道》《重构》《代码审查之道》《代码审查实战》《代码审查艺术》

【1】代码可读性: 变量、函数和类的命名清晰、有意义:一个好的名称可以充分传达该项目是什么或做什么,而不会太长以至于难以阅读。

// Good example
String customerName = "John Doe";// Bad example
String x = "John Doe";

代码缩进和格式一致:

// Good example
if (condition) {statement1;statement2;
}// Bad example
if (condition) {
statement1;
statement2;
}

注释清晰明了:

// Good example
// Calculate the sum of two numbers
public int addNumbers(int a, int b) {return a + b;
}// Bad example
public int addNumbers(int a, int b) {return a + b; // Add the numbers
}

【2】代码结构和组织: 模块化和功能分离:避免过大的类,一个类做太多事情,维护了太多功能,可读性变差,性能也会下降。Duplicated Code也就接踵而至了。

// Good example
// UserService.java
public class UserService {public void createUser() {// Create a new user}
}// OrderService.java
public class OrderService {public void createOrder() {// Create a new order}
}// Bad example
public class UserServiceAndOrderService {public void createUserAndOrder() {// Create a new user and order}
}

避免冗余代码和重复逻辑: 一般是因为需求迭代比较快,开发小伙伴担心影响已有功能,就复制粘贴造成的。重复代码很难维护的,如果你要修改其中一段的代码逻辑,就需要修改多次,很可能出现遗漏的情况。优化手段: 可以使用​​Extract Method提取公共函数,抽出重复的代码逻辑,组成一个公用的方法。

// Good example
public double calculateAverage(List<Double> numbers) {double total = numbers.stream().mapToDouble(Double::doubleValue).sum();return total / numbers.size();
}// Bad example
public double calculateAverage(List<Double> numbers) {double total = 0;for (Double number : numbers) {total += number;}return total / numbers.size();
}

过长参数列Long Parameter List 方法参数数量过多的话,可读性很差。如果有多个重载方法,参数很多的话,有时候你都不知道调哪个呢。并且,如果参数很多,做新老接口兼容处理也比较麻烦。

// Good example
public void getUserInfo(UserInfoParamDTO userInfoParamDTO){// do something ...
}class UserInfoParamDTO{private String name;private String age; private String sex;private String mobile;
}
// Bad example
public void getUserInfo(String name,String age,String sex,String mobile){// do something ...
}

【3】错误处理和异常处理: 检查和处理可能的异常情况:

// Good example
public double divide(double a, double b) {if (b != 0) {return a / b;} else {throw new IllegalArgumentException("Cannot divide by zero");}
}// Bad example
public double divide(double a, double b) {return a / b; // No handling for zero division
}

使用适当的错误处理机制:

// Good example
try {// Code that may throw an exception
} catch (IOException e) {// Handle the specific exception
}// Bad example
try {// Code that may throw an exception
} catch (Exception e) {// Handle all exceptions generically
}

【4】性能和效率: 避免不必要的循环和重复计算,减少时间复杂度:简单来说就是代码中if/case/for/while出现的次数。圈复杂度越高,BUG率越高。如果一个方法的圈复杂度达到5或者更高,那么CR时就要多看两眼。太复杂通常意味着“无法被开发者快速理解”。这也可能意味着“开发人员在尝试调用或修改此代码时可能会引入错误”。

// Good example
int sum = 0;
for (int i = 0; i < array.length; i++) {sum += array[i];
}// Bad example
int sum = 0;
for (int i = 0; i < array.length; i++) {for (int j = 0; j < array.length; j++) {sum += array[j];}
}

使用适当的数据结构和算法:

// Good example
List<Integer> numbers = new ArrayList<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
boolean contains = numbers.contains(2);// Bad example
int[] numbers = {1, 2, 3};
boolean contains = false;
for (int i = 0; i < numbers.length; i++) {if (numbers[i] == 2) {contains = true;break;}
}

【5】安全性: 避免使用不安全的函数和方法:

// Good example
String sanitizedInput = input.replaceAll("<script>", "");// Bad example
String sanitizedInput = input.replace("<script>", "");

防止代码注入和安全漏洞:

// Good example
PreparedStatement statement = connection.prepareStatement("SELECT * FROM users WHERE username = ?");
statement.setString(1, username);
ResultSet resultSet = statement.executeQuery();// Bad example
String query = "SELECT * FROM users WHERE username = '" + username + "'";
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);

【6】可测试性: 编写可测试的代码单元:

// Good example
public int add(int a, int b) {return a + b;
}// Bad example
public void doSomething() {// Perform some complex logic
}

使用适当的测试框架和工具进行单元测试:

// Good example (using JUnit)
@Test
public void testAdd() {Calculator calculator = new Calculator();int result = calculator.add(2, 3);assertEquals(5, result);
}// Bad example
public void testAdd() {Calculator calculator = new Calculator();int result = calculator.add(2, 3);if (result != 5) {throw new AssertionError("Addition test failed");}
}

【7】可维护性: 遵循设计原则和最佳实践:

// Good example (using SOLID principles)
public interface Shape {double calculateArea();
}public class Circle implements Shape {private double radius;public Circle(double radius) {this.radius = radius;}public double calculateArea() {return Math.PI * radius * radius;}
}// Bad example
public class Circle {public double calculateArea(double radius) {return Math.PI * radius * radius;}
}

避免过于复杂和冗长的代码:

// Good example
public void processOrder(Order order) {validateOrder(order);calculateTotalPrice(order);updateInventory(order);sendConfirmationEmail(order);
}// Bad example
public void processOrder(Order order) {// A long and complex method with multiple nested if-else statements
}

【8】可扩展性: 使用适当的设计模式和架构:设计模式全集

// Good example (using the Factory pattern)
public interface Animal {void makeSound();
}public class Dog implements Animal {public void makeSound() {System.out.println("Woof!");}
}public class Cat implements Animal {public void makeSound() {System.out.println("Meow!");}
}// Bad example
public class Animal {public void makeSound(String type) {if (type.equals("dog")) {System.out.println("Woof!");} else if (type.equals("cat")) {System.out.println("Meow!");}}
}

【9】关注性能问题: 性能问题虽然不常见,可一旦暴雷往往就是大问题。下面是一些CR时通常需要关注的点。
  ■ 不要在循环中操作数据库或者调用远程服务。
  ■ 如果可以的话,使用数组实现的集合类型时预估大小。
  ■ 不要在循环中使用try…catch…,应该把其放在最外层。
  ■ 变量不要重复计算。

// Good example
for (int i = 0, length = list.size(); i < length; i++) {...} // Bad example
for (int i = 0; i < list.size(); i++) {...}

  ■ 循环内不要不断创建对象引用。

// Good example
Object obj = null;
for (int i = 0; i <= count; i++) {obj = new Object();
} // Bad example
for (int i = 1; i <= count; i++) {Object obj = new Object();
}

  ■ 异常只能用于错误处理,不应该用来控制程序流程。
  ■ 字符串拼接 尽量使用StringBuilder/StringJoiner
【10】关注分布式事务: 涉及远程服务调用,或者跨库更新的场景,都应考虑是否存在分布式事务问题,以及适用何种处理方式,是依赖框架保证强一致性,还是记录异常数据保证最终一致性,抑或是直接忽略?
【11】关注架构设计: 代码有代码规范,架构有架构规范。面对一个新功能的CD,除了检查架构规范,还应推敲其架构设计,比如是否符合整洁架构三原则,无依赖环原则,稳定依赖原则,稳定抽象原则。如果阅读代码有些困难,减CR的速度,应该找到对应的作者,让其解释沟通清楚,然后再尝试审查它。如果你看不懂代码,其他开发人员很可能也不会。因此,当你要求开发人员对其进行解释时,你也在帮助未来的开发人员理解此代码。

常见CR缺陷:
可能死循环;
传递引用错误;
类型转换错误;
公式计算错误;
数组可能越界;
条件范围选择错误;
除数为0、整数溢出、精度损失;
字符串对比不能用==,使用equals
finally程序块中关闭或者释放资源;
锁的获取和释放是有序的,避免死锁情况的发生;
UT是否覆盖所有场景,测试案例是否存在遗漏场景;
异常未处理或提示不明确(没有catch异常,集合等没有判空和长度为0);
日志埋点信息输出需有意义,需具有可读性,可供日常开发同学排查线上问题;
是否正确处理了共享数据的并发访问,确保对共享资源的操作是原子的,避免出现数据竞争问题;
对于连接池、线程池等共享资源,需要适当地设置和管理资源池的大小,避免资源耗尽或资源浪费的问题;
多个线程相互等待对方释放所持有的资源,导致程序无法继续执行。需要确保对锁的获取和释放是有序的,避免死锁情况的发生;
检查代码中对并发集合的使用,例如ConcurrentHashMapConcurrentLinkedQueue等。确保对并发集合的操作是线程安全的;
检查代码中对数据的读写操作,确定在多线程环境下是否会出现数据不一致的问题。需要使用适当的同步机制来保证数据的一致性
避免在循环中频繁使用字符串拼接操作,尤其是在大型循环中。建议使用StringBuilderStringBuffer来进行字符串拼接,以提高性能;
检查数据库查询和更新操作是否高效。避免频繁的数据库交互,可以考虑使用批处理操作、适当的索引以及缓存机制来提高性能;
检查代码中是否存在频繁的磁盘或网络I/O操作,这些操作通常是性能瓶颈之一。可以考虑合并操作、异步操作或使用缓冲机制来提高性能;

重点检查项:
结构性检查:程序的每个功能是否都作为一个可辨识的代码块存在;
可验证性检查:代码功能是否便于测试;单元测试覆盖度是否足够;
可预测性检查:变量初始化;方法稳定性;代码是否存在死循环;代码无穷递归检查;
高可用性检查:是否有预案(降级开发、限流配置、兜底策略);补偿方案是否合理;
可追溯性检查:代码是否包括一个修订历史记录,记录中对代码的修改和原因都有记录;
完整性检查:服务层是否包含了所有业务功能;数据层是否包含所有需要的数据和操作;
正确性检查:计算逻辑等业务逻辑是否正确;变量是否被正确定义和使用;代码是否符合制定的标准;
健壮性检查:代码是否采取措施避免运行时错误(如数组边界溢出、被零除、值越界、堆栈溢出等);
一致性检查:是否需求相关;是否和方案设计一致;代码风格、日志规范、异常处理等是否和统一规范一致;
可理解性检查:是否使用到不明确或不必要的复杂代码;代码中的算法是否符合开发文档中描述的数学模型;每个变量都定义了合法的取值范围;
可修改性检查:代码涉及到常量是否易于修改,比如使用配置,定义为常量类等;建议业务方法只有一个出口和一个入口(异常处理除外);重要公共方法是否有交叉注释说明;重要的对外方法修改后影响多个下游接口;

三、如何编写CodeReview

【1】态度&位置: CodeReview者需要保持一个虚心请教的态度发表评论,因为彬彬有礼的人才能够让着团队向更好的方向发展。
  ■ 优秀评语: “你的代码整体结构清晰,逻辑合理,很容易理解。你在变量和方法命名上也很注重描述性,这有助于他人快速理解你的意图。不过,在这段代码中,我注意到了一个潜在的性能问题。在第15行的循环中,你每次都在循环内部调用了一个耗时的方法。建议你将这个方法的结果缓存起来,以避免重复计算。这样可以提高代码的效率。除此之外,你的代码注释也可以更加详细一些,帮助其他人更好地理解你的思路。继续保持优秀的工作!”
  ■ 坏的评语: “你的代码结构乱七八糟,根本看不懂。变量和方法命名也太随意了吧!这段代码简直就是垃圾。你在第15行的循环中做了一个非常愚蠢的错误,每次都在循环内部调用一个耗时的方法,你是怎么想的?你的代码注释也太少了吧,根本看不出你在想什么。你需要好好反思一下你的编码能力。”
【2】解释清楚为什么: 因为每个人的阅历和所想的不同,所以Reviewers应该尽量让开发者明白为何会有这一次CommentsReviewers并不总是需要在Comments中包含这些信息,但有时对Comments的意图、遵循的最佳实践或建议进行更多解释是很有必要的。
【3】提出改进方案和该方案的优点: Reviewers应该在指出问题和提供直接指导之间取得适当的平衡。指出问题并让开发人员做出决定通常有助于开发人员学习,并使代码审查变得更容易。它还可以产生更好的解决方案,因为开发人员比审阅者更接近代码。

有时开发人员会推迟代码审查。要么不同意Reviewers的建议,要么抱怨Reviewers总体上过于严格。

上面的问题,最主要的是先弄清楚谁是是对的,因为开发者比你更了解整个系统的业务逻辑和架构,你的意见可能不适合该系统或架构,因此需要友好的交流,让他们知道他们的代码是对的,继续保持,自己则更进一步的了解整个系统和架构,避免第二次犯同样的错误。如果交流后发现你是对的,问题在开发者,就需要搞明白为什么开发者不愿意修改。是因为修改Comment带来的代码质量改进需要花费额外的工作,还是因为项目需要积极发布,修改Comments影响过大,时间上不允许等等。都需要根据自己的团队给出合理的解决方案。

举个例子:稍后清理 开发者不想为了解决这个Comments而进行额外工作,而且需要今天紧急发布,Comment回复在后期的工作中进行清理工作。但是经验表明,清理工作会在其他工作的压力下丢失或被遗忘,这并不是因为开发人员不负责任。我们的解决办法是:如果Comments引入了新的复杂性,除非是紧急情况,否则必须在提交之前对其进行清理。如果Comments现在无法解决,开发人员应该提交一个bug并将其分配给自己,这样它就不会丢失。

Reviewers有时认为,如果自己坚持要求改进,开发人员会感到不安。有时开发人员确实会感到沮丧,但这通常是短暂的,他们稍后会非常感谢你帮助他们提高代码质量。通常,如果你的评论有礼貌,开发人员实际上根本不会生气。不安通常是因为Comments的编写方式,而不是Reviewers对代码质量的坚持。

建议:
【1】CR就像读书,先看目录(改动的文件列表),再精读重点章节(包含核心业务逻辑的代码),最后扫读剩余章节。
【2】如果改动的文件数量较多,可以打开IDE,切换到源分支,方便在CR过程中随时打开相关代码进行阅读。
【3】如果MR提交者对评审意见提出异议,评审者应找提交者当面讨论,避免在评论区互踢皮球。
【4】合并代码之前应确保所有评审意见都被妥善处理。

四、什么时候进行CodeReview

问题一:我们CodeReview工作者基本都是一个开发者,手里有很多工作在做,而且大部分需求都集中在发布日当天进行CodeReview,因此CR的时间和质量就成了一个新的挑战。
问题二:CodeReview慢时,会导致开发者新功能的错误修复延迟,从而增加了返工重构的工作量,降低开发效率。

规范:一个工作日是响应CR请求。越接近软件发布的最终期限,代码也就不能改得太多,因为此时没有测试再帮忙回归了。

五、Commit Message

GitLab Commit MessageCR时的作用也很重要,一个好的Git Commit Message应该能够清晰点明主题,是bug还是feature还是doc的完善,应该让Reviewers一目了然。我们在日常使用GitLab提交代码时经常会写commint message,否则就不允许提交。我们常用的模板如下:

feat(版本号):需求名 - 核心内容
feat: 更改的内容详细说明
属性说明
feat新功能点
fix修改bug
docs文档类修改
style样式lesscss文件修改
refactor重构/优化,提高代码质量等
chore含义为苦力,本分支的事情和功能没关系(比如:配置,升级node包…)
test单元测试代码
build就是打个build,一般就是在发布新版本的时候,你需要更新一下package.json,然后提交到git去自动部署,这个时候就可以用build,比如build: v1.2.0
factorcici相关的一些修改,大概率是ci的配置文件修改
perf就是单纯的性能优化,比如你们如果遇到了性能瓶颈,然后需要提交一些代码去解决这些性能问题,就可以用perf: enhance performance on xxx page

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/736097.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VScode的列选

可以用来优化代码排布&#xff0c;让变量整齐成为一排 一、批量复制&#xff1a; 在1处左键单击&#xff0c;然后摁住SHIFTALT键的同时&#xff0c;左键单击2处&#xff0c;即可复制一整块的内容 如果所示 就可以复制了 二、批量输入 在1处左键单击&#xff0c;然后摁住SHI…

基于斑翠鸟优化算法(Pied Kingfisher Optimizer ,PKO)的无人机三维路径规划(MATLAB)

一、无人机路径规划模型介绍 二、算法介绍 斑翠鸟优化算法&#xff08;Pied Kingfisher Optimizer ,PKO&#xff09;&#xff0c;是由Abdelazim Hussien于2024年提出的一种基于群体的新型元启发式算法&#xff0c;它从自然界中观察到的斑翠鸟独特的狩猎行为和共生关系中汲取灵…

Linux系统中的任务迁移技术

任务迁移技术是指将任务从一个处理器核心&#xff08;CPU核心&#xff09;移动到另一个核心的过程&#xff0c;以实现负载均衡、优化系统性能或者其他系统目标的技术。任务迁移技术在多核系统中具有重要的作用&#xff0c;可以通过动态调整任务位置来避免负载不均衡和性能瓶颈&…

【工具】Git的24种常用命令

相关链接 传送门&#xff1a;>>>【工具】Git的介绍与安装<< 1.Git配置邮箱和用户 第一次使用Git软件&#xff0c;需要告诉Git软件你的名称和邮箱&#xff0c;否则无法将文件纳入到版本库中进行版本管理。 原因&#xff1a;多人协作时&#xff0c;不同的用户可…

恒驰上云规划实施解决方案上线华为云官网

华为云与伙伴共同打造联合解决方案 已成为更多企业的数字化转型利器 1月恒驰上云规划实施解决方案 完成上市宣讲并正式上架华为云官网 恒驰上云规划实施解决方案能力全景图&#xff1a;融合厂商云服务能力&#xff0c;一站式高效云迁移 从深入了解企业的本地IT环境、业务特点…

分享一下 iOS 发布/测试证书 申请过程

1.使用 已开通iOS开发者 的账号登陆 Apple Developer Apple Developer 2.点击下图右上角的 Account&#xff08;账户&#xff09; 点击下图中的 certificates&#xff08;证书&#xff09; 然后会挑战至下图所示页面 3.然后先要注册一个 App id 点击 register 就完成了 4.…

【JAVA】CSS2:样式、选择器、伪类、颜色、字体、边框、列表、背景、盒子、布局、浮动

本文介绍了CSS样式、选择器、伪类、像素、颜色、字体、边框、列表、表格属性、背景、盒子、布局与浮动 1.样式 1.1 行内样式 <h1 style"color: aqua;font-size: large;">123</h1> 1.2 内部样式 <style>h1{color: red;font: 100;}</style>…

Oracle SQL优化(读懂执行计划 一)

目录 SQL执行计划的作用示例演示执行计划概念介绍执行计划实例DISPLAY_CURSOR 类型DISPLAY_AWR 类型 指标详解 SQL执行计划的作用 示例演示 执行计划概念介绍 执行计划实例 DISPLAY_CURSOR 类型 DISPLAY_AWR 类型 指标详解

vim基础命令

目录 前言 一.vim基础命令大全 二.vim熟练的好处 三.入门使用命令 四.使用案例 4.1 gg和G 4.2 i 和 u 和 ESC使用 4.3 y$ 和 p 和 u 使用 五.注意事项 前言 启动vim编辑器后自动进入编辑模式&#xff0c;在此模式中输入命令对应vim一个动作&#xff0c;比如&#xff1a;进入编辑…

linux 配置jdk环境变量

1.确保已上传jdk包到指定目录 2.打开终端&#xff0c;使用文本编辑器&#xff08;比如vi、nano等&#xff09;创建或修改~/.bashrc文件。命令为&#xff1a; sudo vi ~/.bashrc3.在.bashrc文件末添加以下内容&#xff1a; export JAVA_HOME/usr/local/jdk/jdk1.8.0_391 #将…

理解STM32的低功耗模式

低功耗模式简介 TM32的低功耗模式是特别设计来减少微控制器在不活跃状态下的能耗。这些模式允许STM32在保持核心功能的同时尽可能减少电力消耗&#xff0c;适合用在电池供电或需长期运行的场景。理解各种低功耗模式如何节能&#xff0c;主要包括以下几个方面&#xff1a; 关闭…

C++类和对象(下篇)

目录 一.再谈构造函数 二.static成员 三.友元 四.内部类 五. 再次理解类和对象 一.再谈构造函数 1.构造函数体赋值 在创建对象时&#xff0c;编译器通过调用构造函数&#xff0c;给对象中各个成员变量一个合适的初始值。 class Date { public:Date(int year, int month…

MES系统是怎么进行数据采集的?

在MES管理系统中&#xff0c;数据采集作为最基础也最为关键的一环&#xff0c;对于实现生产过程的透明化、可控好以及优化生产流程具有重要意义。 mes系统是怎么采集数据的? 一、PLC类数据采集&#xff1a;使用C#或C直接编程访问PLC(不需要花钱买组态软件或第三方软件) 二、…

HTML 学习笔记(四)图片

<!--通过图片标签"<img src "图片路径">"来调用图片在网页中进行显示--> <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthd…

PostgreSQL索引篇 | GiST索引

GiST索引 PostgreSQL版本为8.4.1 &#xff08;本文为《PostgreSQL数据库内核分析》一书的总结笔记&#xff0c;需要电子版的可私信我&#xff09; GiST&#xff08;Generalized Search Tree&#xff0c;通用搜索树&#xff09;是一种平衡的、树状结构的访问方法。 它在系统中…

【数学建模】传染病模型笔记

传染病的基本数学模型&#xff0c;研究传染病的传播速度、空间范围、传播途径、动力学机理等问题&#xff0c;以指导对传染病的有效地预防和控制。常见的传染病模型按照传染病类型分为 SI、SIR、SIRS、SEIR 模型等&#xff0c;按照传播机理又分为基于常微分方程、偏微分方程、网…

Redis特性与应用场景

Redis是一个在内存中存储数据的中间件&#xff0c;用于作为数据库&#xff0c;用于作为数据缓存&#xff0c;在分布式系统中能够发挥重要作用。 Redis的特性 1.In-memory data structures: MySQL使用表的方式存储数据&#xff0c;这意味着数据通常存储在硬盘上&#xff0c;并且…

python 网络库集锦

目录 通用网络库 网络爬虫框架 1.功能齐全的爬虫 2.其他 HTML/XML解析器 1.通用 2.清理 文本处理 自然语言处理 浏览器自动化与仿真 多重处理 异步网络编程库 队列 云计算 网页内容提取 WebSocket DNS解析 计算机视觉 通用网络库 1.urllib -网络库(stdlib)。…

【MATLAB】语音信号识别与处理:一维信号NLM非局部均值滤波算法去噪及谱相减算法呈现频谱

1 基本定义 一维信号NLM非局部均值滤波算法是一种基于非局部均值思想的滤波方法&#xff0c;它通过对信号进行分块&#xff0c;计算每个块与其他块之间的相似度&#xff0c;以非局部均值的方式去除噪声。该算法的主要思想是在一定范围内寻找与当前块相似的块&#xff0c;以这些…

分享一些实用性的大语言模型(GitHub篇)

1.多模态大模型 GitHub网址&#xff1a;haotian-liu/LLaVA&#xff1a;[NeurIPS23 Oral] 视觉指令调优 &#xff08;LLaVA&#xff09; 构建&#xff0c;旨在实现 GPT-4V 级别及以上的能力。 (github.com) 下面是LLaVA模型的介绍&#xff0c;作者都有一直维护和更新&#xff0c…