计算机编程之美:数据结构与算法之美+设计模式之美
作者:王争(@小争哥)
出版社:人民邮电出版社
出版时间:2022-03-01
ISBN:9787115006653
定价:¥219.60
《数据结构与算法之美(全彩印刷)》
\n目录
\n第 1章 复杂度分析 1
\n1.1 复杂度分析(上):如何分析代码的执行效率和资源消耗 2
\n1.1.1 复杂度分析的意义 2
\n1.1.2 大O复杂度表示法 2
\n1.1.3 时间复杂度分析方法 4
\n1.1.4 几种常见的时间复杂度量级 5
\n1.1.5 空间复杂度分析方法 7
\n1.1.6 内容小结 7
\n1.1.7 思考题 8
\n1.2 复杂度分析(下):详解最好、最坏、平均、均摊这4种时间复杂度 8
\n1.2.1 最好时间复杂度和最坏时间复杂度 8
\n1.2.2 平均时间复杂度 9
\n1.2.3 均摊时间复杂度 10
\n1.2.4 内容小结 11
\n1.2.5 思考题 12
\n第 2章 数组、链表、栈和队列 13
\n2.1 数组(上):为什么数组的下标一般从0开始编号 14
\n2.2 数组(下):数据结构中的数组和编程语言中的数组的区别 19
\n2.3 链表(上):如何基于链表实现LRU缓存淘汰算法 23
\n2.4 链表(下):借助哪些技巧可以轻松地编写链表相关的复杂代码 30
\n2.5 栈:如何实现浏览器的前进和后退功能 35
\n2.6 队列:如何实现线程池等有限资源池的请求排队功能 40
\n第3章 递归、排序、二分查找 46
\n3.1 递归:如何用3行代码找到“Z终推荐人” 47
\n3.2 尾递归:如何借助尾递归避免递归过深导致的堆栈溢出 53
\n3.3 排序算法基础:从哪几个方面分析排序算法 55
\n3.4 O(n2)排序:为什么插入排序比冒泡排序更受欢迎 58
\n3.5 O(nlogn)排序:如何借助快速排序思想快速查找第K大元素 64
\n3.6 线性排序:如何根据年龄给100万个用户排序 72
\n3.7 排序优化:如何实现一个高性能的通用的排序函数 78
\n3.8 二分查找:如何用Z省内存的方式实现快速查找功能 80
\n3.9 二分查找的变体:如何快速定位IP地址对应的归属地 85
\n第4章 哈希表、位图和哈希算法 91
\n4.1 哈希表(上):Word软件的单词拼写检查功能是如何实现的 92
\n4.2 哈希表(中):如何打造一个工业级的哈希表 96
\n4.3 哈希表(下):如何利用哈希表优化LRU缓存淘汰算法 101
\n4.4 位图:如何实现网页“爬虫”中的网址链接去重功能 106
\n4.5 哈希算法:如何防止数据库脱库后用户信息泄露 111
\n第5章 树 117
\n5.1 树和二叉树:什么样的二叉树适合用数组存储 118
\n5.2 二叉查找树:相比哈希表,二叉查找树有何优势 122
\n5.3 平衡二叉查找树:为什么红黑树如此受欢迎 128
\n5.4 递归树:如何借助树求递归算法的时间复杂度 131
\n5.5 B+树:MySQL数据库索引是如何实现的 135
\n第6章 堆 141
\n6.1 堆:如何维护动态集合的最值 142
\n6.2 堆排序:为什么说堆排序没有快速排序快 147
\n6.3 堆的应用:如何快速获取Top 10热门搜索关键词 151
\n第7章 跳表、并查集、线段树和树状数组 157
\n7.1 跳表:Redis中的有序集合类型是如何实现的 158
\n7.2 并查集:路径压缩和按秩合并这两个优化是否冲突 163
\n7.3 线段树:如何查找猎聘网中积分排在第K位的猎头 168
\n7.4 树状数组:如何实现一个高性能、低延迟的实时排行榜 174
\n第8章 字符串匹配算法 179
\n8.1 BF算法:编程语言中的查找、替换函数是怎样实现的 180
\n8.2 RK算法:如何借助哈希算法实现高效的字符串匹配 182
\n8.3 BM算法:如何实现文本编辑器中的查找和替换功能 185
\n8.4 KMP算法:如何借助BM算法理解KMP算法 194
\n8.5 Trie树:如何实现搜索引擎的搜索关键词提示功能 198
\n8.6 AC自动机:如何用多模式串匹配实现敏感词过滤 204
\n第9章 图 210
\n9.1 图的表示:如何存储微博、微信等社交网络中的好友关系 211
\n9.2 深度优先搜索和广度优先搜索:如何找出社交网络中的三度好友关系 216
\n9.3 拓扑排序:如何确定代码源文件的编译依赖关系 221
\n9.4 单源Z短路径:地图软件如何“计算”Z优出行路线 225
\n9.5 多源Z短路径:如何利用Floyd算法解决传递闭包问题 231
\n9.6 启发式搜索:如何用A*算法实现游戏中的寻路功能 233
\n9.7 Z小生成树:如何随机生成游戏中的迷宫地图 238
\n9.8 Z大流:如何解决单身交友联谊中的Z多匹配问题 245
\n第 10章 贪心、分治、回溯和动态规划 251
\n10.1 贪心算法:如何利用贪心算法实现霍夫曼编码 252
\n10.2 分治算法:谈一谈大规模计算框架MapReduce中的分治思想 256
\n10.3 回溯算法:从电影《蝴蝶效应》中学习回溯算法的核心思想 260
\n10.4 初识动态规划:如何巧妙解决“双11”购物时的凑单问题 264
\n10.5 动态规划理论:彻底理解最优子结构、无后效性和重复子问题 272
\n10.6 动态规划实战:如何实现搜索引擎中的拼写纠错功能 278
\n第 11章 数据结构和算法实战 284
\n11.1 实战1:剖析Redis的常用数据类型对应的数据结构 285
\n11.2 实战2:剖析搜索引擎背后的经典数据结构和算法 288
\n11.3 实战3:剖析微服务鉴权和限流背后的数据结构和算法 293
\n11.4 实战4:用学过的数据结构和算法实现短网址服务 299
\n附录A 思考题答案 304
\n《设计模式之美》
\n第 1章概述 1
\n1.1 为什么学习代码设计 2
\n1.1.1 编写高质量的代码 2
\n1.1.2 应对复杂代码的开发 2
\n1.1.3 程序员的基本功 3
\n1.1.4 职场发展的必备技能 4
\n1.1.5 思考题 4
\n1.2 如何评价代码质量 4
\n1.2.1 可维护性(maintainability) 5
\n1.2.2 可读性(readability) 6
\n1.2.3 可扩展性(extensibility) 6
\n1.2.4 灵活性(flexibility) 6
\n1.2.5 简洁性(simplicity) 7
\n1.2.6 可复用性(reusability) 7
\n1.2.7 可测试性(testability) 7
\n1.2.8 思考题 8
\n1.3 如何写出高质量代码 8
\n1.3.1 面向对象 8
\n1.3.2 设计原则 8
\n1.3.3 设计模式 9
\n1.3.4 代码规范 9
\n1.3.5 重构技巧 10
\n1.3.6 思考题 11
\n1.4 如何避免过度设计 11
\n1.4.1 代码设计的初衷是提高代码质量 11
\n1.4.2 代码设计的原则是“先有问题,后有方案” 12
\n1.4.3 代码设计的应用场景是复杂代码 12
\n1.4.4 持续重构可有效避免过度设计 12
\n1.4.5 不要脱离具体的场景谈代码设计 13
\n1.4.6 思考题 13
\n第 2章面向对象编程范式 14
\n2.1 当我们在谈论面向对象时,到底在谈论什么 15
\n2.2 封装、抽象、继承和多态为何而生 17
\n2.3 如何进行面向对象分析、面向对象设计和面向对象编程 25
\n2.4 面向对象编程与面向过程编程和函数式编程之间的区别 35
\n2.5 哪些代码看似面向对象编程风格,实则面向过程编程风格 45
\n2.6 基于“贫血”模型的传统开发模式是否违背OOP 51
\n2.7 接口和抽象类:如何使用普通类模拟接口和抽象类 59
\n2.8 基于接口而非实现编程:有没有必要为每个类都定义接口 65
\n2.9 组合优于继承:什么情况下可以使用继承 70
\n第3章设计原则 75
\n3.1 单一职责原则:如何判定某个类的职责是否单一 76
\n3.2 开闭原则:只要修改代码,就一定违反开闭原则吗 79
\n3.3 里氏替换原则:什么样的代码才算违反里氏替换原则 86
\n3.4 接口隔离原则:如何理解该原则中的“接口” 89
\n3.5 依赖反转原则:依赖反转与控制反转、依赖注入有何关系 97
\n3.6 KISS原则和YAGNI原则:二者是一回事吗 100
\n3.7 DRY原则:相同的两段代码就一定违反DRY原则吗 104
\n3.8 LoD:如何实现代码的“高内聚、低耦合” 110
\n第4章代码规范 117
\n4.1 命名与注释:如何精准命名和编写注释 118
\n4.2 代码风格:与其争论标准,不如团队统一 121
\n4.3 编程技巧:小技巧,大作用,一招提高代码的可读性 123
\n第5章重构技巧 130
\n5.1 重构四要素:目的、对象、时机和方法 131
\n5.2 单元测试:保证重构不出错的有效手段 133
\n5.3 代码的可测试性:如何编写可测试代码 139
\n5.4 解耦:哪些方法可以用来解耦代码 147
\n5.5 重构案例:将ID生成器代码从“能用”重构为“好用” 150
\n第6章创建型设计模式 166
\n6.1 单例模式(上):为什么不推荐在项目中使用单例模式 167
\n6.2 单例模式(下):如何设计实现一个分布式单例模式 177
\n6.3 工厂模式(上):如何解耦复杂对象的创建和使用 180
\n6.4 工厂模式(下):如何设计实现一个依赖注入容器 188
\n6.5 建造者模式:什么情况下必须用建造者模式创建对象 194
\n6.6 原型模式:如何快速复制(clone)一个哈希表 200
\n第7章结构型设计模式 208
\n7.1 代理模式:代理模式在RPC、缓存和监控等场景中的应用 209
\n7.2 装饰器模式:剖析Java IO类库的底层设计思想 213
\n7.3 适配器模式:如何利用适配器模式解决代码的不兼容问题 219
\n7.4 桥接模式:如何将M×N的继承关系简化为M+N的组合关系 230
\n7.5 门面模式:如何设计接口以兼顾接口的易用性和通用性 231
\n7.6 组合模式:一种应用在树形结构上的特殊设计模式 233
\n7.7 享元模式:如何利用享元模式降低系统的内存开销 239
\n第8章行为型设计模式 249
8.1 观察者模式:如何实现一个异步非阻塞的EventBus框架 250
\n8.2 模板方法模式(上):模板方法模式在JDK、Servlet、JUnit中的应用 261
\n8.3 模板方法模式(下):模板方法模式与回调有何区别和联系 267
\n8.4 策略模式:如何避免冗长的if-else和switch-case语句 273
\n8.5 职责链模式:框架中的过滤器、拦截器和插件是如何实现的 282
\n8.6 状态模式:游戏和工作流引擎中常用的状态机是如何实现的 297
\n8.7 迭代器模式(上):为什么要用迭代器遍历集合 306
\n8.8 迭代器模式(下):如何实现一个支持快照功能的迭代器 315
\n8.9 访问者模式:为什么支持双分派的编程语言不需要访问者模式 320
\n8.10 备忘录模式:如何优雅地实现数据防丢失、撤销和恢复功能 330
\n8.11 命令模式:如何设计实现基于命令模式的手游服务器 334
\n8.12 解释器模式:如何设计实现一个自定义接口告警规则的功能 337
\n8.13 中介模式:什么时候使用中介模式?什么时候使用观察者模式? 343