8lovelife's life
0%

基于Docker的代码质量持续约束流程搭建

为了提高团队整体的代码质量,有必要搭建一套持续的代码约束流程。本文记录基于Docker如何搭建自动化代码检测流程

阅读全文 »

记录在Docker上创建单broker的Kafka过程

安装运行Kafka

创建bridge网络

1
docker  network create -d  bridge --subnet=10.0.0.0/24 kafka_net

启动zookeeper

1
docker run --restart=always -d -ti --name zookeeperService --network=kafka_net -p 2181:2181 -v /home/core/zookeeper/conf:/conf -v /home/core/zookeeper/data:/data -v /home/core/zookeeper/dataLog:/dataLog zookeeper

验证zookeeper是否启动正常

1
docker run --rm -it --network=host zookeeper  zkCli.sh -server localhost:2181  
阅读全文 »

记录下Java中常用的Collection与Map

Collection

常用的集合类图

image

常用Collection对比

image

Map

常用的Map类图

image

常用Map对比

image

Mathematics is the only true universal language. - John Nash

A Beautiful Mind

记录下多线程情况下,如何避免资源竞争带来的问题

资源竞争

多线程在运行期间,若存在数据的共享,不同线程对资源的争抢会造成彼方线程的处理错乱。下面是两个线程将数值从零累加10次的例子(预计结果为10)

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
class Count implements Runnable {

private int countResult = 0;

@Override
public void run() {

for (int i = 0; i < 5; i++) {
count();
}

}

private void count() {

try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
int temp = countResult;
countResult++;
System.out.println(Thread.currentThread().getName() + " Count Before " + temp + ", Count After "
+ countResult);

}

public void countResult() {
System.out.println("The result of count is " + countResult);
}

}

Count count = new Count();
Thread t1 = new Thread(count, "T1");
Thread t2 = new Thread(count, "T2");

t1.start();
t2.start();
t1.join();
t2.join();
count.countResult();

// 输出
T1 Count Before 0, Count After 1
T2 Count Before 1, Count After 2
T1 Count Before 2, Count After 3
T2 Count Before 3, Count After 4
T2 Count Before 5, Count After 6
T1 Count Before 4, Count After 6
T2 Count Before 6, Count After 7
T1 Count Before 7, Count After 8
T1 Count Before 8, Count After 9
T2 Count Before 8, Count After 9
The result of count is 9 // 并非是预期的结果 10

image

当线程或进程依赖某一资源(代码中的countResult),会发生资源竞争。使针对资源的操作互斥,能够解决资源竞争带来的结果不可预测

阅读全文 »

记录下Java中多线程的使用

线程的生命周期

  1. NEW:线程被创建未启动
  2. RUNNABLE:线程为启动状态,被虚拟机执行或者是等待系统资源中
  3. WAITING:线程调用 Object.wait、Thread.join或LockSupport.park方法,线程进入WAITING状态
  4. TIMED_WAITING:线程调用 Thread.sleep 、Object.wait(10) 、Thread.join(10)、LockSupport.parkNanos 或 LockSupport.parkUntil方法 ,线程进入TIMED_WAITING状态
  5. BLOCKED:线程等待获取锁
  6. TERMINATED:线程死亡

image

阅读全文 »

记录下并发与多线程的一些知识

并发的前提

多核CPU与缓存

image

多处理器与多核心

  • 多处理器:即多个独立的CPU单元
  • 多核心:每个CPU单元有单个或多个核心,当存在多核心的CPU运行多线程时,那么这些线程是可以并行的。单核心的CPU是否不存在线程的并行?并非如此,若单核心的CPU拥有Hyper-threading技术,那么单核心可以并行的运行两个逻辑线程

并发/并行

  • Concurrency 指的是运行的多线程间存在资源的共享(或者运行的多线程会执行同一段代码片段)。单核、多核都可能存在并发,这种并发若不做相应的控制则会引起安全问题。并发多指发生在同一时间段
  • Parallelism 指的是在多个独立的核心或多个独立的CPU上运行的多线程,并行不存在线程间的数据共享,需要硬件支持(多核、多处理器)。并行发生在同一时刻

image

阅读全文 »

记录下Git如何与IntelliJ IDEA协作

环境准备

IntelliJ IDEA With Git 开发过程

1. 初次获取远端代码

  • 使用IntelliJ IDEA Terminal

image

1
2
Mac:code mac$ git clone https://github.com/grpc/grpc-java.git
Cloning into 'grpc-java'...

2. 查看远端仓库分支

1
2
3
4
5
Mac:dmz-inward- mac$ git branch -av
* master 0388b70 some feture
remotes/origin/HEAD -> origin/master
remotes/origin/feature cd52891 some features
remotes/origin/master 0388b70 some feture
阅读全文 »

线程间的通信

线程间的通信方式有:共享内存和消息传递

共享内存

多个线程通过读写内存中的共享对象来隐式的进行通信。如Java中的对象

消息传递

线程间通过发送消息显示的进行通信。如Java中的wait()/notify()

线程间共享内存

线程间共享的对象都在主存中,每个线程都会有一块私有的本地内存称为栈,线程栈中存储了共享对象的副本

线程安全

线程安全包括几个方面的内容:1。原子性 2。可见性 3。有序性

原子性(执行控制-代码顺序)

原子性提供了多线程间代码指令的互斥访问。如:Synchronized、Lock

可见性

一个线程对共享内存数据的修改是否会立刻被其他线程感知到?多线程间的共享数据访问会由于缓存的不一致性导致数据错乱
image

阅读全文 »

记录下单例模式的几种实现

单例模式

单例类保证在系统中始终只有一份类的实例,单例模式能够节约内存空间,对于整个系统中共性的逻辑可以采用单例模式。分布式系统中ZK就像是整个系统中的”单例”

单例的实现

单例的实现方式有多种,根据实例化时机可分为饿汉、懒汉模式

饿汉模式

1
2
3
4
5
6
7
8
9
10
public class Singleton {
private static final Singleton singleton = new Singleton();

private Singleton() {
}

public static Singleton getInstance() {
return singleton;
}
}

单例在类的加载时就完成了类的实例(即使这个类还没被使用)

阅读全文 »

回顾回顾JVM中的类加载

类的生命周期

类的生命周期包括类的加载、链接、初始化、使用、销毁
image

类装入JVM

将类装入JVM供使用的过程分为:类的加载、链接、初始化

  • 显示装入:1。 调用类加载器中的loadClass方法 2。调用Class.forName方法
  • 隐示装入:解析类中引用的其他类的时候,所引用的类未被加载时则被隐示装入

类的加载

类的加载包括

  1. 将.class文件加载到JVM方法区中
  2. 在堆中生成Class对象,Class对象提供了访问方法区中类数据结构的接口

    这一阶段类对象仅有基本的内存结构,类对象中的方法、字段、引用都不做处理,此时的类还不能使用

类的链接

类的链接将内存中二进制数据转换到JVM运行数据区,链接包括验证、准备、解析

  • 验证:验证类的字节码是否合法
  • 准备:为类的静态变量分配内存并设置默认值
1
2
final static int a = 10  准备阶段阶段 a 的默认值为 10
static int b = 10 准备阶段 b 的默认值为 0
  • 解析:将常量池中的符号引用替换为直接引用,解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符7类符号引用进行
阅读全文 »