读程序员的制胜技笔记11_与Bug共存(上)

这篇具有很好参考价值的文章主要介绍了读程序员的制胜技笔记11_与Bug共存(上)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

读程序员的制胜技笔记11_与Bug共存(上)文章来源地址https://www.toymoban.com/news/detail-746177.html

1. bug只与规则有关

1.1. 如果根本没有任何规则,那么bug也就不存在了

1.2. 公司也就可以不用拙劣的借口“哦,那只是一个feature”来做危机公关

1.3. 你不需要为规则写一份书面文档——你可以只让它存在于自己的脑海里

1.4. Bug是衡量软件质量的基准参考

2. 类型有大用

2.1. 快速并不仅仅涉及代码编写速度,你还得算上代码维护的速度

2.2. 软件开发是一场马拉松,而不是短跑

2.3. 指定数据类型是在编程中防止数据编码出现冲突的最早防范措施之一

2.4. 类型让你尽早受挫,让你在代码中的隐患酿成大错之前,修复它们

2.5. 使用强类型

2.5.1. 类型检查可以算是对代码正确性的免费初审

2.5.2. 好好吃透底层类型系统会让你在成为资深开发者的路上走得更悠然

2.5.3. 类型可以帮助我们编写更安全、更快速运行、更容易维护的代码

2.6. 使用解释型编程语言编写代码的速度非常快,因为你并不需要真正地去声明变量的类型

2.7. 有效性证明

2.7.1. 有效性证明算是预定义类型较少为人所知的一种好处

2.7.2. 数据验证并不能给全部代码的有效性证明“打包票”

2.7.3. 类型可以承载有效性证明

2.7.3.1. 在构造时验证其有效性,这样一来就不可能包含无效值

2.7.4. 运算符重载,非必要不启用

2.8. 奥尔曼(Allman)样式

2.8.1. 每个花括号都在自己专属的行上

2.8.2. 官方推荐使用1TBS(一种真正的花括号样式),也就是改进的K&R样式

2.8.2.1. 其主张一个花括号与声明在同一行

2.9. 巧用框架

2.9.1. 一些由你自定义的、基于文本的值,比如URL、IP地址、文件名,甚至日期,这些都存储为字符串

2.9.1.1. 看看这些现成的类型

2.9.2. IPAddress比string类型更合适存储IP地址,不仅因为它有验证功能,而且它对现已投入使用的IPv6的支持也非常不错

2.9.3. TimeSpan

2.9.3.1. 它代表持续时间

2.9.3.2. 你没有理由用TimeSpan以外的任何东西来表示持续时间,即使你所调用的函数不接受TimeSpan作为参数

2.9.4. 总是尽量使用DateTimeOffset而不是DateTime

2.9.4.1. 它也很容易转换为DateTime

2.9.4.2. 可以使用算术运算符操作TimeSpan和DateTimeOffset,这要归功于运算符重载

2.9.5. 乔恩·斯基特(Jon Skeet)的Noda Time

2.10. 用类型防止打错字

2.11. null的可与不可

2.11.1. “十亿美元的错误”

2.11.1.1. 托尼·霍尔(Tony Hoare)

2.11.1.1.1. null的发明者

2.11.2. null,某些语言中写作nil,是一个值,它代表着没有值或程序员的冷漠

2.11.3. 由于具有0值的内存地址意味着内存中的无效区域,现代CPU可以捕获无效访问并将其转换为对人类友好的异常消息

2.11.4. 可空引用

2.11.4.1. 当所有引用类型都可以为null的时候,所有接受引用的函数都可以接收两个不同的值:有效引用和null

2.11.5. is运算符不能被重载

2.11.6. 如果问题及早暴露,查看异常的栈跟踪时,会发现它非常干净,方便排查

2.11.6.1. 你能确切地知道是哪个参数导致函数运行失败

2.11.7. 当你没办法而非得使用空字符串时,不要使用 ""符号来表示空字符串

2.11.7.1. 很容易将其与一个带有单个空格的字符串(" ")混淆

2.11.7.2. 可以用String.Empty表示,利用现有类型

2.11.8. C# 9.0中引入了一个新的结构,名叫记录类型(record type)

2.11.8.1. 创建一个不可变的类

2.11.9. Maybe<T>已死,Nullable<T>永恒

2.11.9.1. 编译器既能检查又能优化nullable类型,比临时的实现更好

2.11.9.2. 你还可以从语言中得到运算符和模式匹配的语法支持

2.11.10. null检查有助于你思考正在写的代码的作用,你会更加清楚地知道值到底是不是需要设定为可选的

2.11.10.1. 它会减少bug,让你成为更好的开发者

2.12. 免费的更好性能

2.12.1. 一个有效的IPv6字符串最多可以有65个字符

2.12.2. IPv4地址的长度至少为7个字符

2.12.3. 基于字符串的存储将占用14~130字节,如果包含对象头,则占用30~160字节

2.12.4. PAddress类型将IP地址存储为一系列字节,只使用20~44字节

2.13. 引用类型与值类型

2.13.1. 引用类型和值类型之间的区别主要在于类型在内存中的存储方式

2.13.2. 值类型的内容存储在调用栈中

2.13.2.1. 值类型之所以存在,是因为在某些情况下,它们在存储和性能方面都比引用类型效率更高

2.13.2.1.1. 对于值类型来说,运行时直接读取该值,从而实现更快的访问速度

2.13.3. 引用类型(reference type)存储在堆(heap)中

2.13.3.1. 只有在引用类型内容的时候才会将其存储到调用栈中

2.13.3.2. 引用也导致单层间接性(a single level of indirection)

2.13.3.2.1. 当你需要访问一个引用类型的字段时,.NET运行时必须先读取引用的值,然后转到引用所指向的地址,再从那里读取实际的值

2.13.4. 一个不可变、仅表示数值的类,行内人称为值类型(value type)

2.13.5. 结构在定义上与类(class)非常相似,但与类不同的是,它在任何地方都是通过值传递的

2.13.6. 引用(reference)类似于管理指针(managed pointer)

2.13.6.1. 指针是内存的地址

2.13.7. 虚拟内存(virtual memory)

2.13.8. 垃圾回收

2.13.8.1. 程序员需要注意他们的内存分配,并在完成内存分配后释放分配的内存

2.13.8.2. 不及时释放内存的话,应用程序的内存使用量会不断增加,这也称为内存泄漏

2.13.8.3. 引用计数(reference counting),是第一个被提出用来解决手动内存管理问题的方案

2.13.8.3.1. 是垃圾回收的一种原始形式,运行时将为每个分配的对象保留一个秘密计数器(secret counter),而不是将释放内存的主动权留给程序

3. 旅行推销员问题

3.1. 计算机科学中的一个基础主题

3.2. Traveling Salesperson Problem,TSP

3.3. NP完全问题(NP-complete)

3.3.1. 非确定性多项式时间完全问题(nondeterministic polynomial-time complete)

3.3.2. NP是P(多项式时间)问题的超集,只能用“蛮力”解决

3.3.3. 意味着“我们几乎解决不了这个问题,但我们可以马上验证一个别人建议的解决方案”

3.4. 基于图灵机的编程语言是图灵完全的

3.4.1. 艾伦·图灵(Alan Turing)

3.4.2. 图灵机允许我们在软件开发方面有无限的可能性,但不利用图灵机就无法验证软件开发的正确性

3.4.3. 由于图灵机的性质,错误是不可避免的

3.4.3.1. 不可能有一个没有错误的程序

3.4.3.2. 在你着手开发软件之前,接受这个事实将使你的工作更容易

3.5. 并不依赖图灵机的语言

3.5.1. HTML、XML或正则表达式

3.5.2. 它们能做的事远远比那些图灵完全的语言少

4. 不要修复bug

4.1. 开发团队必须有一个筛选过程,来决定在任何大型项目中要修复哪些bug

4.1.1. 确定bug的优先级

4.2. 评估优先级的一个更简单的方法是先使用一个不相关的第二维度,即严重性

4.3. 优先级是指某个bug对业务的影响

4.3.1. 如果你的主页上的企业logo丢失了,这或许一点都不严重,然而这件事有最高的优先级

4.4. 严重性是指它对客户的影响

4.4.1. 如果你的平台上的一个网页不能工作,这是一个高严重性的问题,因为客户不能使用它

4.4.2. 但它的优先级可能完全不同,这取决于它是在首页还是只有少数客户访问的不起眼的页面

4.5. 你区分的级别越多,区分它们就越困难

4.6. 你应该有关于优先级和严重性的阈值

4.6.1. 任何低于这个值的bug都会被归类为不修复

4.7. 寻找bug也会产生成本

4.7.1. 当务之急是避免关注那些永远不可能被修复的bug

4.8. 试着在遇到bug的时候就赶紧做是否要修复的决定,这既能为你节省时间,而且还能确保你保持合格的产品质量

到了这里,关于读程序员的制胜技笔记11_与Bug共存(上)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 读程序员的制胜技笔记05_测试(上)

    3.5.3.1. 也是最容易编写的 3.5.3.2. 只测试单个代码单元:公共函数(public function) 3.5.3.3. 需要是公开的,因为测试应该检查外部可见的接口,而不是类的内部细节 3.5.3.4. 问题是即便它让你能够知晓单个单元是否正常工作,但是并不能保证所有单元能够正常协同工作 3.5.4.1. 测

    2024年02月05日
    浏览(45)
  • 读程序员的制胜技笔记13_安全审查(上)

    5.6.1.1. 任何你不想丢失或泄露的东西都是资产,包括你的源代码、设计文档、数据库、私钥、API令牌、服务器配置,还有Netflix观看清单 5.6.2.1. 每台服务器都会被一些人访问,而每台服务器都会访问其他一些服务器 6.1.1.1. 设计时首先要考虑到安全问题,因为在既有基础上去

    2024年02月05日
    浏览(61)
  • 读程序员的制胜技笔记14_安全审查(下)

    1.2.2.1. 看不出来是什么?那我拒绝为你服务 1.4.1.1. 工作量证明相当消耗客户端的运算资源,对那些性能较低的设备不友好,并且它还会影响设备电池的使用寿命 1.4.1.2. 有可能会严重降低用户体验,其后果甚至比验证码的还要恶劣 3.5.2.1. 存储需求更少,性能更强,数据管理

    2024年02月05日
    浏览(45)
  • 读程序员的制胜技笔记10_可口的扩展

    2.8.3.1. 纯函数有一个好处,它们是100%线程安全的 2.9.1.1. 这套数据结构并不都是无锁的 2.9.1.2. 虽然它们依然使用锁,但它们是被优化过的,锁的持续时间会很短,保证了其速度,而且它们可能比真正的无锁替代方案更简单 2.9.2.1. 其中原始数据从未改变,但每个修改操作都

    2024年02月05日
    浏览(67)
  • 读程序员的制胜技笔记09_死磕优化(下)

    7.5.3.1. 在256KB之后,提升突然变得杯水车薪

    2024年02月05日
    浏览(73)
  • 读程序员的制胜技笔记08_死磕优化(上)

    4.3.1.1. 只能给你一堆用于比较的数字 4.3.1.2. 不能告诉你代码的运行速度是快还是慢 4.3.1.3. 可以告诉你它们比其他一些代码运行得慢还是快 4.3.5.1. 可以消除因测量误差或者调用开销产生的波动 4.3.5.2. 适用于微观基准测试 4.3.5.2.1. 适用于微观基准测试 4.3.5.3. 基准测试并没

    2024年02月05日
    浏览(80)
  • 读程序员的制胜技笔记02_算法与数据结构

    3.1.1.1. 根据你的需要,可以有更智能的算法 3.1.3.1. 算法本身并不意味着它很聪明 3.2.1.1. public static bool Contains(int[] array, int lookFor) { for (int n = 0; n < array.Length; n++) {        if (array[n] == lookFor) {            return true;        }    }    return false; } 3.3.1.1. public sta

    2024年02月06日
    浏览(62)
  • 读程序员的制胜技笔记03_有用的反模式(上)

    4.5.4.1. 你在物理数据库结构上增加了一个依赖项 4.5.4.2. 如果你需要改变信息表的布局或所使用的数据库技术,你就必须检查所有的代码,确保所有的东西都能与新的表布局或新的数据库技术一起工作 4.5.6.1. 这是保持组件或整个层尽可能简单的关键 4.8.3.1. 每个成员只对自己

    2024年02月06日
    浏览(46)
  • 读程序员的制胜技笔记04_有用的反模式(下)

    1.3.1.1. 自己做自己的甲方 3.2.2.1. 紧耦合(tight coupling) 3.2.2.2. 依赖性是万恶之源 3.3.7.1. 因为你可能需要用接口而不是具体的引用来定义依赖关系,但这也会使代码摆脱依赖关系 5.2.3.1. 没有其他错误发生时执行的代码部分 5.3.3.1. 退出点(exit point)是指函数中导致其返回给调用

    2024年02月06日
    浏览(85)
  • 读程序员的README笔记11_软件交付(下)

    1.3.5.1. 通过持续交付,人力被完全从部署环节中移除 1.3.5.2. 打包、测试、发布、部署,甚至展开环节都是自动化的 1.3.6.1. Puppet、Salt、Ansible和Terraform等现成的解决方案可以与现有的工具集成,并且它们是专门为了自动化部署而设计的 1.4.4.1. 只需再次指向旧的版本 1.5.1.1. 

    2024年02月04日
    浏览(61)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包