本文内容主要来自 徐昊老师和同学之间的互动讨论
徐昊
Thoughtworks 中国区 CTO
Thoughtworks全球技术策略顾问、中国区首席咨询师,同时也是北京Java用户组(BJUG: Beijing Java User Group)和Agile China创始人。他从2003年起开始实践极限编程等敏捷方法,2005年开始,多次以敏捷教练的角色帮助国内外多个团队实施极限编程。他在Scrum和FDD等敏捷方法、以及敏捷交付和敏捷项目管理等方面的经验极为丰富。目前,他主要致力于大规模团队(300-500人)内的敏捷实践和管理再造,以及对企业级技术应用趋势和技术战略的研究。
有哪些状态验证技术推荐吗?
- 做各种fake mountainbike,mock,in men do, test container
- 目的就是尽量少做行为验证
- 所谓测试策略 就是在保证有效性的同时 尽可能降低测试成本
- 维持测试有效性 有个最小成本
- 小过这个 测试就无效了 或者不足以支撑长期演化(重构)
- 所以你没办法一直缩短测试时间
- 这也是我们讲的 始终使用状态验证 防止测试失效
- 在状态验证里 通过stub 偷换fake 降低成本
AI + TDD 起飞
- 在 TDD 和结对编程里有一条规矩
- 资深的写测试
- 初级程序员写生产代码
- 在合理的单元构造有效的测试,实现就走不了样
- 现在配合 AI 编程
- 程序员的主要任务就变成了验证 AI 写的代码符合要求
- TDD 就是非常自然的做法:写测试,触发 AI 通过测试
- pair 里写测试的人叫 poilt
- 测试需要维护
- 测试写的好坏直接决定代码质量
- 测试写不好的程序员,生产代码也写不好
- 主要的思考活动,都在写那些测试
- 大部分程序员效率不高在于想不清楚
- 至于实现 相比之下 那是非常简单了
对测试代码的建议
- 保留额外的大粒度测试,是测试金字塔变形主要原因
- 从验证功能的角度讲 很容易就写成所有功能测试的集合 这样的测试集合 维护和运行成本都比较高
- 至于任务分解,前面有同学讲到了 因为一开始没有架构愿景,所以拆封的都是功能点。在重构之后,架构模块改变了,对应的测试策略也要改变
关于设计模式的建议
- 极客时间 | 如何落地业务建模 | 说点题外话02|模式并不是解决方案
- 模式与建模是一样的,都是问题先行
- 模式最难的地方就在于判断当前的问题与模式要解决的是否是同一个问题,这也是为什么我们提倡通过重构获得模式
- 当问题明显出现的时候(以坏味道的形式),那么最难的一步其实你已经解决了
- 这时再通过重构去得到具体的解决方案,反而是简单的
- 极客时间 | 软件设计之美 | 25 | 设计模式:每一种都是一个特定问题的解决方案
- 学习设计模式不仅仅要学习代码怎么写,更重要的是要了解模式的应用场景
- 设计原则其实是这些模式背后的东西
- 设计模式只是设计原则在特定场景下的应用
关于伦敦学派用测试替身,有几个问题
问
- 被替身的组件本身的行为如何测试?
- 如果他们返回的数据并不像stub假设的一样怎么办?
- 如果把ArgTest里面所有用到OptionClass的stub,也照搬一份到OptionClass的测试里面当做测试用例,算不算一种重复?
答
- 伦敦学派的前提 就是交互确定
- 然后沿着调用栈依次实现
- 如果被stub组件行为和stub行为不同
- 那就是前提不成了
- 不成立
- 所以你的问题相当于 如果伦敦学派的前提不成立 怎么使用伦敦学派
- 答案是:用不了
Intellij IDEA 的常用的快捷键视频
任务分解是两层的:需求、架构/架构思想
- 架构不一定能达到一致
- 只能分解功能点,到不了任务
- 任务里有架构构想
图书收集
- 《Refactoring to Pattern》中文版《重构与模式》
- 《How Google Tests Software》
- 《xUnit Test Patterns : Refactoring Test Code》中文版《xUnit测试模式》
- 《Unit Testing : Principles, Patterns and Practices》
- 《Domain Specific Languages》中文版《领域特定语言》
- 我收集的
超级巨头曾经的结论
- 结对编程 + TDD 大约会增加 15-20% 的成本
- 但是提高70%的代码质量,减少反攻和上线时间
大佬说-1
- 自动化重构工具的效率极度影响开发效率
函数编程
- 在函数式风格里,说到底还是要考虑entity,value,不变性,reference这些,和OO也没有什么差别
- 函数式里,你定义一个函数,其实就是定义了一类函数
- 柯里化(英语:Currying)笔记 《Java实战(第2版)》第 19 章 函数式编程的技巧
小巨人项目
- 打基础用的,入职第一年需要看完的书 点击查看共 28 本
- 消化就是做项目的时候,反思
- 不然项目做烂了,都不知道烂在哪
- 再做还是错
- 广度优先,先撑起来
- 核心技能要深挖,TDD
- 每天看书俩小时,TDD 8 小时
2022-04-12 🚀 2023-04-15
大佬说-2
- 我选了args,原因是它风格比较多样,并不一定非要写得特别oo或者fp,发挥的余地大
- api设计,需要一点想象力
BDD
- BDD最开始就是个组织测试的办法
- 我司同事 Daivd North 在04年编的名字
- 第一个承载bdd思想的框架,jbehave
- 初创人是我以前项目上的to… TL
- 没有什么不同层次
- 就是写测试的角度不一样
- 不要描述具体功能
- 描述 feature 和 behave
- 比如不要写 should return 2 if 1 + 1
- 要写,be able to add positive number
- 然后二十年前,我们讨论来讨论去,最后就变成given-when-then了
- 用 given-when-then,描述业务,就是 BDD
- specification-by-example是不是BDD之后写的了?
- 不是
- specification by example 是 Gojko Adzic
- sbe 很好的
- 我觉得sbe比bdd靠谱多了
- 我专门请过Gojko Adzic来北京,给我公司做过培训
- 因为 sbe 只解决一个问题,就是需求怎么分解 而且做得很好
- 所谓 driven development,需要:需求、架构双分解 ⭐️⭐️⭐️⭐️⭐️
- bdd 的问题在于,很难驱动架构分解
- tdd 要求双分解
- 你拿什么分都行,只不过sbe很好用而已
- sbe 很多用法,最简单就是 story 分 ac
- 拆story也行
- example mapping
- bdd 是风格,bdd 框架承载了风格
- sbe 最好的工具,就是脑子
- 这就跟,写诗有什么好工具嘛?
- 写小说又什么好工具嘛?
- 那不是word就行了,工具差异不大
Golang ,我需要启动一个每 5s 执行一次的定时器,这个我如何验证呢?
- 分两步
- 按时间间隔启动
- 和间隔设置是5秒
- 测的时候 给间隔 100ms
- 然后 config 是 5
- 设计从 config 里拿配置
- 三个测试
为啥测试性,能提高代码质量
- 可测试的代码,都不会出写死
- 至少可以替换测试用功能和真的功能
- 永远都有俩选择,所以永远不会写死
tw有没做技术洞察的方法论可以学习下的么
- 技术洞察很容易啊,过去15年所有重要文献读一遍
- 然后不明白的,自己试。很容易就洞察了
- 群友:有哪些重要文献?
- 找一本最近出的书,连书带参考文献,看一遍
- 参考文献的参考文献
- 然后继续,直到都看完,不就知道了。肯定漏不掉
- 群友:没做过这块,就比较迷了,参考文献是个不错的方向,顺着引用倒是能挖出不少东西来
- 你的出发点不重要,重要的都不会错过
- 没做过也没关系
- 随便从哪一本开始,然后开始看
- 基本上愿意花功夫,一个月任何领域,能超过85%的人
- 软件,特别是工程领域,没什么高深的
mcafee 大哥的理论
- 有一年在美国,我们公司请来演讲的
- 他说,绝大部人会高估新技术的效果3倍
- 会低估已经存在技术的能力 3倍
- 所以新技术如果没有10x的优势
- 就会进入漫长的拉锯式变革,而不是马上
- 这里的问题在于,趋势是事后评估的
- 你在当下,把你认为牛X的方向 ➗ 3
- 你认为傻X的 x 3
- 再看看
- 企业2.0 Enterprise 2.0: How to Manage Social Technologies to Transform Your Organization
- 这位大哥是研究企业创新的
曾经有一段时间我们很迷恋cucumber
- 做过各种插件,word,excel,mingle(这个是我做的)
- 就是在业务工具里写验收,然后驱动自动化测试套去跑测试
- 后来发现其实没什么用,维护成本太高
- 为了解决这个问题,我们还专门做了一个工具,后来开源了,支持cucumber语法重构的ide插件
- 然后领悟了,我们执着于工具了,应该是人与交互,建立人与人的信任,而不是人信任工具
- cucumber所有这些,目的是 business readable
- 业务可读,不要求业务可写
- cucumber给你的东西不多
- 毕竟那个语法,写好了也不容易
- given when then,写成ui脚本的比比皆是
- 有那功夫,你直接画图不好嘛
- 直接画图就完了
- cucumber流行,就是因为大家觉得given when then好容易理解啊。然后都用,其实这要有用,你一开始就没啥问题
- 谁讲需求还不会,当怎么样就这么着了…
- 就好像sbe,很简单,什么需求,都说,你给我举个例子
- 然后你发现,有人开始穷举例子
- sbe里,有人穷举例子,说明有概念缺失
- 要提取抽象。这这一步,80%都差在这了
不要问端到端
- 要问你想从测试获得什么
- 功能 + 定位
- 金字塔,越靠上,越能表示功能准确,但是不能定位
- 越往下,定位越准,但是无法还原业务
- 两个是不能替代的。无论是以全部功能替换定位测试,还是全部以小粒度去替换功能
- 但是有办法平衡。方法最简单就是,你这么想。如果我一个功能错了,多快我能找到哪错了
- 毕竟发现错,没用,你还得改对
2022-04-19 🚀 2023-04-20
语言的边界就是思想的边界 —维特根斯坦 《逻辑哲学论(Tractatus Logico-Philosophicus)》
- 软件工程是一个知识管理过程,是关于人的。技术是载体而已
- 所以tdd上来先要讲任务分解,理解需求和架构。至于框架,重构,都是载体
- 16、17、18课是这个项目里 三次大重构的第一次
TDD,愿人们都尊你的名为圣,愿你的国降临,愿你的旨意行在产品测试,如同行在开发。我们日用的测试,今天赐给我们,免了我们的技术债,如同我们免了人的债不叫我们遇到恐惧,救我们脱离凶恶。因为国度、权柄、荣耀,全是你的,直到永远,阿们。
凝聚团队
- 在回顾会议之前
- 组员要宣誓
- 就是 无论发生了什么,我们都相信每个人都在他力所能及的范围进了最大的努力
- 从而 进入 对事不对人模式
- 这是 the power of word,说出来的话,就具有凝视的效果
- 福科说的
- 因而,言语是规定我们行为重要的工具。所谓,说着说着自己就信了
- 以团队的价值观代替个人的
- 只是在 回顾的时候,要这样
- 每个人都带着 个人之见,都愿意评价别人
- 这是现实。通过任何手段,放弃这两种行为,对于团队都是有意义的
- 特别是在 回顾 会的时候
- 好的团队领袖,2次回顾,就能把团伙拧成团队
程序员与电车
- 再说一个
- 比如为什么要代码共有
- 在一张卡,没写完的时候,换结对,让更多人写一个卡。而不是让一个人写完
- 从资本家角度来说,这是降低风险,不要被一个人锁死
- 跟指数基金一个道理
- 只要不是全员离职,我就玩得下去
- 对个人有什么好处?一开始我们只能说,可以随时休假啊。不会因为太重要,而被迫加班啊
- 直到2011年前后,hbr,哈佛商业评论
- 讲了一个调查,组织内,最容易被提升的是第二重要的人
- 因为第一重要的,必须在他现在的岗位上
- 所以实际情况是,你累死累活,不仅没有得到休息,还可能丧失晋升的机会
- hbr那篇就是将,每个人要从工作岗位上disposiable 才能晋升
- 所以,从个人出发,当机会来了,你能上
- 你也得代码共有
- 专有代码会让你的工作安全,而职业不安全
- 这与大多数人的想法是反的
- 而敏捷一开始就告诉你,要代码共有
- 高效而不安全
- 有个叫 电车指数
- 一个电车失控,你们团队损失几个人,项目还能继续
- 一般团队都是1
- 就是最重要那个dev,陨落了就瞎菜
- 主管不怕被挖吗?不是不怕,是他想不到,因为管理水平低
- 代码共有,指责共担
- 不要到个人,团队负责
- 当然了,如果测试够,这种情况也少
大家和姚琪琳老师成为了同学
Thoughtworks 资深咨询师,技术书籍译者
拥有超过十年的软件开发、设计和架构经验。近年来在企业遗留系统现代化、领域驱动设计、敏捷软件开发、整洁代码和重构等方面持续精进,并通过理论指导、实战演练等方式为企业研发团队赋能。参与翻译或审校多本技术书籍,包括《领域特定语言》《.NET 性能优化》《深入理解 C#》等。
2022-04-21 🚀 2023-04-23
- DeepL 翻译
- 对 K8S 友好的虚拟机
- GraalVM 小 启动快
- Quarkus 是一个为 Java 虚拟机(JVM)和原生编译而设计的全堆栈 Kubernetes 原生 Java 框架,用于专门针对容器优化 Java,并使其成为无服务器、云和 Kubernetes 环境的高效平台。
- micronauts
DDD 怎么存 User
- 这里有个隐藏概念,叫cascade lifecyle
- 比如,user是持久化的
- 那么user.add(order),无论order状态是什么,应该也是持久化的
- 生命周期的传递性,这才符合对象的语意
- 所以,讨论来讨论去,实际问题是,怎么处理领域对象的级联生命周期
- Users,实际是表示的是,持久化的User集合
- 所以,users.add(user),可以看作,级连生命周期起作用,将非持久的放入持久化集合,他也变成持久的了
- 概念上没问题
- 然而在实际中,如果users不是jpa,jdo这种
- 那么存在一个封装破坏
- 在users里,可能需要,db.insert(user.getName, user.age)这样的东西
- 那么可以让users持有一个mapper,或者dao
- 然后,users.add(user) { user.save(this.mapper);}
- 就两全其美了。collection对象封装了如何持久,如何传递生命周期
- user封装自己的数据,等人传进去mapper,把数据仍进去
- 举个更具体的:mapper就是SQLStatement
- 然后 insert.execute(user.getName(),user.getAge());
- 和对比,user.save(SQLStatement insert) {
- Insert.execute(this.name, this.age, ….)
- 差别就在最后数据访问是不是能局部化
- 当然我说了,如果用jpa/jdo无所谓
- 反正框架帮你做了
- 群友提问:这里的概念Users和userRepo等价对哇
- userRepo就是集合对象
- 这也是userRepo和userDAO的区别
- 别看实现起来可能一模一样 但其实不是一个模式
- DAO的问题是数据访问
- Repo的问题是,聚合根的生命周期
- DAO的方案是,CRUD
- Repo的方案是构造一个集合对象,解决聚合根生命周期
- 方案是不能定义模式的,问题才行
手速慢就代表开发慢吗?
- 软件根本复杂度的解决是靠思考
- 多在任务分解上下功夫
- 话说,我们之前有个同事,手速极慢:二指流
- 但是研发效率能在前15%
- 因为想的快,想的准
- 那点手速,随便就抹平了
- 我只是觉得,以大多数研发的水平,根本到不了拼手速的时候
- 先把需求想对吧
- 然后还有,就是词汇量
- 手速快,但是拼不出来,你快有啥用
如何持续交付(CD)
- 只有可工作的软件 才是进度唯一的度量
- 而 测试 是以可工作软件的形式 表示的进度
- 我估算 cycle time:统一不超三天
- 守下限 不追最优
- 但是下限必须守住
- 100个功能100天 5个人干 就是 不超5天
- 超五天就是事故
- 别整没用的
- 我管你百分之几 不关心
- 就是 事故 和没有事故
说一下学习重构这部分 ⭐️⭐️⭐️⭐️⭐️
- 第一个你们可以反思一下,bad smell 是什么的,是怎么发现的。这个最重要。
- 第二个,对比重构前和重构后的代码结构。到底做了什么改变。这个慢慢你们就会养成习惯,有重构的大局观。
- 第三个,列一下用的重构手法,看如何改变的。这个反而没那么重要,每个人做法也不一样。
我的理解
- 一、bad smell 是什么的,是怎么发现的
- 违反DRY原则(Don’t repeat yourself)的最多
- 实现逻辑:代码重复基本可以直接看出来(收留心观察就行)
- 测试类:需要在重构后留意是否有重复的逻辑
- 违反YAGNI原则(You ain’t gonna need it)
- 实现逻辑:一波操作后,Idea 会提示没有被用到的变量、方法
- 测试类:需要在重构后留意是否有没有被用到的代码
- 违反 KISS原则(Keep it simple, stupid)
- 实现逻辑:尽量让代码朝着更简单的方向发展
- 违反单一职责原则
- 一个类或方法承担了多个职责
- 总结:当违反 设计原则的时候,就是 bad smell,需要及时重构
- 违反DRY原则(Don’t repeat yourself)的最多
- 二、对比重构前和重构后的代码结构,到底做了什么改变
- 重构前:
- 简单粗暴实现功能,不要给我说什么设计原则、设计模式、数据结构、拿起键盘就是干!一把梭!
- 对测试友好(因为是 TDD,代码再烂也不能直接翻车)
- 对后期维护不友好,代码有点乱
- 重构后:
- 大部分代码符合设计原则、合理套用设计模式、正确使用数据结构
- 对测试友好
- 对后期维护友好,代码整洁、逻辑清晰
- 重构前:
- 三、列一下用的重构手法,看如何改变的
- 使用 Idea 快捷键进行重构(Extract 变量、方法参数、方法、类;inLine 方法;构造工厂方法;尽量使用接口等)
- 通过绞杀植物模式替换旧的实现
- 姚琪琳老师的 遗留系统现代化实战 | 06 | 以增量演进为手段:为什么历时一年的改造到头来是一场空?中有详细介绍
2022-04-24 🚀
群友问:测试到底应该测试动态的过程还是静态的结果?
问题举例
- S(t) = S(t-1, delta)
- 对于线性系统 可以改写 S(t) = S(t-1) + F(delta)
答
- 计算机里有个基本的等价关系
- computation 等价于 data
- 2 和 1 + 1是等价的。只不过一个是数据,一个是计算
- 所以你说的,其实是一回事,两者其实并没有什么区别
- 计算和数据等价有很多用处
- 比如cache,也是一个意思
- 还有 lazy evaluation
- 包括stateless,event architecture,都是这个在更大范围的应用
- S(t-1, delta) => S(t) 更一般的形式是 eval(ctx, statement) = value
- 有个隐含上下文
- 时序差,是ctx before 和 ctx after
- S(t-1, ctx) => S(t, ctx’)
- 时间也就变成状态改变,也就变成数据或者计算了
- 这就是利用 lambda calc
- 等价图灵机的基本思路
- 把纸带建模成,状态/数据流
- 时序操作就只和数据相关了
- 所有测试都是对过程(计算)测试
- 可以从data验证,也可以从computation验证
- 就是状态验证和行为验证
- 哪个好用用哪个(注:奥卡姆剃刀原理,如果你有两个或多个类似的解决方案,选择最简单的)
无论是行为验证,还是状态验证,最后都只能验证状态
- mock,spy,也是记录了发生了什么。判断是不是如期待一样
2022-04-25 🚀 2023-04-27
- 不同语言里,坏味道不一样
- 有好多年,我学一门语言的路径,就是写这个语言的编译器
- 然后,我准备做点不一样的
- API设计跟用户体验设计一样。最好是don’t make me think
- 热心群友:Neal Ford 是一个拥有多重身份的传奇式人物。作为跨国数字化转型咨询公司ThoughtWorks的总监、软件架构师,他精通各种编程语言,为大规模企业应用的设计、构建和工程实践提供咨询服务;作为国际知名讲师,他登上过许多世界顶级开发者会议的讲台;作为极客和作家,他著有多本广受好评的畅销书,如《卓有成效的程序员》、《函数式编程思维》
2022-04-28 🚀 2023-04-29
TDD 强在哪
- tdd是工程化方法 所谓工程化 就是一堆人一起干
- 一个人踢正步 和一群人走方阵是俩任务
结对编程的好处
- 基本上你写个测试,5分钟实现不了,基本上就能知道你知识有缺陷
- 可以进去学习模式了,现在的任务跟你没关系了,因为你不会
- 这也是pair的一个重要好处
- 总得有一个人会吧…两人都不会,也比较好意思找人帮忙
- 因为 没有把“个人”拎出来,感觉有个伴,好一点
- 要么有一个人会,学习马上发生了
- 要么俩人都不会,一起找人帮助,不需要复杂的心理建设
- 你知道有多少项目延期,是毁在这种无聊的自尊上吗
- 不行,我不能让别人知道我是弱鸡
- 然后项目就超期了…
- 然后,你发现很多人反对tdd
- 因为弱鸡无处藏
- 而且,任务一分,你需求理解没理解,架构理解没理解,不是马上就知道了吗
- 软件工程:是围绕知识管理的社会工程,是管人的
- tdd 在于把你的理解显示化为别人可理解的东西
- 你藏不住的,弱鸡都不爱tdd,因为暴露无疑
- 一天都活不下来,心理压力太大
2022-04-30 🚀 2023-05-19
工程化的 TDD 可以提升开发效率
- 原教旨xp是非常紧耦合的实践集合,tdd要和pair,refactoring,simple design一起来
- tdd是testability driven,可测试性
- 要做到,过程可管理,成本时效可管理,就一定要按照测试试性 分解 成不同验收节点
- 那就是 可测试性驱动
- 现在明确要求分解任务的 工程方法 就是tdd
- 明确要求分解成 可细粒度验收的节点的 就是tdd
- 因为要给管理者看,这些节点可验证,才需要拆开
- 因为是工程方法,才要求所有人一样
- 首选我们可以说什么不是工程方法
- 比如 做实验 就不是工程方法,是启发式过程 成本不一定能确定 怎么做也不一定能知道
- 然后你发现 行业里一堆人其实写软件就跟做实验一样,也不知道多久 也不知道怎么做 也不知道做的啥,边stackoverflow 边做
- 这绝对不能叫工程化
- 你就想 你是个包工头,给人铺厕所
- 主人给你5000你干还是不干?
- 你得明确知道我要怎么铺、用多少砖、几天
- 你不能铺着看吧
- 最近行业里就有一门手艺刚工程化,就是ML,之前几乎都是实验性的启发过程
- 现在 项目结构 流程节点 产物管理依次都工程化了
- 工程不依赖个人,依赖团队
- 比如tdd为什么要明显地把工作拆分出来,不只是给你自己看的,更是给团队里人看的
- 看 我想清楚了 我会做
- 你的开发活动 就从个体行为 变成了 工程的一部分
- 工程化思路 是 不依赖个人 而依赖岗位:如果把任务分清了 那么就不需要 某个人 而需要能实现这个任务的角色
- 工作内容的具体化澄清 是让每个人都可替代
- 从工程的角度才可管理
- Adam Smith 《国富论》前两章;资本主义基石的基石
- tayler 科学管理方法
- 软件难以工程化的原因就是 工作内容难以澄清
- 而 tdd是目前 唯一要求 持续澄清工作内容的方法
- 对日软件也是一种工程化(文档化澄清)
- tdd是通过可测试化澄清
- 为什么机器人来了 程序员就都tdd了
- ai coding首先要替代 写生产代码的
- 这样思路才对 反正结对编程也是 资深写测试 小白写生产
- 所以学好tdd 顺利进入ai时代 (视频)
结对编程与权利
- 请把pair 理解为 边沁的环形监狱
- 这是一种重要的机制,因为它使权力力自自动化和非个性化权力不再体现在某个人身上,而是体现在对于肉体、表面、光线、目光的某种统一分配上,体现在一种安排上。这种安排的内在机制能够产生制约每个人的关系。
- 这是福科说的
- 执行权力的成本过高的话 权力其实也没啥用
- 这也是一个会了不用看,看了也不会的书《金字塔原理》
拆分任务的建议
- 不能分解成大小恰当(15-90分钟)独立可验证的功能,就还是不行
- 和业务上下文无关,这样要分解成什么样都行
建模数据如何分页
- user.getSubscriptions(OrderBy.xxx).subList(100, 150)
- 你封装了集合对象,那么排序就不是集合自己的逻辑
2023-05-20 🚀 2022-05-29
Idea 简洁设置
- https://www.jetbrains.com/lp/intellij-new-ui-preview/
- JetBrains 表示,他们的目标是降低 IDE 的视觉复杂性,提供对基本功能的便捷访问,并根据需要逐步公开复杂的功能 —— 从而构建他们认为干净、现代和强大的外观。新 UI 是对现有 JetBrains IDE 产品线的重新设计,他们更改了主 IDE 窗口的外观和视觉,以及部分 UX 方面的变动,所有以代码为中心的功能和集成都像以前一样运行。新 UI 会确保与所有 IntelliJ 插件完全兼容
- 双击 shift键 ,输入 registry ,将 ide.experimental 开头的都勾上就可以体验了
- ide.experimental.* 全部打✓ 重启 IEDA
MyBatis 的优雅
- 用mybatis,抽象地实现分库分表,还是很优雅的
- 然后你会发现 其实你实现了一个jpa
- db属于典型的一致性优先的系统
- 插入和索引更新是同步的
- 分布了之后 要做很多取舍,具体要看业务
2023-09-14 🚀 2022-10-07
评估开发时间:预研与开发要分开
- 预研工作,重要的仍旧是反馈速度与反馈质量
TDD 不是追求测试覆盖率 100%
- TDD 也可能不是100% 比如checked exception
- 目的不是 100% 覆盖
- 同样是 100% 覆盖,“行为覆盖”和“功能覆盖”效果也不一样
- 之所以不强调 100%,在于有的时候:你就是得行为测才能 100%
- 比起看起来爽 测试质量更重要
- 注意力在覆盖率就跑偏了
- 优先覆盖重要的处理逻辑
- 正常 TDD 达到 95% 以上几乎是必然了,比这个低就要想想了
- 但不是100%的话,在团队做的时候,就很难设置这个门禁。当然个体和互动重于流程和工具。门禁或许也不重要。
- 这都是不结对的补丁,其实也没什么大用
- 强调覆盖率 实际就是说 写测试手段不重要 最后数字凑上就行了,那能推好 TDD 才怪