Skip to content

Commit c46705d

Browse files
authored
Merge pull request #5 from JavaCourse00/main
merge
2 parents b2b2047 + 672a304 commit c46705d

9 files changed

Lines changed: 216 additions & 33 deletions

File tree

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
11
package io.kimmking.java8;
22

3-
import lombok.Data;
3+
import lombok.*;
4+
import lombok.extern.slf4j.Slf4j;
45

5-
@Data
6+
@ToString
7+
@NoArgsConstructor
8+
@AllArgsConstructor
9+
@Slf4j
10+
@Builder
11+
@Getter
12+
@Setter
613
public class A {
7-
14+
815
private int age;
9-
16+
17+
private String name;
18+
1019
}

04fx/java8/src/main/java/io/kimmking/java8/GenericDemo.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package io.kimmking.java8;
22

3+
import java.io.Serializable;
34
import java.lang.reflect.ParameterizedType;
45
import java.lang.reflect.Type;
56

6-
public class GenericDemo {
7+
public class GenericDemo implements Serializable {
78
public static void main(String[] args) {
89
Demo demo = new Demo();
910
Class clazz = demo.getClass();
@@ -20,7 +21,7 @@ public static void main(String[] args) {
2021
System.out.println(c);
2122
}
2223

23-
public static class Person<T> {
24+
public static class Person<T extends Serializable> {
2425

2526
}
2627

04fx/java8/src/main/java/io/kimmking/java8/GuavaDemo.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ private static void testEventBus() {
4848
// Callback/Listener
4949
//
5050
Student student2 = new Student(2, "KK02");
51-
System.out.println("I want " + student2 + " run now.");
51+
System.out.println(Thread.currentThread().getName()+" I want " + student2 + " run now.");
5252
bus.post(new AEvent(student2));
5353
}
5454

@@ -81,6 +81,7 @@ private static List<Integer> testList() {
8181
List<Integer> list = Lists.newArrayList(4,2,3,5,1,2,2,7,6);
8282

8383
List<List<Integer>> list1 = Lists.partition(list,3);
84+
8485
print(list1);
8586
return list;
8687
}
@@ -89,10 +90,11 @@ private static List<String> testString() {
8990
// 字符串处理
9091
//
9192
List<String> lists = Lists.newArrayList("a","b","g","8","9");
93+
9294
String result = Joiner.on(",").join(lists);
9395
System.out.println(result);
9496

95-
String test = "34344,34,34,哈哈";
97+
String test = "34344,,,34,34,哈哈";
9698
lists = Splitter.on(",").splitToList(test);
9799
System.out.println(lists);
98100
return lists;
@@ -111,7 +113,7 @@ public static class AEvent{
111113

112114
@Subscribe
113115
public void handle(AEvent ae){
114-
System.out.println(ae.student + " is running.");
116+
System.out.println(Thread.currentThread().getName()+" "+ae.student + " is running.");
115117
}
116118

117119

04fx/java8/src/main/java/io/kimmking/java8/LambdaDemo.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,20 @@ public Integer operation(int a, int b) {
1717
};
1818

1919
MathOperation op1 = (a, b) -> 1;
20+
21+
22+
MathOperation op2 = new MathOperation<Integer>() {
23+
@Override
24+
public Integer operation(int a, int b) {
25+
return a+b;
26+
}
27+
};
2028

2129
// 类型声明
2230
MathOperation addition = (int a, int b) -> a + b;
2331

2432
// 不用类型声明
25-
MathOperation subtraction = (a, b) -> a - b + 1.0;
33+
MathOperation subtraction = (int a, int b) -> a - b + 1.0;
2634

2735
// 大括号中的返回语句
2836
MathOperation multiplication = (int a, int b) -> {
@@ -47,9 +55,10 @@ public Integer operation(int a, int b) {
4755
System.out.println("Hello " + message);
4856

4957
// 用括号
50-
GreetingService greetService2 = (message) ->
51-
System.out.println("Hello " + message);
52-
58+
GreetingService greetService2 = (message) -> {
59+
System.out.println(message);
60+
};
61+
5362
GreetingService greetService3 = System.out::println;
5463

5564
Arrays.asList(1,2,3).forEach( x -> System.out.println(x+3));

04fx/java8/src/main/java/io/kimmking/java8/LombokDemo.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
package io.kimmking.java8;
22

33
import lombok.extern.java.Log;
4+
import org.slf4j.LoggerFactory;
45

56
import java.io.IOException;
67

78
@Log
89
public class LombokDemo {
9-
10+
1011
public static void main(String[] args) throws IOException {
11-
12+
13+
A a = new A(1, "KK");
14+
System.out.println(a.toString());
15+
A.builder().age(1).name("KKK").build();
16+
1217
new LombokDemo().demo();
1318

1419
Student student1 = new Student();
@@ -17,6 +22,7 @@ public static void main(String[] args) throws IOException {
1722
System.out.println(student1.toString());
1823

1924
Student student2 = new Student(2, "KK02");
25+
//student2.init();
2026
System.out.println(student2.toString());
2127
}
2228

04fx/java8/src/main/java/io/kimmking/java8/StreamDemo.java

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,7 @@
33
import com.alibaba.fastjson.JSON;
44

55
import java.io.IOException;
6-
import java.util.Arrays;
7-
import java.util.LinkedHashMap;
8-
import java.util.List;
9-
import java.util.Map;
10-
import java.util.Optional;
6+
import java.util.*;
117
import java.util.stream.Collectors;
128

139
public class StreamDemo {
@@ -19,14 +15,14 @@ public static void main(String[] args) throws IOException {
1915

2016
// Optional
2117
Optional<Integer> first = list.stream().findFirst();
22-
18+
2319
System.out.println(first.map(i -> i * 100).orElse(100));
2420

2521
int sum = list.stream().filter( i -> i<4).distinct().reduce(0,(a,b)->a+b);
2622
System.out.println("sum="+sum);
2723

28-
//Map map = list.stream().collect(Collectors.toMap(a->a,a->(a+1)));
29-
Map<Integer,Integer> map = list.parallelStream().collect(Collectors.toMap(a->a,a->(a+1),(a,b)->a, LinkedHashMap::new));
24+
//Map map1 = list.stream().collect(Collectors.toMap(a->a,a->(a+1)));
25+
Map<Integer,Integer> map = list.stream().parallel().collect(Collectors.toMap(a->a,a->(a+1),(a,b)->a, LinkedHashMap::new));
3026
print(map);
3127

3228

04fx/springboot01/src/main/resources/application.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ spring:
1818
enabled: true
1919
max-connections: 10 #连接池最大连接数
2020
idle-timeout: 30000 #空闲的连接过期时间,默认为30秒
21-
21+
2222

2323

2424
data:

README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,14 @@
11
# JavaCourse
2-
JavaCourse
2+
Java进阶训练营示例代码。此处代码,一方面作为作业的基本版本,另一方面需要大家通过调整加深自己对技术点的认识。
3+
4+
本课程的三个要素:
5+
6+
1)40%是课程,包括预习、听课、复习总结,形成自己对知识体系的认识和经验,这是最基本的学习方法。
7+
8+
2)30%是作业,作业包括基础版本的必做作业,补充的选做作业,高难度的挑战作业。基本上完成必做可以通过P6的技术面试,完成选做可以通过P7的技术面试,高难度的话可以达到P7+/P8的技术面试水平。这是通过练习,得到第一手的体验。
9+
10+
3)30%是活动,包括且不限于源码分析学习小组,技术文章活动,读书活动,线下技术沙龙,线上技术分享等。通过一群愿意学习的人,在更好的学习氛围中,实现长期深入学习。
11+
12+
## 挑战作业
13+
14+
每个模块的挑战作业:[homework2.0.md](./homework2.0.md) , 能做出来70%的题目,直接联系我,给你推荐一线大厂工作。

homework2.0.md

Lines changed: 156 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,167 @@
3131

3232
#### 3.2-侧重应用:
3333

34-
1. 10-根据课程提供的场景,实现一个订单处理Service,模拟处理100万订单:后面提供模拟数据
34+
1. 10-根据课程提供的场景,实现一个订单处理Service,模拟处理100万订单:后面提供模拟数据
3535
2. 20-使用多线程方法优化订单处理,对比处理性能
3636
3. 30-使用并发工具和集合类改进订单Service,对比处理性能
37-
4. 30-使用分布式集群+分库分表方式处理拆分订单,对比处理性能:第6模块讲解分库分表
38-
5. 30-使用读写分离和分布式缓存优化订单的读性能:第6、8模块讲解读写分离和缓存
37+
4. 30-使用分布式集群+分库分表方式处理拆分订单,对比处理性能:第6模块讲解分库分表
38+
5. 30-使用读写分离和分布式缓存优化订单的读性能:第6、8模块讲解读写分离和缓存
3939

4040
### 4. 框架
4141

4242
#### 4.1 Spring AOP
4343

44-
1. 10-讲网关的frontend/backend/filter/router/线程池都改造成Spring配置方式
45-
2. 20-基于AOP改造Netty网关,filter和router使用AOP方式实现
46-
3. 30-基于前述改造,将网关请求前后端分离,中级使用JMS传递消息
47-
4. 30-尝试使用ByteBuddy实现一个简单的基于类的AOP
48-
5. 30-尝试使用ByteBuddy与Instrument实现一个简单JavaAgent实现无侵入下的AOP
44+
1. 10-讲网关的frontend/backend/filter/router/线程池都改造成Spring配置方式
45+
2. 20-基于AOP改造Netty网关,filter和router使用AOP方式实现
46+
3. 30-基于前述改造,将网关请求前后端分离,中级使用JMS传递消息
47+
4. 30-尝试使用ByteBuddy实现一个简单的基于类的AOP
48+
5. 30-尝试使用ByteBuddy与Instrument实现一个简单JavaAgent实现无侵入下的AOP
4949

50+
#### 4.2 Spring ORM
51+
52+
1. 基于AOP和自定义注解,实现@MyCache(60)对于指定方法返回值缓存60秒
53+
2. 自定义实现一个数据库连接池,并整合Hibernate/Mybatis/Spring/SpringBoot
54+
3. 基于MyBatis实现一个简单的分库分表+读写分离+分布式ID生成方案
55+
56+
### 5. 数据库与性能
57+
58+
1. 模拟1000万订单数据,测试不同方式下导入导出(数据备份还原)MySQL的速度,包括jdbc程序处理和命令行处理,思考和实践,如何提升处理效率
59+
2. 对MySQL配置不同的数据库连接池(DBCP、C3P0、Druid、Hikari),测试增删改查100万次,对比性能,生成报告
60+
3. 尝试自己做一个ID生成器(可以模拟Seq或Snowflake)
61+
4. 尝试实现或改造一个非精确分页的组件,思考是否可以用于改造自己的业务系统
62+
5. 基于必做作业2.0版本,实现读写分离-数据库中间件版本3.0
63+
64+
### 6. 分库分表
65+
66+
1. 思考总结常用的数据拆分和数据迁移同步方案,以及它们的优势劣势,适用场景,考虑是否可以引入到自己的工作中
67+
2. 设计实现一个简单的XA分布式事务框架demo,只需要能管理和调用2个MySQL的本地事务即可,不需要考虑全局事务的持久化和恢复、高可用等
68+
3. 设计实现一个TCC分布式事务框架的简单Demo,需要实现事务管理器,不需要实现全局事务的持久化和恢复、高可用等
69+
4. 设计实现一个AT分布式事务框架的简单Demo,仅需要支持根据主键id进行的单个删改操作的SQL或插入操作的事务
70+
71+
### 7. RPC与分布式服务化
72+
73+
#### 7.1 RPC与Dubbo
74+
75+
1. 升级作业中的自定义RPC程序:
76+
- 尝试使用压测并分析优化RPC性能
77+
- 尝试使用Netty+TCP作为两端传输方式
78+
- 尝试自定义二进制序列化或者使用kyro/fst等
79+
- 尝试压测改进后的RPC并分析优化,有问题欢迎群里讨论
80+
- 尝试将fastjson改成xstream
81+
- 尝试使用字节码生成方式代替服务端反射
82+
83+
2. 尝试扩展Dubbo
84+
- 基于上次作业的自定义序列化,实现Dubbo的序列化扩展;
85+
- 基于上次作业的自定义RPC,实现Dubbo的RPC扩展;
86+
- 在Dubbo的filter机制上,实现REST权限控制,可参考dubbox;
87+
- 实现自定义Dubbo的Cluster/Loadbalance扩展,如果一分钟内调用某个服务/提供者超过10次,则拒绝提供服务直到下一分钟;
88+
- 整合Dubbo+Sentinel,实现限流功能;
89+
- 整合Dubbo与Skywalking,实现全链路性能监控。
90+
91+
#### 7.2 自定义RPC
92+
93+
1. rpcfx1.1: 给自定义RPC实现简单的分组(group)和版本(version)。
94+
95+
2. rpcfx2.0: 给自定义RPC实现:
96+
- 基于zookeeper的注册中心,消费者和生产者可以根据注册中心查找可用服务进行调用(直接选择列表里的最后一个)。
97+
- 当有生产者启动或者下线时,通过zookeeper通知并更新各个消费者,使得各个消费者可以调用新生产者或者不调用下线生产者。
98+
99+
3. 在2.0的基础上继续增强rpcfx实现:
100+
- 3.0: 实现基于zookeeper的配置中心,消费者和生产者可以根据配置中心配置参数(分组,版本,线程池大小等)。
101+
- 3.1:实现基于zookeeper的元数据中心,将服务描述元数据保存到元数据中心。
102+
- 3.2:实现基于etcd/nacos/apollo等基座的配置/注册/元数据中心。
103+
104+
4. 在3.2的基础上继续增强rpcfx实现:
105+
- 4.0:实现基于tag的简单路由;
106+
- 4.1:实现基于Weight/ConsistentHash的负载均衡;
107+
- 4.2:实现基于IP黑名单的简单流控;
108+
- 4.3:完善RPC框架里的超时处理,增加重试参数;
109+
110+
5. 在4.3的基础上继续增强rpcfx实现:
111+
- 5.0:实现利用HTTP头跨进程传递Context参数(隐式传参);
112+
- 5.1:实现消费端mock一个指定对象的功能(Mock功能);
113+
- 5.2:实现消费端可以通过一个泛化接口调用不同服务(泛化调用);
114+
- 5.3:实现基于Weight/ConsistentHash的负载均衡;
115+
- 5.4:实现基于单位时间调用次数的流控,可以基于令牌桶等算法;
116+
117+
6. 实现最终版本6.0:压测并分析调优5.4版本。
118+
119+
### 8. 分布式缓存
120+
121+
1. 基于其他各类场景,设计并在示例代码中实现简单demo:
122+
- 实现分数排名或者排行榜;
123+
- 实现全局ID生成;
124+
- 基于Bitmap实现id去重;
125+
- 基于HLL实现点击量计数。
126+
- 以redis作为数据库,模拟使用lua脚本实现前面课程的外汇交易事务。
127+
128+
2. 升级改造项目:
129+
- 实现guava cache的spring cache适配;
130+
- 替换jackson序列化为fastjson或者fst,kryo;
131+
- 对项目进行分析和性能调优。
132+
133+
3. 以redis作为基础实现上个模块的自定义rpc的注册中心;
134+
4. 练习redission的各种功能;
135+
5. 练习hazelcast的各种功能;
136+
6. 搭建hazelcast 3节点集群,写入100万数据到一个map,模拟和演示高可用,测试一下性能。
137+
138+
### 9. 分布式消息
139+
140+
#### 9.1 消息队列原理与应用
141+
142+
1. 基于数据库的订单表,模拟消息队列处理订单:
143+
- 一个程序往表里写新订单,标记状态为未处理(status=0);
144+
- 另一个程序每隔100ms定时从表里读取所有status=0的订单,打印一下订单数据,然后改成完成status=1;
145+
- 考虑失败重试策略,考虑多个消费程序如何协作;
146+
- 将上述订单处理场景,改成使用ActiveMQ发送消息处理模式;
147+
- 使用java代码,创建一个ActiveMQ Broker Server,并测试它;
148+
149+
2. ActiveMQ/RabbitMQ作业
150+
- 搭建ActiveMQ的network集群和master-slave主从结构;
151+
- 基于ActiveMQ的MQTT实现简单的聊天功能或者Android消息推送;
152+
- 创建一个RabbitMQ,用Java代码实现简单的AMQP协议操作;
153+
- 搭建RabbitMQ集群,重新实现前面的订单处理;
154+
- 使用Apache Camel打通上述ActiveMQ集群和RabbitMQ集群,实现所有写入到ActiveMQ上的一个队列q24的消息,自动转发到RabbitMQ;
155+
- 压测ActiveMQ和RabbitMQ的性能;
156+
157+
3. 演练本课提及的各种生产者和消费者特性。
158+
159+
4. Kafka金融领域实战:在证券或者外汇、数字货币类金融核心交易系统里,对于订单的处理,大概可以分为收单、定序、撮合、清算等步骤。其中我们一般可以用mq来实现订单定序,然后将订单发送给撮合模块。
160+
- 收单:请实现一个订单的rest接口,能够接收一个订单Order对象;
161+
- 定序:将Order对象写入到kafka集群的order.usd2cny队列,要求数据有序并且不丢失;
162+
- 撮合:模拟撮合程序(不需要实现撮合逻辑),从kafka获取order数据,并打印订单信息,要求可重放, 顺序消费, 消息仅处理一次。
163+
164+
#### 9.2 自定义消息中间件
165+
166+
1. v1.0-内存队列:基于内存Queue实现生产和消费API(示例代码已经完成)
167+
- 创建内存BlockingQueue,作为底层消息存储
168+
- 定义Topic,支持多个Topic
169+
- 定义Producer,支持Send消息
170+
- 定义Consumer,支持Poll消息
171+
172+
2. v2.0-自定义队列:去掉内存Queue,设计自定义Queue,实现消息确认和消费offset
173+
- 自定义内存Message数组模拟Queue。
174+
- 使用指针记录当前消息写入位置。
175+
- 对于每个命名消费者,用指针记录消费位置。
176+
177+
3. v3.0-基于SpringMVC实现MQServer:拆分broker和client(包括producer和consumer),从单机走向服务器模式。
178+
- 将Queue保存到web server端
179+
- 设计消息读写API接口,确认接口,提交offset接口
180+
- producer和consumer通过httpclient访问Queue
181+
- 实现消息确认,offset提交
182+
- 实现consumer从offset增量拉取
183+
184+
4. v4.0-功能全面:增加多种策略(各条之间没有关系,可以任意选择实现),基于TCP实现server->client,从而实现 PUSH模式
185+
- 考虑实现消息过期,消息重试,消息定时投递等策略
186+
- 考虑批量操作,包括读写,可以打包和压缩
187+
- 考虑消息清理策略,包括定时清理,按容量清理、LRU等
188+
- 考虑消息持久化,存入数据库,或WAL日志文件,或BookKeeper
189+
- 考虑将spring mvc替换成netty下的tcp传输协议,rsocket/websocket
190+
191+
5. v5.0-优化完善:对接各种技术(各条之间没有关系,可以任意选择实现)
192+
- 考虑封装 JMS 1.1 接口规范
193+
- 考虑实现 STOMP 消息规范
194+
- 考虑实现消息事务机制与事务管理器
195+
- 对接Spring
196+
- 对接Camel或Spring Integration
197+
- 优化内存和磁盘的使用

0 commit comments

Comments
 (0)