当前位置: 首页 > news >正文

《编写可读代码的艺术》读书笔记

1. 写在前面

借着春节放假的几天, 读了下《编写可读代码的艺术》这本书, 这本书不是很长,主要关注代码的一些编写细节,比如方法命名,函数命名,语句组织,任务分解等, 旨在让写的代码更加鲁棒,便于维护以及便于让别人理解。写的还是很不错的,所以这边文章整理一些不错的编码细节。

大纲如下:

  • 1. 写在前面
  • 2. 表面层次的改进
    • 2.1 起名字
    • 2.2 不会误解的名字
    • 2.3 审美
    • 2.4 注释
  • 3. 简化循环和逻辑
    • 3.1 控制流变得易读
    • 3.2 拆分超长的表达式
    • 3.3 变量与可读性
  • 4. 重新组织代码
    • 4.1 抽取不相关的子问题
    • 4.2 一次只做一件事情
    • 4.3 想法变成代码
    • 4.4 少写代码
  • 5. 测试与可读性
  • 6. 小总

2. 表面层次的改进

我们写代码的时候,考虑的最重要的一个原则应当是易于让别人理解的,代码的写法应当使得别人理解它使用的时间最小化, 这是作者书中提到的可读性的基本原理, 提高代码的可读性在实际中非常重要, 我们可以先从表面层次开始。

表面层次包括:选择好的名字、写好的注释、把代码整洁成更好的格式

2.1 起名字

关键思想:

给变量、函数、类起名字的时候, 要把信息装在名字中

介绍了6个常用的小方法:

  1. 起名字的时候,选择比较专业的词,避免"空洞"的次, 名字表达的信息越具体越好

    # 一个反例
    def GetPage(url)# get 这个词没有很多信息,这个方法是从本地缓存中得到页面,还是数据库,还是网页?  get比较宽泛,更专业的词FetchPage or DownloadPage等,更加具体
    

    另外可以找更有表现力的词, 清晰和精确比装可爱好。 比如:send -> deliver,dispatch,announce, find -> search, extract,locate, start -> launch, create, begin, open make -> create, build, add

  2. 好的名字应当描述变量的目的或它所承载的值,少用tmp和retrtval这样泛泛的名字

    # retval 除了表示返回一个值, 没有更多信息
    # 如果想计算平方和, 用sum_squares 比 retval要好很多# tmp这个名字也只应用于短期存在且临时性为主要存在因素的变量
    
  3. 循环迭代器里面往往喜欢用i,j,k这样的变量, 这个在多层循环里面不是个好的主意, 可以加上迭代器变量自身的信息

    for i in range(len(clubs)):for j in range(len(clubs[i].members)):for k in range(len(users)): ....# 换成
    for ci in range(len(clubs)):for mj in range(len(clubs[ci].members)):for uk in range(len(users)):...
    
  4. 具体的名字替代抽象的名字, 比如,假设有一个内部方法叫ServerCanStart(), 检测服务是否可以监听某个给定的TCP/IP端口。 但这个名字有点抽象,换成CanListenOnPort()更具体。

  5. 名字附带更多信息, 比如带上变量格式, 单位,其他重要的信息等

    # 格式
    id -> hex_id# 单位信息
    timestamp -> timestamp_ns
    delay -> delay_secs
    size -> size_mb
    limit -> max_kbps
    angle -> degree_cw# 其他重要信息: 如果变量表示的有需要理解的关键信息, 就把这个信息放到名字里面
    password -> plaintext_password
    comment -> unescapted_comment
    html -> html_utf8
    data -> raw_data
    
  6. 为作用域大的名字采用更长的名字,作用域小的用较短的名字, 使用缩略词和缩写的原则是团队的新成员是否能理解名字的含义, 比如把BackEndManager写成BManager可能更令人费解。

  7. 利用名字的格式来传递含义, 对不同的实体使用不同的格式,比如可以在类成员变量加_区分开普通变量

    # 有目的的使用大小写, 下划线等
    # 常量 AGE = 10
    # 类变量 age_
    # 普通变量  age
    

2.2 不会误解的名字

起名字时, 要考虑下是否会让别人产生误解,比如Filter这个名字, 可能过滤不好的,也可能保留好的,这样的名字直接看就有问题。类似的length, limit等。

这里也介绍了几个小技巧:

  1. 推荐用minmax来表示包含的极限, 即最大和最小取到多少, max_age, min_age
  2. 推荐用firstlast表示包含的范围
  3. 推荐用beginend表示起始位置和终止位置(终止位置的意思是最后一个元素的后一个位置,注意和上面的last区分)
  4. 给布尔值也命名,即赋予逻辑含义,比如is_xxx, has_xxx, can_xxx等,并且最好避免使用反义的名字,比如not_xxx,
  5. 小心用户对特定词的期望, 这个的意思是, 用户一般认为get(), size()这种方法是轻量级的方法, 可以直接索引到或用很简单的方式就能拿到,如果定义了一个方法,里面有比较大的计算量,就避免用get_xxx()来命名, 可以用count_xxx()

2.3 审美

审美主要是包括代码的布局, 这里介绍的一些技巧:

  1. 如果多个代码块作相似的事情, 尝试用同样的格式和布局
  2. 把代码按 “列” 对齐,可以让代码更容易浏览
  3. 如果一段代码中提到A,B和C, 后面就一直保持这个顺序
  4. 用空行把大块的代码,逻辑上分成多个段落

2.4 注释

注释的目的是尽量帮助读着了解的和作者一样多,所以注释的写法也是有讲究的。

  1. 不需要写注释的情况: 从代码本身就能快速推断的事实, 不好的名字

    # 类的定义
    class XXX# 初始化def __init__(self):...# 上面的这种注释没有意义# 如果起的名字不好,不要写注释,而是把名字起好: 好代码 > 坏代码 + 好注释
    
  2. 注释的作用

    1. 记录思想: 比如为什么写成这样而不是那样的理由, 指导性批注, 一些背景知识等
    2. 代码中的瑕疵: 使用TODO, FIX, HACK等进行标记
    3. 常量加注释: 常量的介绍,为什么是这个值等
  3. 站在读者的角度

    1. 预料到代码中哪些部分会让读者看不懂
    2. 为普通读者意料之外的行为加注释
    3. 文件/类的级别上使用"全局观"注释来解释所有的部分是如何一起工作的
    4. 用注释来总结代码块, 使读者不迷失在细节中
  4. 写出言简意赅的注释

    1. 注释保持紧凑, 有很高的信息/空间率
    2. 避免使用it和this这样的代词
    3. 尽量精确的描述函数的行为
    4. 注释中用精心挑选的输入/输出的例子说明
    5. 声明代码的高层次意图,而非明显的细节
    6. 用嵌入的注释(如Function(/*arg=*/...))解释难以理解的函数参数
    7. 用含义丰富的词来使注释更简洁

3. 简化循环和逻辑

改变程序的“循环和逻辑”,可以让代码更有可读性。

一个原则:尽量减少代码中的"思维包袱", 思维包袱越多, 需要考虑复杂并记住更多事情,与容易理解恰好相反。

3.1 控制流变得易读

几种方法:

  1. 写一个比较时(while (bytes_expected > bytes_received)), 把改变的值写在左边并且把稳定的值写在右边会更好

  2. 可以重新排列is/else语句块, 一般先处理正确的/简单的/有趣的情况

  3. 某些变成结果,像三目运算符,do-while循环,goto最后不使用,会导致可读性变差

  4. 嵌套的代码块需要更加集中精力去理解,每层新的嵌套都需要读者把更多的山下文"压入栈", 应该改写成更"线性"的代码

  5. 提早return可以减少嵌套使得代码更加整结, 保护语句(函数顶部处理简单情况)很有用

    def xxx(value):# 保护代码if value == "xxx": return Trueif xxx: return xxxif xxx: return xxx# 逻辑代码...
    

3.2 拆分超长的表达式

几种方法:

  1. 引入"解释性变量",代表较长的子表达式

    username = line.split(":")[0].strip()
    if username == "xxx": ...users_owns_docement = (requests.user.id == document.owner.id)
    if user_owns_docement: ...
    
  2. 德摩根定理操作逻辑表达式 (if (!(a && b)) ⇒ if (!a || !b)

  3. 更复杂的逻辑表达拆分

3.3 变量与可读性

尽量减少变量的数量和让它们"轻量级", 来让代码更有可读性。

  1. 减少变量,即妨碍的变量,并减少中间结果

    now = datetime.datetime.now()
    root_message.last_view_time = now# 这个now在这里就没有意义, 没有拆分复杂的表达式,也没有做更多的澄清,只用过一次
    root_message.last_view_time = datetime.datetime.now()
    
  2. 减少每个变量的作用域, 越小越好,尽量避免使用全局变量,因为修改了可能不知道

  3. 只写一次的变量更好,比如const, final, 常量,使得代码更容易理解,一个变量操作的越多, 就越难确定值。

4. 重新组织代码

在函数级别对代码做更大的改动,使得逻辑更加清晰。

4.1 抽取不相关的子问题

写代码时, 要把和项目不相关的代码单独拿出来, 写成一个工具库供主程序调用。这样可以使得我们关注小而定义良好的问题。

纯工具代码Utils,独立的小模块,独立的小函数等都属于这个范畴, 这样在后期维护(添加功能,改进可读性,处理边界等)变得很容易。

现在我写代码的时候,一般会有utils目录,存放一些工具函数, consts存放一些常用变量等。

4.2 一次只做一件事情

forcus, 在写代码中非常使用,一个组织代码的技巧: 一次只做一个事情。如果有很难读的代码,尝试把它所做的所有任务先列出来,其中一些任务拆分成单独的函数 或 类, 其他的可以简单成为函数中的逻辑"段落", 小事情越具体,越容易拆分,也是很有挑战的一件事情。

4.3 想法变成代码

这里主要是介绍了一个简单的技巧:用自然语言描述程序 然后用这个描述来帮助写出更自然的代码, 这个就是把一个大的问题先拆解开,然后用自然语言去描述,有点像“如何把大象装进冰箱的意思"

4.4 少写代码

最好读的代码就是没有代码, 我们很容易乐观的估计一个粗糙原型所花的时间, 但忘了将来的维护时间和成本, 所以最后的一个建议是,不要过度设计项目,减少不必要的代码,重新考虑需求,解决版本最简单的问题,另外是经常性的阅读标准库的整个API,保持对它们的熟悉程度,不要重复造轮子

每隔一段时间, 花15分钟阅读标准库中的所有函数/模块/类型的名字

5. 测试与可读性

这一部分属于比较精细的话题了,如何写出有效且可读的测试。

几个要点如下:

  1. 每个测试的最高一层应该越简明越好, 最后每个测试的输入/输出可以用一行代码描述

    def CheckXXX(input, expected_output):# 处理逻辑# 最外层的测试函数不要有过多的实现细节output = Getoutput(input)assert (output == expected_output)
    
  2. 错误消息要尽量的有可读性,这样测试失败,可以更快跟踪问题, 比如python测试的时候,可以用unittest的测试库,比较专业

    import unittest
    class MyTestCase(unittest.TestCase):def testFunction(self):a = 1b = 2self.assertEqual(a, b)unittest.main()
    

    手工打造报错信息也可以。

  3. 使用最简单且能够完整运用代码的测试输入

  4. 给测试函数取一个完整描述性的名字,使得每个测试所测到的东西很明确,不要用Test1(), 用像Test_functionname_situation这样的名字

总之,测试要易于改动和增加新的测试。

6. 小总

过年在家, 用了3个晚上, 看完了这本书, 这本书篇幅不是很长, 读完了之后还是受益匪浅的, 里面有一些细节确实之前没有在意, 想用这篇文章大概把这本书的一些方法论整理出来,后面还是得需要实践去巩固,在实践的过程中慢慢的巩固这些方法论吧。

2025年的第一篇博客,新年快乐, 继续加油哇 😉

相关文章:

《编写可读代码的艺术》读书笔记

1. 写在前面 借着春节放假的几天, 读了下《编写可读代码的艺术》这本书, 这本书不是很长,主要关注代码的一些编写细节,比如方法命名,函数命名,语句组织,任务分解等, 旨在让写的代码…...

(9)下:学习与验证 linux 里的 epoll 对象里的 EPOLLIN、 EPOLLHUP 与 EPOLLRDHUP 的不同。小例子的实验

(4)本实验代码的蓝本,是伊圣雨老师里的课本里的代码,略加改动而来的。 以下是 服务器端的代码: 每当收到客户端的报文时,就测试一下对应的 epoll 事件里的事件标志,不读取报文内容,…...

MySQL基础-多表查询

多表查询-多表关系 多表查询-概述 例如执行下行sql语句就会出现笛卡尔积: select *from emp,dept; --消除笛卡尔积 select * from emp,dept where emp.dept_id dept.id; 多表查询-查询分类 多表查询-连接查询-内连接 --内连接演示 --1.查询每一个员工的姓名,及关…...

RK3568 opencv播放视频

文章目录 一、opencv相关视频播放类1. `cv::VideoCapture` 类主要构造方法:主要方法:2. 视频播放基本流程代码示例:3. 获取和设置视频属性4. 结合 FFmpeg 使用5. OpenCV 视频播放的局限性6. 结合 Qt 实现更高级的视频播放总结二、QT中的代码实现一、opencv相关视频播放类 在…...

C++中的类型转换

文章目录 一、概述二、隐式类型转换(Implicit Conversion)三、显式类型转换(Explicit Conversion)四、C 风格类型转换 一、概述 C 提供了多种类型转换(Type Conversion)方式,以便在不同类型的数…...

day7手机拍照装备

对焦对不上:1、光太暗;2、离太近;3、颜色太单一没有区分点 滤镜可以后期P 渐变灰滤镜:均衡色彩,暗的地方亮一些,亮的地方暗一些 中灰滤镜:减少光差 手机支架:最基本70cm即可 手…...

Joplin 插件在Vscode中无法显示图片

1.问题 在vscode里面装好joplin插件之后,无法显示图片内容。 粘贴的图片可以再vscode中显示,无法再joplin客户端显示 2.解决方法 这种情况是因为和vscode自带的MD编辑器的预览模式有冲突,或者没用通过专用方式上传图片。 方法一&#xff…...

ReentrantReadWriteLock源码分析

文章目录 概述一、状态位设计二、读锁三、锁降级机制四、写锁总结 概述 ReentrantReadWriteLock(读写锁)是对于ReentranLock(可重入锁)的一种改进,在可重入锁的基础上,进行了读写分离。适用于读多写少的场景…...

ChatGPT-4o和ChatGPT-4o mini的差异点

在人工智能领域,OpenAI再次引领创新潮流,近日正式发布了其最新模型——ChatGPT-4o及其经济实惠的小型版本ChatGPT-4o Mini。这两款模型虽同属于ChatGPT系列,但在性能、应用场景及成本上展现出显著的差异。本文将通过图文并茂的方式&#xff0…...

小程序设计和开发:什么是竞品分析,如何进行竞品分析

一、竞品分析的定义 竞品分析是指对竞争对手的产品进行深入研究和比较,以了解市场动态、发现自身产品的优势和不足,并为产品的设计、开发和营销策略提供参考依据。在小程序设计和开发中,竞品分析可以帮助开发者了解同类型小程序的功能、用户体…...

计算机网络之计算机网络的分类

计算机网络可以根据不同的角度进行分类,以下是几种常见的分类方式: 1. 按照规模和范围: 局域网(LAN,Local Area Network):覆盖较小范围(例如一个建筑物或校园)&#xf…...

什么是门控循环单元?

一、概念 门控循环单元(Gated Recurrent Unit,GRU)是一种改进的循环神经网络(RNN),由Cho等人在2014年提出。GRU是LSTM的简化版本,通过减少门的数量和简化结构,保留了LSTM的长时间依赖…...

ESP32-c3实现获取土壤湿度(ADC模拟量)

1硬件实物图 2引脚定义 3使用说明 4实例代码 // 定义土壤湿度传感器连接的模拟输入引脚 const int soilMoisturePin 2; // 假设连接到GPIO2void setup() {// 初始化串口通信Serial.begin(115200); }void loop() {// 读取土壤湿度传感器的模拟值int sensorValue analogRead…...

获取snmp oid的小方法1(随手记)

snmpwalk遍历设备的mib # snmpwalk -v <SNMP version> -c <community-id> <IP> . snmpwalk -v 2c -c test 192.168.100.201 .根据获取的值&#xff0c;找到某一个想要的值的oid # SNMPv2-MIB::sysName.0 STRING: test1 [rootzabbix01 fonts]# snmpwalk -v…...

【C++篇】哈希表

目录 一&#xff0c;哈希概念 1.1&#xff0c;直接定址法 1.2&#xff0c;哈希冲突 1.3&#xff0c;负载因子 二&#xff0c;哈希函数 2.1&#xff0c;除法散列法 /除留余数法 2.2&#xff0c;乘法散列法 2.3&#xff0c;全域散列法 三&#xff0c;处理哈希冲突 3.1&…...

Nginx开发01:基础配置

一、下载和启动 1.下载、使用命令行启动&#xff1a;Web开发&#xff1a;web服务器-Nginx的基础介绍&#xff08;含AI文稿&#xff09;_nginx作为web服务器,可以承担哪些基本任务-CSDN博客 注意&#xff1a;我配置的端口是81 2.测试连接是否正常 访问Welcome to nginx! 如果…...

mysqldump+-binlog增量备份

注意&#xff1a;二进制文件删除必须使用help purge 不可用rm -f 会崩 一、概念 增量备份&#xff1a;仅备份上次备份以后变化的数据 差异备份&#xff1a;仅备份上次完全备份以后变化的数据 完全备份&#xff1a;顾名思义&#xff0c;将数据完全备份 其中&#xff0c;…...

hive:数据导入,数据导出,加载数据到Hive,复制表结构

hive不建议用insert,因为Hive是建立在Hadoop之上的数据仓库工具&#xff0c;主要用于批处理和大数据分析&#xff0c;而不是为OLTP&#xff08;在线事务处理&#xff09;操作设计的。INSERT操作会非常慢 数据导入 命令行界面:建一个文件 查询数据>>复制>>粘贴到新…...

【工欲善其事】利用 DeepSeek 实现复杂 Git 操作:从原项目剥离出子版本树并同步到新的代码库中

文章目录 利用 DeepSeek 实现复杂 Git 操作1 背景介绍2 需求描述3 思路分析4 实现过程4.1 第一次需求确认4.2 第二次需求确认4.3 第三次需求确认4.4 V3 模型&#xff1a;中间结果的处理4.5 方案验证&#xff0c;首战告捷 5 总结复盘 利用 DeepSeek 实现复杂 Git 操作 1 背景介绍…...

mac 手工安装OpenSSL 3.4.0

如果你希望继续安装 openssl-3.4.0 而不是降级到 3.1.1&#xff0c;可以尝试以下解决方案。根据你提供的错误信息&#xff0c;问题可能出在测试阶段&#xff08;make test&#xff09;&#xff0c;我们可以尝试跳过测试或修复测试失败的原因。 --- ### **解决方案&#xff1a…...

构建一个数据分析Agent:提升分析效率的实践

在上一篇文章中,我们讨论了如何构建一个智能客服Agent。今天,我想分享另一个实际项目:如何构建一个数据分析Agent。这个项目源于我们一个金融客户的真实需求 - 提升数据分析效率,加快决策速度。 从分析师的痛点说起 记得和分析师团队交流时的场景&#xff1a; 小张&#xff…...

【SRC排名】安全应急响应中心SRC上榜记录

2023年 新氧第三 https://security.soyoung.com/top 合合第四 https://security.intsig.com/index.php?m&chall&aindex 2024年 好未来第一 https://src.100tal.com/index.php?m&chall&aindex&#xff08;官网是总榜&#xff0c;年榜只有海报&#xff09;…...

截止到2025年2月1日,Linux的Wayland还有哪些问题是需要解决的?

截至2025年2月1日,Wayland需要解决的核心问题可按权重从高到低排序如下: 1. 屏幕共享与远程桌面的完整支持(权重:★★★★★) 问题:企业场景(如 腾讯会议)、开发者远程调试依赖稳定的屏幕共享功能。当前Wayland依赖PipeWire和XWayland,存在权限管理复杂、多显示器选择…...

TCP编程

1.socket函数 int socket(int domain, int type, int protocol); 头文件&#xff1a;include<sys/types.h>&#xff0c;include<sys/socket.h> 参数 int domain AF_INET: IPv4 Internet protocols AF_INET6: IPv6 Internet protocols AF_UNIX, AF_LOCAL : Local…...

Java泛型深度解析(JDK23)

第一章 泛型革命 1.1 类型安全的进化史 前泛型时代的类型转换隐患 代码的血泪史&#xff08;Java 1.4版示例&#xff09;&#xff1a; List rawList new ArrayList(); rawList.add("Java"); rawList.add(Integer.valueOf(42)); // 编译通过// 灾难在运行时爆发…...

【JavaEE进阶】图书管理系统 - 壹

目录 &#x1f332;序言 &#x1f334;前端代码的引入 &#x1f38b;约定前后端交互接口 &#x1f6a9;接口定义 &#x1f343;后端服务器代码实现 &#x1f6a9;登录接口 &#x1f6a9;图书列表接口 &#x1f384;前端代码实现 &#x1f6a9;登录页面 &#x1f6a9;…...

搜索旋转排序数组(二分查找)

测试链接&#xff1a;https://leetcode.cn/problems/search-in-rotated-sorted-array/https://leetcode.cn/problems/search-in-rotated-sorted-array/https://leetcode.cn/problems/search-in-rotated-sorted-array/ 问题描述 假设我们有一个旋转排序的数组&#xff0c;这个…...

STM32 TIM定时器配置

TIM简介 TIM&#xff08;Timer&#xff09;定时器 定时器可以对输入的时钟进行计数&#xff0c;并在计数值达到设定值时触发中断 16位计数器、预分频器、自动重装寄存器的时基单元&#xff0c;在72MHz计数时钟下可以实现最大59.65s的定时 不仅具备基本的定时中断功能&#xff…...

AI开发之 ——Anaconda 介绍

Anaconda 是什么&#xff1f; 在这里插入图片描述 一句话&#xff1a;Anaconda 是Python 库和环境便捷管理的平台。 Anaconda 是数据科学和 AI 领域的工具&#xff0c;通过集成常用库和工具&#xff0c;简化了环境管理和包安装&#xff0c;特别适合初学者和需要快速上手的开…...

Uber损失(Huber Loss):从均方误差到绝对误差的完美过渡

前言 在机器学习的世界里,损失函数就像是你在迷宫中的导航系统,它决定了你到底能否顺利找到出口,而出口的大小就代表着模型的表现。而在这么多的“导航系统”中,Huber损失(你可以叫它“Uber损失”,我觉得这名字挺有意思的,能不能打车到一个更好的模型呢?)凭借其独特的…...

【Arxiv 大模型最新进展】TOOLGEN:探索Agent工具调用新范式

【Arxiv 大模型最新进展】TOOLGEN&#xff1a;探索Agent工具调用新范式 文章目录 【Arxiv 大模型最新进展】TOOLGEN&#xff1a;探索Agent工具调用新范式研究框图方法详解 作者&#xff1a;Renxi Wang, Xudong Han 等 单位&#xff1a;LibrAI, Mohamed bin Zayed University o…...

41【文件名的编码规则】

我们在学习的过程中&#xff0c;写出数据或读取数据时需要考虑编码类型 火山采用&#xff1a;UTF-16 易语言采用&#xff1a;GBK php采用&#xff1a;UTF-8 那么我们写出的文件名应该是何种编码的&#xff1f;比如火山程序向本地写出一个“测试.txt”&#xff0c;理论上这个“测…...

Linux命令入门

Linux命令入门 ls命令 ls命令的作用是列出目录下的内容&#xff0c;语法细节如下: 1s[-a -l -h] [Linux路径] -a -l -h是可选的选项 Linux路径是此命令可选的参数 当不使用选项和参数,直接使用ls命令本体,表示:以平铺形式,列出当前工作目录下的内容 ls命令的选项 -a -a选项&a…...

如何用函数去计算x年x月x日是(C#)

如何用函数去计算x年x月x日是? 由于现在人工智能的普及,我们往往会用计算机去算,或者去记录事情 1.计算某一年某一个月有多少天 2.计算某年某月某日是周几 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threadin…...

29.Word:公司本财年的年度报告【13】

目录 NO1.2.3.4 NO5.6.7​ NO8.9.10​ NO1.2.3.4 另存为F12&#xff1a;考生文件夹&#xff1a;Word.docx选中绿色标记的标题文本→样式对话框→单击右键→点击样式对话框→单击右键→修改→所有脚本→颜色/字体/名称→边框&#xff1a;0.5磅、黑色、单线条&#xff1a;点…...

Flutter常用Widget小部件

小部件Widget是一个类&#xff0c;按照继承方式&#xff0c;分为无状态的StatelessWidget和有状态的StatefulWidget。 这里先创建一个简单的无状态的Text小部件。 Text文本Widget 文件&#xff1a;lib/app/app.dart。 import package:flutter/material.dart;class App exte…...

高可用 Keepalived 服务部署流程

一、配置文件 vim /etc/keepalived/keepalived.confGLOBAL CONFIGURATION --- 全局配置部分VRRPD CONFIGURATION --- VRRP协议配置部分LVS CONFIGURATION --- LVS服务管理配置部分[rootlb01 ~]# cat /etc/keepalived/keepalived.…...

网站结构优化:加速搜索引擎收录的关键

本文来自&#xff1a;百万收录网 原文链接&#xff1a;https://www.baiwanshoulu.com/9.html 网站结构优化对于加速搜索引擎收录至关重要。以下是一些关键策略&#xff0c;旨在通过优化网站结构来提高搜索引擎的抓取效率和收录速度&#xff1a; 一、合理规划网站架构 采用扁…...

【深度学习】softmax回归的从零开始实现

softmax回归的从零开始实现 (就像我们从零开始实现线性回归一样&#xff0c;)我们认为softmax回归也是重要的基础&#xff0c;因此(应该知道实现softmax回归的细节)。 本节我们将使用Fashion-MNIST数据集&#xff0c;并设置数据迭代器的批量大小为256。 import torch from IP…...

AMS仿真方法

1. 准备好verilog文件。并且准备一份.vc文件&#xff0c;将所有的verilog file的路径全部写在里面。 2. 将verilog顶层导入到virtuoso中&#xff1a; 注意.v只要引入顶层即可。不需要全部引入。实际上顶层里面只要包含端口即可&#xff0c;即便是空的也没事。 引入时会报warni…...

多模态论文笔记——ViViT

大家好&#xff0c;这里是好评笔记&#xff0c;公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细解读多模态论文《ViViT: A Video Vision Transformer》&#xff0c;2021由google 提出用于视频处理的视觉 Transformer 模型&#xff0c;在视频多模态领域有…...

Flink2支持提交StreamGraph到Flink集群

最近研究Flink源码的时候&#xff0c;发现Flink已经支持提交StreamGraph到集群了&#xff0c;替换掉了原来的提交JobGraph。 新增ExecutionPlan接口&#xff0c;将JobGraph和StreamGraph作为实现。 Flink集群Dispatcher也进行了修改&#xff0c;从JobGraph改成了接口Executio…...

机器学习优化算法:从梯度下降到Adam及其变种

机器学习优化算法&#xff1a;从梯度下降到Adam及其变种 引言 最近deepseek的爆火已然说明&#xff0c;在机器学习领域&#xff0c;优化算法是模型训练的核心驱动力。无论是简单的线性回归还是复杂的深度神经网络&#xff0c;优化算法的选择直接影响模型的收敛速度、泛化性能…...

2024具身智能模型汇总:从训练数据、动作预测、训练方法到Robotics VLM、VLA

前言 本文一开始是属于此文《GRAPE——RLAIF微调VLA模型&#xff1a;通过偏好对齐提升机器人策略的泛化能力》的前言内容之一(该文发布于23年12月底)&#xff0c;但考虑到其重要性&#xff0c;加之那么大一张表格 看下来 阅读体验较差&#xff0c;故抽出取来独立成文且拆分之 …...

基于Spring Security 6的OAuth2 系列之七 - 授权服务器--自定义数据库客户端信息

之所以想写这一系列&#xff0c;是因为之前工作过程中使用Spring Security OAuth2搭建了网关和授权服务器&#xff0c;但当时基于spring-boot 2.3.x&#xff0c;其默认的Spring Security是5.3.x。之后新项目升级到了spring-boot 3.3.0&#xff0c;结果一看Spring Security也升级…...

当WebGIS遇到智慧文旅-以长沙市不绕路旅游攻略为例

目录 前言 一、旅游数据组织 1、旅游景点信息 2、路线时间推荐 二、WebGIS可视化实现 1、态势标绘实现 2、相关位置展示 三、成果展示 1、第一天旅游路线 2、第二天旅游路线 3、第三天旅游路线 4、交通、订票、住宿指南 四、总结 前言 随着信息技术的飞速发展&…...

浅析CDN安全策略防范

CDN&#xff08;内容分发网络&#xff09;信息安全策略是保障内容分发网络在提供高效服务的同时&#xff0c;确保数据传输安全、防止恶意攻击和保护用户隐私的重要手段。以下从多个方面详细介绍CDN的信息安全策略&#xff1a; 1. 数据加密 数据加密是CDN信息安全策略的核心之…...

Python安居客二手小区数据爬取(2025年)

目录 2025年安居客二手小区数据爬取观察目标网页观察详情页数据准备工作&#xff1a;安装装备就像打游戏代码详解&#xff1a;每行代码都是你的小兵完整代码大放送爬取结果 2025年安居客二手小区数据爬取 这段时间需要爬取安居客二手小区数据&#xff0c;看了一下相关教程基本…...

Python爬虫获取custom-1688自定义API操作接口

一、引言 在电子商务领域&#xff0c;1688作为国内领先的B2B平台&#xff0c;提供了丰富的API接口&#xff0c;允许开发者获取商品信息、店铺信息等。其中&#xff0c;custom接口允许开发者进行自定义操作&#xff0c;获取特定的数据。本文将详细介绍如何使用Python调用1688的…...

CAPL与外部接口

CAPL与外部接口 目录 CAPL与外部接口1. 引言2. CAPL与C/C++交互2.1 CAPL与C/C++交互简介2.2 CAPL与C/C++交互实现3. CAPL与Python交互3.1 CAPL与Python交互简介3.2 CAPL与Python交互实现4. CAPL与MATLAB交互4.1 CAPL与MATLAB交互简介4.2 CAPL与MATLAB交互实现5. 案例说明5.1 案…...