ARTS 第59周

ARTS (第59周)

会的越多,不会的越多。

知道的越多,不知道的越多。

Algorithm 算法

二叉搜索树的第k个结点

1
2
3
题目描述
给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。
https://www.nowcoder.com/practice/ef068f602dde4d28aab2b210e859150a?tpId=13&tqId=11215&tPage=4&rp=4&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

解法1 中序遍历 记录已遍历过的数量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

int KthNode_num = 0;
TreeNode KthNode_(TreeNode pRoot, int k) {
if (pRoot == null || k <= 0) {
return null;
}
return KthNode_helpe(pRoot, k);
}

public TreeNode KthNode_helpe(TreeNode node, int k) {
if (node == null || KthNode_num > k) {
return null;
}
TreeNode left = KthNode_helpe(node.left, k);
if (left != null)
return left;
if (++KthNode_num == k) {
return node;
}
TreeNode right = KthNode_helpe(node.right, k);
if (right != null)
return right;
return null;
}

解法2 用栈来实现中序遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
TreeNode KthNode(TreeNode pRoot, int k) {
if (pRoot == null) {
return null;
}
int num = 0;
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode res = null;
while (!stack.isEmpty() || pRoot != null) {
while (pRoot != null) {
stack.push(pRoot);
pRoot = pRoot.left;
}
TreeNode cur = stack.pop();
if (++num == k) {
res = cur;
break;
}
pRoot = cur.right;
}
return res;
}

Review 英文文章

https://spring.io/guides/gs/accessing-data-mongodb/

spring配置MongoDB

Tip 技巧

重构

重构的目的:为什么重构(why)?

对于项目来言,重构可以保持代码质量持续处于一个可控状态,不至于腐化到无可救药的地步。对于个人而言,重构非常锻炼一个人的代码能力,并且是一件非常有成就感的事情。它是我们学习的经典设计思想、原则、模式、编程规范等理论知识的练兵场。

重构的对象:重构什么(what)?

按照重构的规模,我们可以将重构大致分为大规模高层次的重构和小规模低层次的重构。大规模高层次重构包括对代码分层、模块化、解耦、梳理类之间的交互关系、抽象复用组件等等。这部分工作利用的更多的是比较抽象、比较顶层的设计思想、原则、模式。小规模低层次的重构包括规范命名、注释、修正函数参数过多、消除超大类、提取重复代码等等编程细节问题,主要是针对类、函数级别的重构。小规模低层次的重构更多的是利用编码规范这一理论知识。

重构的时机:什么时候重构(when)?

我反复强调,我们一定要建立持续重构意识,把重构作为开发必不可少的部分,融入到日常开发中,而不是等到代码出现很大问题的时候,再大刀阔斧地重构。

重构的方法:如何重构(how)?

大规模高层次的重构难度比较大,需要组织、有计划地进行,分阶段地小步快跑,时刻让代码处于一个可运行的状态。而小规模低层次的重构,因为影响范围小,改动耗时短,所以,只要你愿意并且有时间,随时随地都可以去做。课堂讨论

来源于极客时间《设计模式之美》

https://time.geekbang.org/column/intro/250

代码的可测试性

粗略地讲,所谓代码的可测试性,就是针对代码编写单元测试的难易程度。对于一段代码,如果很难为其编写单元测试,或者单元测试写起来很费劲,需要依靠单元测试框架中很高级的特性,那往往就意味着代码设计得不够合理,代码的可测试性不好。

依赖注入是编写可测试性代码的最有效手段。通过依赖注入,我们在编写单元测试的时候,可以通过 mock 的方法解依赖外部服务,这也是我们在编写单元测试的过程中最有技术挑战的地方。

常见的测试不友好的代码有下面这 5 种:代码中包含未决行为逻辑滥用可变全局变量滥用静态方法使用复杂的继承关系高度耦合的代码

来源于极客时间《设计模式之美》

https://time.geekbang.org/column/intro/250

什么是URI

URI,通一资源标志符(Uniform Resource Identifier, URI),表示的是web上每一种可用的资源,如 HTML文档、图像、视频片段、程序等都由一个URI进行定位的。
URL是URI的一个子集。它是Uniform Resource Locator的缩写,译为“统一资源定位 符”。

什么是URL

通俗地说,URL是Internet上描述信息资源的字符串,主要用在各种WWW客户程序和服务器程序上。

采用URL可以用一种统一的格式来描述各种信息资源,包括文件、服务器的地址和目录等。URL是URI概念的一种实现方式。

测试类别

单元测试是对软件组成单元进行测试。其目的是检验软件基本组成单位的正确性。测试的对象是软件设计的最小单位:模块。又称为模块测试

集成测试也称联合测试(联调)、组装测试,将程序模块采用适当的集成策略组装起来,对系统的接口及集成后的功能进行正确性检测的测试工作。
将软件系统看成是一个系统的测试。包括对功能、性能以及软件所运行的软硬件环境进行测试。

验收测试是部署软件之前的最后一个测试操作。它是技术测试的最后一个阶段,也称为交付测试。

回归测试是指修改了旧代码后,重新进行测试以确认修改没有引入新的错误或导致其他代码产生错误。

Share 分享

https://blog.csdn.net/freeager/article/details/80260033 maven私服,添加阿里云仓库

不知道如何命名,推荐:Codelf(变量命名神器)

代码中的很多低级质量问题不需要人工去审查,java开发有很多现成的工具可以使用,比如:checkstyle,findbugs, pmd, jacaco, sonar等。