Math

Computer Science

Algorithm & Data Structures

Compiler & Interpreter

Operating Systems

Database

Networking

Linux

Programming

Programming Languages

C

Java

JavaScript

TypeScript

Python

Clojure

Ruby

Racket

Rust

Go

OCaml

Haskell

Redis

Git

German

Others

首先构建一个多模块的 Maven 项目,项目结构如下:

1
2
3
4
5
6
7
├── product-service
│ └── pom.xml
├── sum-service
│ └── pom.xml
├── app
│ └── pom.xml
├── pom.xml

其中 product-servicesum-service 表示功能代码,app 负责测试用例的整合。product-servicesum-service 分别包含一个 ProductService 类和 SumService 类,具体代码如下:

1
2
3
4
5
6
// ProductService
public class ProductService {
public int product(int x, int y) {
return x * y;
}
}
1
2
3
4
5
6
// SumService
public class SumService {
public int sum(int x, int y) {
return x + y;
}
}

app 内的测试用例如下:

1
2
3
4
5
6
7
public class AppTest {
@Test
public void shouldCalculateCorrectSumAndProduct() {
Assert.assertEquals(10, new ProductService().product(2, 5));
Assert.assertEquals(5, new SumService().sum(2, 3));
}
}

然后在 root 模块的 pom.xml 文件中配置 JaCoCo 插件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.5</version>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

最后在 app 模块的 pom.xml 文件中配置 JaCoCo 插件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<argLine>${argLine} -Xms256m -Xmx2048m</argLine>
<forkCount>1</forkCount>
<runOrder>random</runOrder>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.5</version>
<executions>
<execution>
<id>report-aggregate</id>
<phase>test</phase>
<goals>
<goal>report-aggregate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

此时在 root 模块下执行 mvn test,执行成功后在 app/target/site/jacoco-aggregate 目录下就会生成各个模块的覆盖测试报告:

alt

完整的代码可参考 GitHub

参考:

在某个 Web 应用中,引用了 豆瓣读书 的图片,大部分图片会无法显示并返回 403 Forbidden 错误,一个可能的原因是触发了 豆瓣 的图片防盗链机制。

一般来说,防盗链机制会判断图片请求的 Request Headers 里的 Referer 字段的值是否是允许的地址,如果不是,则不允许访问相应的资源。所以,一种可能的解决办法是在 HTML 页面中设置 Referrer-Policyno-referrer,在发送 HTTP 请求时不发送 Referer 信息:

1
<meta name="referrer" content="no-referrer" />

参考:

由于网络原因,Flutter 项目获取包依赖时有可能会失败,可通过设置镜像地址解决,新增如下两个环境变量即可:

1
2
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn

参考:

在某些场景下,我们会使用 {} 来存储某类对象的映射关系,例如车主和车子的映射关系可记为:

1
2
3
4
{
'Alice': new Car(),
'Bob': new Car()
}

而在 TypeScript 中声明这种对象的类型时遇到了问题:该对象的属性名是未知的,不过所有属性名对应的值的类型是确定的。这种情况下可以借助 Indexable Types 解决,以上述的例子为例:

1
2
3
4
5
6
7
8
interface CarOwners {
[key: string]: Car;
}

const carOwners: CarOwners = {
'Alice': new Car(),
'Bob': new Car()
}

参考:

可以使用清华大学开源软件镜像站上的镜像。例如需要下载 Ubuntu 18 的镜像,先在站内找到对应镜像的地址(例如:https://mirrors.tuna.tsinghua.edu.cn/ubuntu-cloud-images/bionic/20191211/bionic-server-cloudimg-amd64-vagrant.box),然后在终端执行 vagrant box add 镜像的地址 --name ubuntu/bionic,下载完成后即可执行 vagrant init ubuntu/bionic 等操作。

参考:

I opened a git repo by VS Code, but it shows No source control providers registered. One possible reason is that VS Code couldn’t find the executable git command, so we can set the executable path of git in settings. Open File -> Preferences -> Settings, then find the Git: Path setting, click Edit in settings.json, and add "git.path": "full-path-to-git" to settings.json.

Reference:

Integer 类的内部维护了一个 IntegerCache 的静态类,默认缓存了-128到127的 Integer 对象,而 java.lang.Integer#valueOf(int) 方法执行时会判断参数是否在-128到127之间,如果在这个区间,则返回 IntegerCache 内部的缓存对象,所以 Integer.valueOf(127) == Integer.valueOf(127)True

不过,整型缓存只适用于自动装箱的情况,不适用于通过构造函数创建的 Integer 对象间的比较,在下述代码中,最终的输出结果是 integer1 == integer2integer3 != integer4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Integer integer1 = 3;
Integer integer2 = 3;

if (integer1 == integer2) {
System.out.println("integer1 == integer2");
} else {
System.out.println("integer1 != integer2");
}

Integer integer3 = new Integer(3);
Integer integer4 = new Integer(3);

if (integer3 == integer4) {
System.out.println("integer3 == integer4");
} else {
System.out.println("integer3 != integer4");
}

Integer integer1 = 3 发生了自动装箱,编译器会将其等价转换为 Integer integer1 = Integer.valueOf(3),所以 integer1 == integer2。而通过构造函数创建的 Integer 对象属于不同的对象,指向不同的内存地址,所以 integer3 != integer4

另外,可以通过增加虚拟机的参数 -XX:AutoBoxCacheMax=size 来设置整型缓存的最大值,如 -XX:AutoBoxCacheMax=500 表示-128到500的整型会被缓存。

参考:

0%