提交 c26a57aa 编写于 作者: 沉默王二's avatar 沉默王二 💬

优质面经/八股文

上级 12ad5763
......@@ -400,30 +400,27 @@
> - **学习了那么多 Java 知识,耗费了无数的脑细胞,熬掉了无数根秀发,为的是什么?当然是谋取一份心仪的 offer 了**。那八股文、面试题、城市选择、优质面经又怎能少得了呢?
> - 千淘万漉虽辛苦,吹尽狂沙始到金。
## 精选面试题
## 精选面&八股文
- [Java:34道精选高频面试题](docs/baguwen/java-basic-34.md)
- [Java:13道HashMap精选面试题](docs/collection/hashmap-interview.md)
- [Redis:12道精选高频面试题)](docs/mianjing/redis12question.md)
- [Nginx:40道精选面试题](docs/nginx/40-interview.md)
## 背诵版八股文
- [Java 基础八股文(背诵版)必看:+1:](docs/baguwen/java-basic.md)
- [Java 并发编程八股文(背诵版)必看:+1:](docs/baguwen/java-thread.md)
- [Java 虚拟机八股文(背诵版)必看:+1:](docs/baguwen/jvm.md)
- [MySQL 八股文(背诵版)必看:+1:](docs/sidebar/herongwei/mysql.md)
- [34 道 Java 精选面试题👍](docs/interview/java-34.md)
- [13 道 Java HashMap 精选面试题👍](docs/interview/java-hashmap-13.md)
- [12 道 Redis 精选面试题👍](docs/interview/redis-12.md)
- [40 道 Nginx 精选面试题👍](docs/interview/nginx-40.md)
- [60 道 MySQL 精选面试题👍](docs/interview/mysql-60.md)
- [Java 基础背诵版八股文必看🍉](docs/baguwen/java-basic.md)
- [Java 并发编程背诵版八股文必看🍉](docs/baguwen/java-thread.md)
- [Java 虚拟机背诵版八股文必看🍉](docs/baguwen/jvm.md)
## 优质面经
- [硕士读者春招斩获深圳腾讯PCG和杭州阿里云 offer✌️](docs/mianjing/shanganaliyun.md)
- [本科读者小公司一年工作经验社招拿下阿里美团头条京东滴滴等 offer✌️](docs/nice-article/weixin/shezynmjfxhelmtttjddd.md)
- [非科班读者,用一年时间社招拿下阿里 Offer✌️](docs/nice-article/weixin/xuelybdzheloffer.md)
- [二本读者社招两年半10家公司28轮面试面经✌️](docs/nice-article/weixin/huanxgzl.md)
- [双非一本秋招收获腾讯ieg、百度、字节等6家大厂offer✌️](docs/nice-article/weixin/quzjlsspdx.md)
- [双非学弟收割阿里、字节、B站校招 offer,附大学四年硬核经验总结✌️](docs/nice-article/weixin/zheisnylzldhzd.md)
- [本科读者小公司一年工作经验社招拿下阿里美团头条京东滴滴等 offer✌️](docs/mianjing/shezynmjfxhelmtttjddd.md)
- [非科班读者,用一年时间社招拿下阿里 Offer✌️](docs/mianjing/xuelybdzheloffer.md)
- [二本读者社招两年半10家公司28轮面试面经✌️](docs/mianjing/huanxgzl.md)
- [双非一本秋招收获腾讯ieg、百度、字节等6家大厂offer✌️](docs/mianjing/quzjlsspdx.md)
- [双非学弟收割阿里、字节、B站校招 offer,附大学四年硬核经验总结✌️](docs/mianjing/zheisnylzldhzd.md)
- [深漂 6 年了,回西安的一波面经总结✌️](docs/mianjing/chengxyspnhxagzl.md)
## 面试准备
......@@ -482,6 +479,8 @@
- [如何在繁重的工作中持续成长?](docs/xuexijianyi/ruhzfzdgzzcxcz.md)
- [如何获得高并发的经验?](docs/xuexijianyi/gaobingfa-jingyan-hsmcomputer.md)
- [怎么跟 HR 谈薪资?](docs/xuexijianyi/hr-xinzi.md)
- [程序员 35 岁危机,如何破局?](docs/xuexijianyi/35-weiji.md)
- [大厂的优惠券系统是如何设计的?](docs/xuexijianyi/youhuiquan.md)
# 知识库搭建
......
......@@ -692,24 +692,17 @@ export const sidebarConfig = sidebar({
collapsable: true,
children: [
{
text: "面试题集合",
text: "面试题&八股文",
collapsable: true,
prefix:"/interview"
children: [
"baguwen/java-basic-34",
"collection/hashmap-interview",
"mianjing/redis12question",
"nginx/40-interview"
],
},
{
text: "背诵版八股文",
collapsable: true,
children: [
"baguwen/java-basic",
"baguwen/java-thread",
"baguwen/jvm",
"sidebar/herongwei/mysql",
"java-34",
"java-hashmap-13",
"redis-12",
"mysql-60",
"java-basic-baguwen",
"java-thread-baguwen",
"java-jvm-baguwen",
],
},
{
......
......@@ -414,28 +414,25 @@ head:
### 精选面试题
- [Java:34道精选高频面试题](baguwen/java-basic-34.md)
- [Java:13道HashMap精选面试题](collection/hashmap-interview.md)
- [Redis:12道精选高频面试题)](mianjing/redis12question.md)
- [Nginx:40道精选面试题](nginx/40-interview.md)
### 背诵版八股文
- [Java 基础八股文(背诵版)必看:+1:](baguwen/java-basic.md)
- [Java 并发编程八股文(背诵版)必看:+1:](baguwen/java-thread.md)
- [Java 虚拟机八股文(背诵版)必看:+1:](baguwen/jvm.md)
- [MySQL 八股文(背诵版)必看:+1:](sidebar/herongwei/mysql.md)
- [34 道 Java 精选面试题👍](interview/java-34.md)
- [13 道 Java HashMap 精选面试题👍](interview/java-hashmap-13.md)
- [12 道 Redis 精选面试题👍](interview/redis-12.md)
- [40 道 Nginx 精选面试题👍](interview/nginx-40.md)
- [60 道 MySQL 精选面试题👍](interview/mysql-60.md)
- [Java 基础背诵版八股文必看🍉](interview/java-basic-baguwen.md)
- [Java 并发编程背诵版八股文必看🍉](interview/java-thread-baguwen.md)
- [Java 虚拟机背诵版八股文必看🍉](interview/java-jvm-baguwen.md)
### 优质面经
- [硕士读者春招斩获深圳腾讯PCG和杭州阿里云 offer✌️](mianjing/shanganaliyun.md)
- [本科读者小公司一年工作经验社招拿下阿里美团头条京东滴滴等 offer✌️](nice-article/weixin/shezynmjfxhelmtttjddd.md)
- [非科班读者,用一年时间社招拿下阿里 Offer✌️](nice-article/weixin/xuelybdzheloffer.md)
- [二本读者社招两年半10家公司28轮面试面经✌️](nice-article/weixin/huanxgzl.md)
- [双非一本秋招收获腾讯ieg、百度、字节等6家大厂offer✌️](nice-article/weixin/quzjlsspdx.md)
- [双非学弟收割阿里、字节、B站校招 offer,附大学四年硬核经验总结✌️](nice-article/weixin/zheisnylzldhzd.md)
- [本科读者小公司一年工作经验社招拿下阿里美团头条京东滴滴等 offer✌️](mianjing/shezynmjfxhelmtttjddd.md)
- [非科班读者,用一年时间社招拿下阿里 Offer✌️](mianjing/xuelybdzheloffer.md)
- [二本读者社招两年半10家公司28轮面试面经✌️](mianjing/huanxgzl.md)
- [双非一本秋招收获腾讯ieg、百度、字节等6家大厂offer✌️](mianjing/quzjlsspdx.md)
- [双非学弟收割阿里、字节、B站校招 offer,附大学四年硬核经验总结✌️](mianjing/zheisnylzldhzd.md)
- [深漂 6 年了,回西安的一波面经总结✌️](mianjing/chengxyspnhxagzl.md)
### 面试准备
......@@ -472,6 +469,11 @@ head:
- [如何在繁重的工作中持续成长?](xuexijianyi/ruhzfzdgzzcxcz.md)
- [如何获得高并发的经验?](xuexijianyi/gaobingfa-jingyan-hsmcomputer.md)
- [怎么跟 HR 谈薪资?](xuexijianyi/hr-xinzi.md)
- [程序员 35 岁危机,如何破局?](xuexijianyi/35-weiji.md)
- [大厂的优惠券系统是如何设计的?](xuexijianyi/youhuiquan.md)
- [不到 20 人的 IT 公司该去吗?](xuexijianyi/20ren-it-quma.md)
- [本科生如何才能进入腾讯、阿里等一流的互联网公司?](xuexijianyi/benkesheng-ali-tengxun.md)
- [大厂的优惠券系统是如何设计的?](xuexijianyi/youhuiquan.md)
## 知识库搭建
......
---
title: 34 道 Java 精选面试题👍
shortTitle: 34 道 Java 精选面试题👍
category:
- 求职面试
tag:
- 面试题集合
- 面试题&八股文
description: Java程序员进阶之路,小白的零基础Java教程,34 道 Java 精选面试题👍
head:
- - meta
- name: keywords
content: Java,java,面试题,八股文
---
# Java:34道精选高频面试题必看:+1:
......@@ -571,4 +578,11 @@ Object obj = new Object();
>作者:moon聊技术,转载链接:[https://mp.weixin.qq.com/s/aTWtqPyMQ-6P_c8iuMVrkg](https://mp.weixin.qq.com/s/aTWtqPyMQ-6P_c8iuMVrkg)
---------
最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
关注二哥的原创公众号 **沉默王二**,回复**111** 即可免费领取。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
---
title: Java 基础背诵版八股文必看🍉
shortTitle: Java 基础背诵版八股文必看🍉
category:
- 求职面试
tag:
- 背诵版八股文
- 面试题&八股文
description: Java程序员进阶之路,小白的零基础Java教程,Java 基础背诵版八股文必看🍉
head:
- - meta
- name: keywords
content: Java,java,面试题,八股文
---
# Java 基础八股文(背诵版)必看:+1:
# Java 基础八股文(背诵版)必看🍉
### Java 语言具有哪些特点?
......@@ -400,4 +407,11 @@ equals 和 hashCode 这两个方法都是从 object 类中继承过来的,equa
转载链接:[https://mp.weixin.qq.com/s/PmeH38qWVxyIhBpsAsjG7w](https://mp.weixin.qq.com/s/PmeH38qWVxyIhBpsAsjG7w)
---------
最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
关注二哥的原创公众号 **沉默王二**,回复**111** 即可免费领取。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
---
title: 13 道 Java HashMap 精选面试题👍
shortTitle: 13 道 Java HashMap 精选面试题👍
category:
- 求职面试
tag:
- 面试题集合
- 面试题&八股文
description: Java程序员进阶之路,小白的零基础Java教程,13 道 Java HashMap 精选面试题👍
head:
- - meta
- name: keywords
content: Java,java,hashmap,面试题,八股文
---
# Java HashMap精选面试题
......@@ -195,7 +202,14 @@ HashMap 在容量超过负载因子所定义的容量之后,就会扩容。
>参考链接:https://zhuanlan.zhihu.com/p/362214327
>参考链接:[https://zhuanlan.zhihu.com/p/362214327](https://zhuanlan.zhihu.com/p/362214327)
---------
最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
关注二哥的原创公众号 **沉默王二**,回复**111** 即可免费领取。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
---
title: Java 虚拟机背诵版八股文必看🍉
shortTitle: Java 虚拟机背诵版八股文必看🍉
category:
- 求职面试
tag:
- 背诵版八股文
- 面试题&八股文
description: Java程序员进阶之路,小白的零基础Java教程,Java 虚拟机背诵版八股文必看🍉
head:
- - meta
- name: keywords
content: Java,java,jvm,面试题,八股文
---
# Java 虚拟机八股文(背诵版)必看:+1:
......@@ -204,4 +211,11 @@ MinorGC 前,虚拟机必须检查老年代最大可用连续空间是否大于
投稿作者:后端技术小牛说
转载链接:[https://mp.weixin.qq.com/s/PmeH38qWVxyIhBpsAsjG7w](https://mp.weixin.qq.com/s/PmeH38qWVxyIhBpsAsjG7w)
---------
最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
关注二哥的原创公众号 **沉默王二**,回复**111** 即可免费领取。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
---
title: Java 并发编程背诵版八股文必看🍉
shortTitle: Java 并发编程背诵版八股文必看🍉
category:
- 求职面试
tag:
- 背诵版八股文
- 面试题&八股文
description: Java程序员进阶之路,小白的零基础Java教程,Java 并发编程背诵版八股文必看🍉
head:
- - meta
- name: keywords
content: Java,java,thread,面试题,八股文
---
# Java 并发编程八股文(背诵版)必看:+1:
......@@ -302,4 +309,11 @@ AQS获取共享锁/释放共享锁原理
投稿作者:后端技术小牛说
转载链接:[https://mp.weixin.qq.com/s/PmeH38qWVxyIhBpsAsjG7w](https://mp.weixin.qq.com/s/PmeH38qWVxyIhBpsAsjG7w)
---------
最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
关注二哥的原创公众号 **沉默王二**,回复**111** 即可免费领取。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
---
title: 60 道 MySQL 精选面试题👍
shortTitle: 60 道 MySQL 精选面试题👍
category:
- 数据库
- 求职面试
tag:
- MySQL
- 面试题&八股文
description: Java程序员进阶之路,小白的零基础Java教程,60 道 MySQL 精选面试题👍
head:
- - meta
- name: keywords
content: MySQL,mysql,面试题,八股文
---
......@@ -619,5 +626,12 @@ MySQL 主备切换流程:
> 图文详解 60 道 MySQL 面试高频题,这次吊打面试官,我觉得稳了(手动 dog)。整理:沉默王二,戳[转载链接](https://mp.weixin.qq.com/s/c-sy7tM0BmrqMUQFW7C65g),里面有局详细的思维导图;作者:herongwei,戳[原文链接](https://mp.weixin.qq.com/s/-SqqKmhZcOlQxM-rHiIpKg)。
---------
最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
关注二哥的原创公众号 **沉默王二**,回复**111** 即可免费领取。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
---
title: 40 道 Nginx 精选面试题👍
shortTitle: 40 道 Nginx 精选面试题👍
category:
- 求职面试
tag:
- 面试题集合
- 面试题&八股文
description: Java程序员进阶之路,小白的零基础Java教程,40 道 Nginx 精选面试题👍
head:
- - meta
- name: keywords
content: Nginx,nginx,面试题,八股文
---
# Nginx:40道精选面试题必看:+1:
......@@ -786,6 +793,13 @@ Proxy_set_header THE-TIME $date_gmt;
----
>原文链接:blog.csdn.net/wuzhiwei549/article/details/122758937,整理:沉默王二
>原文链接:[blog.csdn.net/wuzhiwei549/article/details/122758937](blog.csdn.net/wuzhiwei549/article/details/122758937),整理:沉默王二
---------
最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
关注二哥的原创公众号 **沉默王二**,回复**111** 即可免费领取。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
---
title: 12 道 Redis 精选面试题👍
shortTitle: 12 道 Redis 精选面试题👍
category:
- 求职面试
tag:
- 面试题集合
- 面试题&八股文
description: Java程序员进阶之路,小白的零基础Java教程,12 道 Redis 精选面试题👍
head:
- - meta
- name: keywords
content: Redis,redis,面试题,八股文
---
# Redis:12道精选高频面试题
......@@ -169,6 +176,13 @@ C |10001 - 16383
----
文章来源于JAVA日知录 ,作者飘渺Jam
转载链接:https://mp.weixin.qq.com/s/GFUHslsSm96fJbhsCkFe_w
转载链接:[https://mp.weixin.qq.com/s/GFUHslsSm96fJbhsCkFe_w](https://mp.weixin.qq.com/s/GFUHslsSm96fJbhsCkFe_w)
---------
最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
关注二哥的原创公众号 **沉默王二**,回复**111** 即可免费领取。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
\ No newline at end of file
---
title: 程序员深漂 6 年,回西安工作了
shortTitle: 离开苏州了!
author: 七哥呀
title: 深漂 6 年了,回西安的一波面经总结✌️
shortTitle: 社招,深漂6 年回西安
category:
- 微信公众号
- 求职面试
tag:
- 优质面经
description: 深漂 6 年了,回西安的一波面经总结✌️
head:
- - meta
- name: keywords
content: 面试经验,面经,求职,offer,春招,秋招,社招,校招
---
>[二哥的编程星球](https://mp.weixin.qq.com/s/3RVsFZ17F0JzoHCLKbQgGw)已经有 **470 多名** 小伙伴加入了,如果你也需要一个良好的学习氛围,[戳链接](https://mp.weixin.qq.com/s/3RVsFZ17F0JzoHCLKbQgGw)加入我们吧!这是一个 Java 学习指南 + 编程实战的私密圈子,你可以向二哥提问、帮你制定学习计划、跟着二哥一起做项目、刷力扣,冲冲冲。
......@@ -249,15 +255,18 @@ hr 面,聊聊做了什么项目,遇到了最复杂的问题是啥?如何
没有什么使我停留——除了目的,纵然岸旁有玫瑰、有绿荫、有宁静的港湾,我是不系之舟。
**推荐阅读**
- [没必要为实习碰的头破血流](https://mp.weixin.qq.com/s/KxUMq2YmlIBMbAeRwUm8JA)
- [网站挣了 200 美刀后的感触](https://mp.weixin.qq.com/s/PxgZkuA_SnAgG7xfwlKLgw)
- [在 IDEA 里下五子棋不过分吧?](https://mp.weixin.qq.com/s/R13FkPipfEMKjqNaCL3UoA)
- [顺利入职了](https://mp.weixin.qq.com/s/oBLUSnHOmzoVpCP1sacNbA)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-rumrabbitmqzypjdg-53717e59-63c9-44bd-99d3-dd2c26fe68bb.png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-rumrabbitmqzypjdg-53717e59-63c9-44bd-99d3-dd2c26fe68bb.png)
>转载链接:[https://mp.weixin.qq.com/s/vIqfeVmWtDnvsHllC4M5Tg](https://mp.weixin.qq.com/s/vIqfeVmWtDnvsHllC4M5Tg),整理:沉默王二
---------
最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
关注二哥的原创公众号 **沉默王二**,回复**111** 即可免费领取。
>转载链接:[https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247524803&idx=1&sn=c5df3564f67d3c66d1c5357face5b001&chksm=cea12e08f9d6a71e6889f615918cef6232dea7045a7dee56530f6c86a3c979880dda266cbae2#rd](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247524803&idx=1&sn=c5df3564f67d3c66d1c5357face5b001&chksm=cea12e08f9d6a71e6889f615918cef6232dea7045a7dee56530f6c86a3c979880dda266cbae2#rd),出处:JavaGuide,整理:沉默王二
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
......@@ -6,15 +6,7 @@ author: CoderW
category:
- 求职面试
tag:
- 面试经验
- 面试准备
- 面经
- 求职
- offer
- 春招
- 秋招
- 社招
- 校招
- 优质面经
head:
- - meta
- name: description
......@@ -332,4 +324,13 @@ head:
>转载链接:[https://mp.weixin.qq.com/s/obuAuxa6gYiVdm-bjkoXRw](https://mp.weixin.qq.com/s/obuAuxa6gYiVdm-bjkoXRw),出处:CoderW,整理:沉默王二
---------
最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
关注二哥的原创公众号 **沉默王二**,回复**111** 即可免费领取。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
......@@ -4,7 +4,9 @@ shortTitle: 去字节了!SSP顶薪
description: 没有什么使我停留——除了目的,纵然岸旁有玫瑰、有绿荫、有宁静的港湾,我是不系之舟。
author: wasabi
category:
- 微信公众号
- 求职面试
tag:
- 优质面经
head:
- - meta
- name: description
......@@ -189,15 +191,12 @@ CSOC 开源项目结项通知
我认为这都是实力的体现。总之,你需要尽力地做一些 “显而易见” 的成就,让面试成功拥有事半功倍的效果。
* * *
*没有什么使我停留——除了目的,纵然岸旁有玫瑰、有绿荫、有宁静的港湾,我是不系之舟*
---------
最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
**推荐阅读**
关注二哥的原创公众号 **沉默王二**,回复**111** 即可免费领取。
* [崩溃,我把自己的网站搞挂了!](https://mp.weixin.qq.com/s?__biz=MzIxNzQwNjM3NA==&mid=2247506251&idx=1&sn=17cfecf45d761853c0cb82156cc6c6a2&scene=21#wechat_redirect)
* [真材实料才是底气!](https://mp.weixin.qq.com/s?__biz=MzIxNzQwNjM3NA==&mid=2247506170&idx=1&sn=d6f94e1e60583df6e819043700ae4d41&scene=21#wechat_redirect)
* [干掉iTerm!号称下一代终端神器,功能贼强大!](https://mp.weixin.qq.com/s?__biz=MzIxNzQwNjM3NA==&mid=2247506099&idx=1&sn=73bf97ee09cdbd8449fb564be1599509&scene=21#wechat_redirect)
* [LeetCode刷题笔记.pdf下载(Java版)](https://mp.weixin.qq.com/s?__biz=MzUxNzAzMTU4OQ==&mid=2247483848&idx=1&sn=5e338587650f4a5199fea1844a616343&scene=21#wechat_redirect)
>转载链接:[https://mp.weixin.qq.com/s?__biz=MzIxNzQwNjM3NA==&mid=2247506281&idx=1&sn=1ecdfab4e04ce0201e55a9c3be88d6a1&chksm=97f8d7a0a08f5eb6908c5b0a246300c781df051590b455b2a8616478e8d43e2eb71ab3da67ef&token=2006113039&lang=zh_CN#rd](https://mp.weixin.qq.com/s?__biz=MzIxNzQwNjM3NA==&mid=2247506281&idx=1&sn=1ecdfab4e04ce0201e55a9c3be88d6a1&chksm=97f8d7a0a08f5eb6908c5b0a246300c781df051590b455b2a8616478e8d43e2eb71ab3da67ef&token=2006113039&lang=zh_CN#rd),出处:沉默王二,整理:沉默王二
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
......@@ -4,19 +4,9 @@ shortTitle: 硕士读者春招上岸阿里云
category:
- 求职面试
tag:
- 面试经验
- 面经
- 求职
- offer
- 春招
- 秋招
- 社招
- 校招
- 优质面经
description: 春招斩获深圳腾讯 PCG 和杭州阿里云
head:
- - meta
- name: description
content: 春招斩获深圳腾讯 PCG 和杭州阿里云
- - meta
- name: keywords
content: 面试经验,面经,求职,offer,春招,秋招,社招,校招
......@@ -144,4 +134,12 @@ head:
>转载链接:[https://mp.weixin.qq.com/s/EB_NCC2fNyYHuz04k1H4Nw](https://mp.weixin.qq.com/s/EB_NCC2fNyYHuz04k1H4Nw),出处:JavaGuide,整理:沉默王二
---------
最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
关注二哥的原创公众号 **沉默王二**,回复**111** 即可免费领取。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
......@@ -6,14 +6,7 @@ author: 日常加油站
category:
- 求职面试
tag:
- 面试经验
- 面经
- 求职
- offer
- 春招
- 秋招
- 社招
- 校招
- 优质面经
head:
- - meta
- name: description
......@@ -335,4 +328,12 @@ head:
>转载链接:[https://mp.weixin.qq.com/s/h2tV6v5Rh6jHdO9x0p63-g](https://mp.weixin.qq.com/s/h2tV6v5Rh6jHdO9x0p63-g),出处:月伴飞鱼,整理:沉默王二
---------
最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
关注二哥的原创公众号 **沉默王二**,回复**111** 即可免费领取。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
\ No newline at end of file
......@@ -6,14 +6,7 @@ author: 茶杯
category:
- 求职面试
tag:
- 面试经验
- 面经
- 求职
- offer
- 春招
- 秋招
- 社招
- 校招
- 优质面经
head:
- - meta
- name: description
......@@ -276,4 +269,12 @@ g、分库分表:减轻 DB 压力
>转载链接:[https://mp.weixin.qq.com/s/vnMZY9Gsy3o1FwMi4f1GlA](https://mp.weixin.qq.com/s/vnMZY9Gsy3o1FwMi4f1GlA),出处:大厂面试指南,整理:沉默王二
---------
最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
关注二哥的原创公众号 **沉默王二**,回复**111** 即可免费领取。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
......@@ -4,11 +4,9 @@ shortTitle: 双非学弟收割大厂offer附大学经验总结
description: 双非学弟收割阿里、字节、B站校招 offer,附大学四年经验总结,硬核!
author: 兴趣使然的草帽路飞
category:
- 微信公众号
head:
- - meta
- name: description
content: 双非学长收割大厂offer,大学经验总结
- 求职面试
tag:
- 优质面经
---
大家好,我是二哥。今天分享一位双非进大厂同学的成长经历以及经验总结(他大学读的河科大,就在我们洛阳,离二哥住的地方就两站路的距离)。
......@@ -367,15 +365,11 @@ Last Question:
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-zheisnylzldhzd-2335e716-3853-457b-a3a7-fc8da353cdfa.png)
---
---------
_没有什么使我停留——除了目的,纵然岸旁有玫瑰、有绿荫、有宁静的港湾,我是不系之舟_
最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
**推荐阅读**
关注二哥的原创公众号 **沉默王二**,回复**111** 即可免费领取。
- [顺利入职了](https://mp.weixin.qq.com/s/oBLUSnHOmzoVpCP1sacNbA)
- [外包被歧视](https://mp.weixin.qq.com/s/n2mvD3sZ_pt9qVKbSCaiDg)
- [给大家鼓鼓劲!](https://mp.weixin.qq.com/s/QNlqleAj8Osq3gRW_D05Ew)
- [计划国庆前跳槽](https://mp.weixin.qq.com/s/1_9FVEhEErMhjCRNP9dqZw)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-rumrabbitmqzypjdg-53717e59-63c9-44bd-99d3-dd2c26fe68bb.png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
---
title: 超越 Nginx!号称下一代 Web 服务器,用起来够优雅!
shortTitle: 超越 Nginx!号称下一代 Web 服务器,用起来够优雅!
title: Caddy:超越 Nginx!号称下一代 Web 服务器,用起来够优雅!
shortTitle: Caddy:号称下一代 Web 服务器
description: Github标星38K+,Web服务器后起之秀!
author: 梦想de星空
category:
......@@ -17,7 +17,7 @@ head:
Caddy是一款功能强大,扩展性高的Web服务器,目前在Github上已有`38K+Star`。Caddy采用Go语言编写,可用于静态资源托管和反向代理。
![](https://mmbiz.qpic.cn/mmbiz_png/CKvMdchsUwliaXhlIY1ibvFfDzk0oTqaWyic9pYv5Rnk0XtbCCFCYH13siazfcQ0kWu730nOiab2RF7TvUZsuiaOC3Tw/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chaoynginxhcxydwebfwqyqlgyy-9934a57f-8350-4ea0-b3c9-d42e5d032c8f.jpg)
Caddy具有如下主要特性:
......@@ -35,12 +35,14 @@ Caddy具有如下主要特性:
* 使用如下命令通过DNF工具安装Caddy,安装成功后Caddy会被注册成系统服务;
```
dnf install 'dnf-command(copr)' dnf copr enable @caddy/caddy dnf install caddy
dnf install 'dnf-command(copr)'
dnf copr enable @caddy/caddy
dnf install caddy
```
* 使用`systemctl status caddy`查看Caddy的状态,可以发现Caddy已被注册为系统服务,但是还没开启。
![](https://mmbiz.qpic.cn/mmbiz_png/CKvMdchsUwliaXhlIY1ibvFfDzk0oTqaWyZ9DjgwxIf8WR8czpVgiakibIxelIEgDZahkTQGSBmAHkOgBeic6dHN2xw/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chaoynginxhcxydwebfwqyqlgyy-37c16043-2774-4571-8e96-940c09d664a1.jpg)
## 使用
......@@ -52,45 +54,63 @@ dnf install 'dnf-command(copr)' dnf copr enable @caddy/caddy dnf install 
* 直接使用`caddy`命令将输出Caddy的常用命令,基本看介绍就知道如何使用了,标出来的是常用命令;
![](https://mmbiz.qpic.cn/mmbiz_png/CKvMdchsUwliaXhlIY1ibvFfDzk0oTqaWyJX5LicAxNDTianKTrMEjEAgVpibTjDAiapBYsbngSWDF9AxOFyGlLrScEA/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chaoynginxhcxydwebfwqyqlgyy-814f1724-07d8-4b0e-947c-d2be4623ff00.jpg)
* 使用`caddy start`命令可以让Caddy服务在后台运行;
![](https://mmbiz.qpic.cn/mmbiz_png/CKvMdchsUwliaXhlIY1ibvFfDzk0oTqaWyqB6JIia6ciaSU6qkJ4fuJHn2PTpwLn8VQmpoWx47ZPYOnjib2LIb0RT8g/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chaoynginxhcxydwebfwqyqlgyy-91091246-afc8-4baa-ac94-9c71239fc7d7.jpg)
* Caddy默认使用JSON格式的配置文件,但由于JOSN格式配置书写比较麻烦,又提供了`Caddyfile`这种更加简洁的配置形式,使用如下命令能自动把`Caddyfile`转化为JSON配置;
```
caddy adapter
caddy adapter
```
* 我们可以先创建一个名称为`Caddyfile`的文件,文件内容如下,然后使用`caddy adapter`将它转换为JSON配置,再使用`caddy reload`使配置生效,该配置将监听`2015`端口,并返回`Hello, world!`
```
:2015 respond "Hello, world!"
:2015
respond "Hello, world!"
```
* 然后我们使用curl命令访问`localhost:2015`,将返回指定的信息;
![](https://mmbiz.qpic.cn/mmbiz_png/CKvMdchsUwliaXhlIY1ibvFfDzk0oTqaWyE1Lop7oCO9XA41rsV6rIx965KibCJVvxZvlcHmyBLugzNVwhMCZiclEA/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chaoynginxhcxydwebfwqyqlgyy-067cef19-b4fa-465d-a78e-b0aeda1fdfe8.jpg)
* 当然我们还可以使用Caddy提供的`Admin API`来查看配置信息,使用如下命令即可;
```
curl localhost:2019/config/
curl localhost:2019/config/
```
* 当前JSON配置如下,如果你直接使用JSON配置的话需要书写如下配置,使用`Caddyfile`确实方便很多!
```
{  "apps": {   "http": {    "servers": {     "srv0": {      "listen": [":2015"],      "routes": [{       "handle": [{        "body": "Hello, world!",        "handler": "static_response"       }]      }]     }    }   }  } }
{
 "apps": {
  "http": {
   "servers": {
    "srv0": {
     "listen": [":2015"],
     "routes": [{
      "handle": [{
       "body": "Hello, world!",
       "handler": "static_response"
      }]
     }]
    }
   }
  }
 }
}
```
### `Caddyfile`基本语法
* 下面案例将使用`Caddyfile`来进行配置,我们有必要了解下它的语法,`Caddyfile`的具体语法规则如下。
![](https://mmbiz.qpic.cn/mmbiz_png/CKvMdchsUwliaXhlIY1ibvFfDzk0oTqaWyNlfRVs45X1gmSoXRTfn92JAgITJGd9fnibmcDvVtSiaIjc9zCZbJd7iaA/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chaoynginxhcxydwebfwqyqlgyy-7164a091-ca8e-494b-9036-578d86bb5ebd.jpg)
* 介绍下上图中的关键字,有助于理解。
......@@ -115,30 +135,39 @@ Directive|指令|指令赋予了Caddy强大的功能|
* 首先我们修改下本机的host文件:
```
192.168.3.106 docs.macrozheng.com 192.168.3.106 mall.macrozheng.com
192.168.3.106 docs.macrozheng.com
192.168.3.106 mall.macrozheng.com
```
* 然后将我们的文档项目和mall前端项目上传到Caddy的html目录中去,并进行解压操作:
![](https://mmbiz.qpic.cn/mmbiz_png/CKvMdchsUwliaXhlIY1ibvFfDzk0oTqaWykpHD5r6oUasglvK4BgicubLewfpZyEMthIfvv0LCrCaFbcIxKr1u8Mw/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chaoynginxhcxydwebfwqyqlgyy-c3daf1e4-465c-4438-90f0-3ff43ea5f894.jpg)
* 修改`Caddyfile`文件,使用如下配置,修改完成后使用`caddy reload`命令刷新配置;
```
http://docs.macrozheng.com {         root * /mydata/caddy/html/docs         file_server browse } http://mall.macrozheng.com {         root * /mydata/caddy/html/mall         file_server browse }
http://docs.macrozheng.com {
        root * /mydata/caddy/html/docs
        file_server browse
}
http://mall.macrozheng.com {
        root * /mydata/caddy/html/mall
        file_server browse
}
```
* 如果你的`Caddyfile`文件格式不太合格的话,会出现如下警告,直接使用`caddy fmt --overwrite`格式化并重写配置即可解决;
![](https://mmbiz.qpic.cn/mmbiz_png/CKvMdchsUwliaXhlIY1ibvFfDzk0oTqaWyzz5efViac36b9ic6icuPunQoZqnrLqvGicwWrW1r7p9vrFFSB9wRTtboTg/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chaoynginxhcxydwebfwqyqlgyy-c605a767-d9cf-4962-9e58-26b1acde3d8b.jpg)
* 通过`docs.macrozheng.com`即可访问部署好的文档项目了:
![](https://mmbiz.qpic.cn/mmbiz_png/CKvMdchsUwliaXhlIY1ibvFfDzk0oTqaWyGNcrBssiaTMiaC9kI1JichCnqr2bUS6mXHT9icxvr7Bkh77sAMIDxZXzTQ/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chaoynginxhcxydwebfwqyqlgyy-13db54d4-c25b-4a9f-a303-93552dfa4751.jpg)
* 通过`mall.macrozheng.com`即可访问到部署好的前端项目了。
![](https://mmbiz.qpic.cn/mmbiz_png/CKvMdchsUwliaXhlIY1ibvFfDzk0oTqaWyeot4SMTibs5UxhuQBx4oyz0O9jbnbTNOoOKypsZD9vepWSsF0CwqYQA/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chaoynginxhcxydwebfwqyqlgyy-0af0e997-4135-4dbe-9255-4c11fda173c7.jpg)
#### 动态代理
......@@ -147,18 +176,20 @@ http://docs.macrozheng.com {         root * /mydata/caddy/html/docs
* 首先我们修改下本机的host文件,添加如下规则:
```
192.168.3.106 api.macrozheng.com
192.168.3.106 api.macrozheng.com
```
* 修改`Caddyfile`文件,使用如下配置,修改完成后使用`caddy reload`命令刷新配置;
```
http://api.macrozheng.com {         reverse_proxy http://admin-api.macrozheng.com }
http://api.macrozheng.com {
        reverse_proxy http://admin-api.macrozheng.com
}
```
* 之后通过`api.macrozheng.com/swagger-ui.html`即可访问到`mall-admin`的API文档页面了。
![](https://mmbiz.qpic.cn/mmbiz_png/CKvMdchsUwliaXhlIY1ibvFfDzk0oTqaWyjezYsLibVetwblI1bL541QIxgGFBIBSmggFZrKj4OBXRFUuQabhrXqg/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chaoynginxhcxydwebfwqyqlgyy-64a2a842-ce0b-49e3-a901-69583dbba655.jpg)
### 文件压缩
......@@ -167,20 +198,26 @@ http://api.macrozheng.com {         reverse_proxy http://admin-api.mac
* 我们需要修改`Caddyfile`文件,使用`encode`指令开启Gzip压缩,修改完成后使用`caddy reload`命令刷新配置;
```
http://mall.macrozheng.com {         root * /mydata/caddy/html/mall         encode {             gzip         }         file_server browse }
http://mall.macrozheng.com {
        root * /mydata/caddy/html/mall
        encode {
            gzip
        }
        file_server browse
}
```
* 有个比较大的JS文件压缩前是`1.7M`
![](https://mmbiz.qpic.cn/mmbiz_png/CKvMdchsUwliaXhlIY1ibvFfDzk0oTqaWy5Et1W6kialSkXGVor1mDx4I35uibiaCV2jI3yp0mbUDvnL6dPIqHd68aA/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chaoynginxhcxydwebfwqyqlgyy-ed4d3a63-0bdb-4330-927d-2fd496ecc21b.jpg)
* 压缩后为`544K`,访问速度也有很大提示;
![](https://mmbiz.qpic.cn/mmbiz_png/CKvMdchsUwliaXhlIY1ibvFfDzk0oTqaWyPrX5AKdbdetLJddlI0oSgib9MKe4xA1yoswfcEnQd27TW1ZtKr7b0tQ/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chaoynginxhcxydwebfwqyqlgyy-452cb1c0-4298-4834-a5c2-a15db28d1a62.jpg)
* 另外我们可以看下响应信息,如果有`Content-Encoding: gzip`这个响应头表明Gzip压缩已经启用了。
![](https://mmbiz.qpic.cn/mmbiz_png/CKvMdchsUwliaXhlIY1ibvFfDzk0oTqaWyoA9E03ABUgHCOz0CI3sc5YnB9m3iaXOHwCmKQGVWH5icbwRwBMNTvN3Q/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chaoynginxhcxydwebfwqyqlgyy-df92216c-66c4-4d8c-8139-bcf6f2ce43ca.jpg)
### 地址重写
......@@ -189,7 +226,9 @@ http://mall.macrozheng.com {         root * /mydata/caddy/html/mall
* 我们需要修改`Caddyfile`文件,使用`redir`指令重写地址,修改完成后使用`caddy reload`命令刷新配置;
```
http://docs.macrozheng.com {         redir http://www.macrozheng.com }
http://docs.macrozheng.com {
        redir http://www.macrozheng.com
}
```
* 此时访问旧域名`docs.macrozheng.com`会直接跳转到`www.macrozheng.com`去。
......@@ -201,13 +240,31 @@ http://docs.macrozheng.com {         redir http://www.macrozheng.com }
* 比如说我们需要按以下路径来访问各个前端项目;
```
www.macrozheng.com #访问文档项目 www.macrozheng.com/admin #访问后台项目 www.macrozheng.com/app #访问移动端项目
www.macrozheng.com #访问文档项目
www.macrozheng.com/admin #访问后台项目
www.macrozheng.com/app #访问移动端项目
```
* 我们需要修改`Caddyfile`文件,使用`route`指令定义路由,修改完成后使用`caddy reload`命令刷新配置。
```
http://www.macrozheng.com {         route /admin/* {                 uri strip_prefix /admin                 file_server {                         root /mydata/caddy/html/admin                 }         }         route /app/* {                 uri strip_prefix /app                 file_server {                         root /mydata/caddy/html/app                 }         }         file_server * {                 root /mydata/caddy/html/www         } }
http://www.macrozheng.com {
        route /admin/* {
                uri strip_prefix /admin
                file_server {
                        root /mydata/caddy/html/admin
                }
        }
        route /app/* {
                uri strip_prefix /app
                file_server {
                        root /mydata/caddy/html/app
                }
        }
        file_server * {
                root /mydata/caddy/html/www
        }
}
```
### HTTPS
......@@ -218,19 +275,23 @@ http://www.macrozheng.com {         route /admin/* {         
* 之后使用如下命令验证DNS解析记录是否正确,注意配置的服务器的`80``443`端口需要在外网能正常访问;
```
curl "https://cloudflare-dns.com/dns-query?name=docs.macrozheng.com&type=A" \   -H "accept: application/dns-json"
curl "https://cloudflare-dns.com/dns-query?name=docs.macrozheng.com&type=A" \
  -H "accept: application/dns-json"
```
* 修改`Caddyfile`配置文件,进行如下配置;
```
docs.macrozheng.com {         root * /mydata/caddy/html/docs         file_server browse }
docs.macrozheng.com {
        root * /mydata/caddy/html/docs
        file_server browse
}
```
* 然后使用`caddy run`命令启动Caddy服务器即可,是不是非常方便!
```
caddy run
caddy run
```
### Docker支持
......@@ -240,30 +301,36 @@ caddy run
* 首先使用如下命令下载Caddy的Docker镜像;
```
docker pull caddy
docker pull caddy
```
* 然后在`/mydata/caddy/`目录下创建`Caddyfile`配置文件,文件内容如下;
```
http://192.168.3.105:80 respond "Hello, world!"
http://192.168.3.105:80
respond "Hello, world!"
```
* 之后使用如下命令启动caddy服务,这里将宿主机上的`Caddyfile`配置文件、Caddy的数据目录和网站目录挂载到了容器中;
```
docker run -p 80:80 -p 443:443 --name caddy \     -v /mydata/caddy/Caddyfile:/etc/caddy/Caddyfile \     -v /mydata/caddy/data:/data \     -v /mydata/caddy/html:/usr/share/caddy \     -d caddy
docker run -p 80:80 -p 443:443 --name caddy \
    -v /mydata/caddy/Caddyfile:/etc/caddy/Caddyfile \
    -v /mydata/caddy/data:/data \
    -v /mydata/caddy/html:/usr/share/caddy \
    -d caddy
```
* 之后使用`docker exec`进入caddy容器内部执行命令;
```
docker exec -it caddy /bin/sh
docker exec -it caddy /bin/sh
```
* 输入Caddy命令即可操作,之后的操作就和我们直接在CentOS上安装一样了。
![](https://mmbiz.qpic.cn/mmbiz_png/CKvMdchsUwliaXhlIY1ibvFfDzk0oTqaWyXGYibV5qAibu6EiauLWxnYDibKibBaInlSTmtrM10wuj3zRHcOkEibUJ7bcg/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chaoynginxhcxydwebfwqyqlgyy-f589fa89-5940-43f2-a798-5b1523be9441.jpg)
## 总结
......@@ -280,7 +347,7 @@ docker exec -it caddy /bin/sh
**扫描下方二维码即可加我微信啦,`2022,抱团取暖,一起牛逼。`**
![](https://mmbiz.qpic.cn/mmbiz_jpg/CKvMdchsUwliaXhlIY1ibvFfDzk0oTqaWyWovicuqACWv6zibOMxSe2GIYlK1zWrZeoI8BxaosSt3LAeJDZmPjWLtg/640?wx_fmt=jpeg)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chaoynginxhcxydwebfwqyqlgyy-756f64b8-2db0-4bba-a813-a5f8f9f4ef79.jpg)
## 推荐阅读
......@@ -293,8 +360,8 @@ docker exec -it caddy /bin/sh
* [40K+Star!Mall电商实战项目开源回忆录!](https://mp.weixin.qq.com/s?__biz=MzU1Nzg4NjgyMw==&mid=2247486684&idx=1&sn=807fd808adac8019eb2095ba088efe54&scene=21#wechat_redirect)
* [mall-swarm 微服务电商项目发布重大更新,打造Spring Cloud最佳实践!](https://mp.weixin.qq.com/s?__biz=MzU1Nzg4NjgyMw==&mid=2247486362&idx=1&sn=fb6d71d328e8eee34976a86135dc6a7d&scene=21#wechat_redirect)
![](https://mmbiz.qpic.cn/mmbiz_gif/CKvMdchsUwlkU1ysoMgG69dVYbCQcI6Byneb8ibzZWPfUCr3T8CuBicCSGyFE6SpAtxpxtDCp6VlZ4F1hEL1BNyg/640?wx_fmt=gif)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chaoynginxhcxydwebfwqyqlgyy-92de163f-23a3-4194-b87b-83bb7fe9d203.jpg)
>转载链接:[https://mp.weixin.qq.com/s?__biz=MzU1Nzg4NjgyMw==&mid=2247499016&idx=1&sn=b4f12202e884dd02588cc701d0946ad3&chksm=fc2c4100cb5bc8167dcde2b0fb052e534ef335f2a8e6afd4034a5cfb8292d05423af0f35dcd0#rd](https://mp.weixin.qq.com/s?__biz=MzU1Nzg4NjgyMw==&mid=2247499016&idx=1&sn=b4f12202e884dd02588cc701d0946ad3&chksm=fc2c4100cb5bc8167dcde2b0fb052e534ef335f2a8e6afd4034a5cfb8292d05423af0f35dcd0#rd),出处:macrozheng,整理:沉默王二
--- title: 大文件上传时如何做到 秒传? shortTitle: 大文件上传时如何做到 秒传? author: 不才陈某 category: - 微信公众号 --- 大家好,我是二哥呀~ 文件上传是一个老生常谈的话题了,在文件相对比较小的情况下,可以直接把文件转化为字节流上传到服务器,但在文件比较大的情况下,用这种方式进行上传,可不是一个好的办法,毕竟很少有用户能忍受,尤其是当文件上传到一半中断后,继续上传却只能重头开始上传,让用户的体验尤其不爽。 那有没有比较好的上传体验呢,答案有的,就是下边要介绍的几种上传方式。 ## 秒传 ### 1、什么是秒传 通俗的说,你把要上传的东西上传,服务器会先做 MD5 校验,如果服务器上有同样的东西,它就直接给你个新地址,其实你下载的都是服务器上的同一个文件,想要不秒传,其实只要让 MD5 改变,就是对文件本身做一下修改(改名字不行),例如一个文本文件,你多加几个字,MD5 就变了,就不会秒传了. ### 2、本文实现的秒传核心逻辑 a、利用 redis 的 set 方法存放文件上传状态,其中 key 为文件上传的 md5,value 为是否上传完成的标志位; b、当标志位为 true 表示上传已经完成,此时如果有相同文件上传,则进入秒传逻辑。如果标志位为 false,则说明还没上传完成,此时需要再调用 set 方法,保存块号文件记录的路径,其中 key 为上传文件的 md5 + 一个固定前缀,value 为块号文件的记录路径 ## 分片上传 ### 1、什么是分片上传 分片上传,就是将所要上传的文件,按照一定的大小,将整个文件分隔成多个数据块(我们称之为 Part)来进行上传,上传完之后再由服务端对所有上传的文件进行汇总整合成原始的文件。 ### 2、分片上传的场景 1.大文件上传 2.网络环境环境不好,存在需要重传风险的场景 ## 断点续传 ### 1、什么是断点续传 断点续传是在下载或上传时,将下载或上传任务(一个文件或一个压缩包)人为的划分为几个部分,每一个部分采用一个线程进行上传或下载,如果碰到网络故障,可以从已经上传或下载的部分开始继续上传或者下载未完成的部分,而没有必要从头开始上传或者下载。 PS:本文的断点续传主要是针对断点上传场景。 ### 2、应用场景 断点续传可以看成是分片上传的一个衍生,因此可以使用分片上传的场景,都可以使用断点续传。 ### 3、实现断点续传的核心逻辑 在分片上传的过程中,如果因为系统崩溃或者网络中断等异常因素导致上传中断,这时候客户端需要记录上传的进度。在之后支持再次上传时,可以继续从上次上传中断的地方进行继续上传。 为了避免客户端在上传之后的进度数据被删除而导致重新开始从头上传的问题,服务端也可以提供相应的接口便于客户端对已经上传的分片数据进行查询,从而使客户端知道已经上传的分片数据,从而从下一个分片数据开始继续上传。 ### 4、实现流程步骤 a、方案一,常规步骤 - 将需要上传的文件按照一定的分割规则,分割成相同大小的数据块; - 初始化一个分片上传任务,返回本次分片上传唯一标识; - 按照一定的策略(串行或并行)发送各个分片数据块; - 发送完成后,服务端根据判断数据上传是否完整,如果完整,则进行数据块合成得到原始文件。 b、方案二、本文实现的步骤 - 前端(客户端)需要根据固定大小对文件进行分片,请求后端(服务端)时要带上分片序号和大小 - 服务端创建 conf 文件用来记录分块位置,conf 文件长度为总分片数,每上传一个分块即向 conf 文件中写入一个 127,那么没上传的位置就是默认的 0,已上传的就是 Byte.MAX_VALUE 127(这步是实现断点续传和秒传的核心步骤) - 服务器按照请求数据中给的分片序号和每片分块大小(分片大小是固定且一样的)算出开始位置,与读取到的文件片段数据,写入文件。 #### 5、分片上传/断点上传代码实现 a、前端采用百度提供的 webuploader 插件,进行分片。因本文主要介绍服务端代码实现,webuploader 如何进行分片,具体实现可以查看如下链接: [http://fex.baidu.com/webuploader/getting-started.html](http://fex.baidu.com/webuploader/getting-started.html) b、后端用两种方式实现文件写入,一种是用 RandomAccessFile,如果对 RandomAccessFile 不熟悉的朋友,可以查看如下链接: [https://blog.csdn.net/dimudan2015/article/details/81910690](https://blog.csdn.net/dimudan2015/article/details/81910690) 另一种是使用 MappedByteBuffer,对 MappedByteBuffer 不熟悉的朋友,可以查看如下链接进行了解: [https://www.jianshu.com/p/f90866dcbffc](https://www.jianshu.com/p/f90866dcbffc) ## 后端进行写入操作的核心代码 ### 1、RandomAccessFile 实现方式 ``` @UploadMode(mode = UploadModeEnum.RANDOM_ACCESS)   @Slf4j   public class RandomAccessUploadStrategy extends SliceUploadTemplate {        @Autowired     private FilePathUtil filePathUtil;        @Value("${upload.chunkSize}")     private long defaultChunkSize;        @Override     public boolean upload(FileUploadRequestDTO param) {       RandomAccessFile accessTmpFile = null;       try {         String uploadDirPath = filePathUtil.getPath(param);         File tmpFile = super.createTmpFile(param);         accessTmpFile = new RandomAccessFile(tmpFile, "rw");         //这个必须与前端设定的值一致         long chunkSize = Objects.isNull(param.getChunkSize()) ? defaultChunkSize * 1024 * 1024             : param.getChunkSize();         long offset = chunkSize * param.getChunk();         //定位到该分片的偏移量         accessTmpFile.seek(offset);         //写入该分片数据         accessTmpFile.write(param.getFile().getBytes());         boolean isOk = super.checkAndSetUploadProgress(param, uploadDirPath);         return isOk;       } catch (IOException e) {         log.error(e.getMessage(), e);       } finally {         FileUtil.close(accessTmpFile);       }      return false;     }      }   ``` ### 2、MappedByteBuffer 实现方式 ``` @UploadMode(mode = UploadModeEnum.MAPPED_BYTEBUFFER)   @Slf4j   public class MappedByteBufferUploadStrategy extends SliceUploadTemplate {        @Autowired     private FilePathUtil filePathUtil;        @Value("${upload.chunkSize}")     private long defaultChunkSize;        @Override     public boolean upload(FileUploadRequestDTO param) {          RandomAccessFile tempRaf = null;       FileChannel fileChannel = null;       MappedByteBuffer mappedByteBuffer = null;       try {         String uploadDirPath = filePathUtil.getPath(param);         File tmpFile = super.createTmpFile(param);         tempRaf = new RandomAccessFile(tmpFile, "rw");         fileChannel = tempRaf.getChannel();            long chunkSize = Objects.isNull(param.getChunkSize()) ? defaultChunkSize * 1024 * 1024             : param.getChunkSize();         //写入该分片数据         long offset = chunkSize * param.getChunk();         byte[] fileData = param.getFile().getBytes();         mappedByteBuffer = fileChannel   .map(FileChannel.MapMode.READ_WRITE, offset, fileData.length);         mappedByteBuffer.put(fileData);         boolean isOk = super.checkAndSetUploadProgress(param, uploadDirPath);         return isOk;          } catch (IOException e) {         log.error(e.getMessage(), e);       } finally {            FileUtil.freedMappedByteBuffer(mappedByteBuffer);         FileUtil.close(fileChannel);         FileUtil.close(tempRaf);          }          return false;     }      }   ``` ### 3、文件操作核心模板类代码 ``` @Slf4j   public abstract class SliceUploadTemplate implements SliceUploadStrategy {        public abstract boolean upload(FileUploadRequestDTO param);        protected File createTmpFile(FileUploadRequestDTO param) {          FilePathUtil filePathUtil = SpringContextHolder.getBean(FilePathUtil.class);       param.setPath(FileUtil.withoutHeadAndTailDiagonal(param.getPath()));       String fileName = param.getFile().getOriginalFilename();       String uploadDirPath = filePathUtil.getPath(param);       String tempFileName = fileName + "_tmp";       File tmpDir = new File(uploadDirPath);       File tmpFile = new File(uploadDirPath, tempFileName);       if (!tmpDir.exists()) {         tmpDir.mkdirs();       }       return tmpFile;     }        @Override     public FileUploadDTO sliceUpload(FileUploadRequestDTO param) {          boolean isOk = this.upload(param);       if (isOk) {         File tmpFile = this.createTmpFile(param);         FileUploadDTO fileUploadDTO = this.saveAndFileUploadDTO(param.getFile().getOriginalFilename(), tmpFile);         return fileUploadDTO;       }       String md5 = FileMD5Util.getFileMD5(param.getFile());          Map<Integer, String> map = new HashMap<>();       map.put(param.getChunk(), md5);       return FileUploadDTO.builder().chunkMd5Info(map).build();     }        /**      * 检查并修改文件上传进度      */     public boolean checkAndSetUploadProgress(FileUploadRequestDTO param, String uploadDirPath) {          String fileName = param.getFile().getOriginalFilename();       File confFile = new File(uploadDirPath, fileName + ".conf");       byte isComplete = 0;       RandomAccessFile accessConfFile = null;       try {         accessConfFile = new RandomAccessFile(confFile, "rw");         //把该分段标记为 true 表示完成         System.out.println("set part " + param.getChunk() + " complete");         //创建conf文件文件长度为总分片数,每上传一个分块即向conf文件中写入一个127,那么没上传的位置就是默认0,已上传的就是Byte.MAX_VALUE 127         accessConfFile.setLength(param.getChunks());         accessConfFile.seek(param.getChunk());         accessConfFile.write(Byte.MAX_VALUE);            //completeList 检查是否全部完成,如果数组里是否全部都是127(全部分片都成功上传)         byte[] completeList = FileUtils.readFileToByteArray(confFile);         isComplete = Byte.MAX_VALUE;         for (int i = 0; i < completeList.length && isComplete == Byte.MAX_VALUE; i++) {           //与运算, 如果有部分没有完成则 isComplete 不是 Byte.MAX_VALUE           isComplete = (byte) (isComplete & completeList[i]);           System.out.println("check part " + i + " complete?:" + completeList[i]);         }          } catch (IOException e) {         log.error(e.getMessage(), e);       } finally {         FileUtil.close(accessConfFile);       }    boolean isOk = setUploadProgress2Redis(param, uploadDirPath, fileName, confFile, isComplete);       return isOk;     }        /**      * 把上传进度信息存进redis      */     private boolean setUploadProgress2Redis(FileUploadRequestDTO param, String uploadDirPath,         String fileName, File confFile, byte isComplete) {          RedisUtil redisUtil = SpringContextHolder.getBean(RedisUtil.class);       if (isComplete == Byte.MAX_VALUE) {         redisUtil.hset(FileConstant.FILE_UPLOAD_STATUS, param.getMd5(), "true");         redisUtil.del(FileConstant.FILE_MD5_KEY + param.getMd5());         confFile.delete();         return true;       } else {         if (!redisUtil.hHasKey(FileConstant.FILE_UPLOAD_STATUS, param.getMd5())) {           redisUtil.hset(FileConstant.FILE_UPLOAD_STATUS, param.getMd5(), "false");           redisUtil.set(FileConstant.FILE_MD5_KEY + param.getMd5(),               uploadDirPath + FileConstant.FILE_SEPARATORCHAR + fileName + ".conf");         }            return false;       }     }   /**      * 保存文件操作      */     public FileUploadDTO saveAndFileUploadDTO(String fileName, File tmpFile) {          FileUploadDTO fileUploadDTO = null;          try {            fileUploadDTO = renameFile(tmpFile, fileName);         if (fileUploadDTO.isUploadComplete()) {           System.out               .println("upload complete !!" + fileUploadDTO.isUploadComplete() + " name=" + fileName);           //TODO 保存文件信息到数据库            }          } catch (Exception e) {         log.error(e.getMessage(), e);       } finally {          }       return fileUploadDTO;     }   /**      * 文件重命名      *      * @param toBeRenamed 将要修改名字的文件      * @param toFileNewName 新的名字      */     private FileUploadDTO renameFile(File toBeRenamed, String toFileNewName) {       //检查要重命名的文件是否存在,是否是文件       FileUploadDTO fileUploadDTO = new FileUploadDTO();       if (!toBeRenamed.exists() || toBeRenamed.isDirectory()) {         log.info("File does not exist: {}", toBeRenamed.getName());         fileUploadDTO.setUploadComplete(false);         return fileUploadDTO;       }       String ext = FileUtil.getExtension(toFileNewName);       String p = toBeRenamed.getParent();       String filePath = p + FileConstant.FILE_SEPARATORCHAR + toFileNewName;       File newFile = new File(filePath);       //修改文件名       boolean uploadFlag = toBeRenamed.renameTo(newFile);          fileUploadDTO.setMtime(DateUtil.getCurrentTimeStamp());       fileUploadDTO.setUploadComplete(uploadFlag);       fileUploadDTO.setPath(filePath);       fileUploadDTO.setSize(newFile.length());       fileUploadDTO.setFileExt(ext);       fileUploadDTO.setFileId(toFileNewName);          return fileUploadDTO;     }   }   ``` ## 总结 在实现分片上传的过程,需要前端和后端配合,比如前后端上传块号的文件大小,前后端必须得要一致,否则上传就会有问题。其次文件相关操作正常都是要搭建一个文件服务器的,比如使用 fastdfs、hdfs 等。 本示例代码在电脑配置为 4 核内存 8G 情况下,上传 24G 大小的文件,上传时间需要 30 多分钟,主要时间耗费在前端的 md5 值计算,后端写入的速度还是比较快。 如果项目组觉得自建文件服务器太花费时间,且项目的需求仅仅只是上传下载,那么推荐使用阿里的 oss 服务器,其介绍可以查看官网: [https://help.aliyun.com/product/31815.html](https://help.aliyun.com/product/31815.html) 阿里的 oss 它本质是一个对象存储服务器,而非文件服务器,因此如果有涉及到大量删除或者修改文件的需求,oss 可能就不是一个好的选择。 文末提供一个 oss 表单上传的链接 demo,通过 oss 表单上传,可以直接从前端把文件上传到 oss 服务器,把上传的压力都推给 oss 服务器: [https://www.cnblogs.com/ossteam/p/4942227.html](https://www.cnblogs.com/ossteam/p/4942227.html)
\ No newline at end of file
......@@ -5,10 +5,6 @@ description: 去年倒腾了一个半月,写过一篇 DDD 的文章,当时
author: 楼仔
category:
- 微信公众号
head:
- - meta
- name: description
content: 去年倒腾了一个半月,写过一篇 DDD 的文章,当时没有推广,完全自嗨,为了不让这篇好文被埋没,现重新整理,突出重点,可读性更强!
---
> [二哥编程知识星球](https://mp.weixin.qq.com/s/vZwDdRc21ot7SSjDo4CXJQ) (戳链接加入)正式上线了,来和 **270 多名** 小伙伴一起打怪升级吧!这是一个 Java 学习指南 + 编程实战的私密圈子,你可以向二哥提问、帮你制定学习计划、跟着二哥一起做实战项目,冲冲冲。<br><br>
......@@ -16,7 +12,7 @@ head:
不 BB,直接上思维导图!
![](https://mmbiz.qpic.cn/mmbiz_png/sXFqMxQoVLESpJibWtYnlHsuuI2wOYE4gQysHznWicFBVfUNmFXeJB8sjYBRVuNjsN4qnicNQH1u2jZXVOaV5JFmw/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-ganlygyddddywdnzw-0edf009a-064b-48d3-8626-8f6e90eacc8d.jpg)
## 1\. 走进 DDD
......@@ -32,13 +28,13 @@ head:
- 增加可维护性和可读性,延长软件生命周期;
- 中台化的基石。
![](https://mmbiz.qpic.cn/mmbiz_jpg/sXFqMxQoVLESpJibWtYnlHsuuI2wOYE4gcibPaJcRMCM40R7SLW2cCxVs09pFQShIv8QkRkUXx28OWYRN3pF1icjg/640?wx_fmt=jpeg)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-ganlygyddddywdnzw-8ab1b0ae-e3f7-4f55-a504-6fff76c03fe9.jpg)
### 1.2 DDD 作用
说到 DDD,绕不开 MVC,在 MVC 三层架构中,我们进行功能开发的之前,拿到需求,解读需求。往往最先做的一步就是先设计表结构,在逐层设计上层 dao,service,controller。对于产品或者用户的需求都做了一层自我理解的转化。
![](https://mmbiz.qpic.cn/mmbiz_png/sXFqMxQoVLESpJibWtYnlHsuuI2wOYE4gxfcvFgsx9IKicEGmiaaBic8OVWSdAemib1EhdqvyvqK63Z5QMmVKz6C0aw/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-ganlygyddddywdnzw-da88d3d6-034e-436f-b1b1-f9059a54aaf3.jpg)
用户需求在被提出之后经过这么多层的转化后,特别是研发需求在数据库结构这一层转化后,将业务以主观臆断行为进行了转化。一旦业务边界划分模糊,考虑不全,大量的逻辑补充堆积到了代码层实现,变得越来越难维护。
......@@ -63,7 +59,7 @@ head:
在领域驱动设计(DDD)中采用的是松散分层架构,层间关系不那么严格。每层都可能使用它下面所有层的服务,而不仅仅是下一层的服务。每层都可能是半透明的,这意味着有些服务只对上一层可见,而有些服务对上面的所有层都可见。
![](https://mmbiz.qpic.cn/mmbiz_png/sXFqMxQoVLESpJibWtYnlHsuuI2wOYE4gH4zTYicZIwYwpa46cW4g4apHxCD9IehxDhc6V37kDSnsia8SQHKIhZ4Q/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-ganlygyddddywdnzw-2d9f189e-292a-4f80-8bba-e7c24b18638e.jpg)
分层的作用,从上往下:
......@@ -85,7 +81,7 @@ head:
## 3\. DDD 基础
![](https://mmbiz.qpic.cn/mmbiz_png/sXFqMxQoVLESpJibWtYnlHsuuI2wOYE4g1H77UIiaarqZyRCdtyibq12D99axNhibaGtMlibiaAQFpmxbaZmHkh3zP4A/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-ganlygyddddywdnzw-aa8c5d49-429b-4357-aa36-a5bc7b83f770.jpg)
学习 DDD 前,有很多基础概念需要掌握,这幅图总结的很全,他把 DDD 划分不同的层级:
......@@ -133,7 +129,7 @@ head:
直接看下面这幅图(来源于极客时间欧创新的 DDD 实战课):
![](https://mmbiz.qpic.cn/mmbiz_png/sXFqMxQoVLESpJibWtYnlHsuuI2wOYE4gfKFMUOOUT7n1venjo2biaNaVNA2oicgEiaWfoecD35LKGqX692EzhO6LQ/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-ganlygyddddywdnzw-0fdd4b5c-83e1-43ef-a3f2-7238a4b72664.jpg)
##### 3.3.2 限界上下文
......@@ -165,9 +161,9 @@ DDD 中要求实体是唯一的且可持续变化的。意思是说在实体的
下面给个简单的图(同样是源于极客时间欧创新的 DDD 实战课):
![](https://mmbiz.qpic.cn/mmbiz_png/sXFqMxQoVLESpJibWtYnlHsuuI2wOYE4giabLQgdFH95qmHjMToKfelbQCicTicdOBHh5m2dh8thvw1e1Rm8x6SwUw/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-ganlygyddddywdnzw-1d5c9f50-88c3-4338-8382-fd9b02153397.jpg)
![](https://mmbiz.qpic.cn/mmbiz_png/sXFqMxQoVLESpJibWtYnlHsuuI2wOYE4gJbnlkngwfbp2D2OxicF9DI4zVFdzzr3YFvpJajPXA5urCibVqsjCJ0Xg/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-ganlygyddddywdnzw-da7315fd-e7dc-40ed-a2db-fd88d78aec17.jpg)
### 3.5 聚合和聚合根
......@@ -191,7 +187,7 @@ DDD 中要求实体是唯一的且可持续变化的。意思是说在实体的
上面讲的还是有些抽象,下面看一个图就能很好理解(同样是源于极客时间欧创新的 DDD 实战课):
![](https://mmbiz.qpic.cn/mmbiz_png/sXFqMxQoVLESpJibWtYnlHsuuI2wOYE4gUNqMr7v4mS1Ikv4m3UcmNUJMUgPFrP37pbw4mcuicUYRSbbOdM8Xabg/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-ganlygyddddywdnzw-752b9a44-0e80-4cd8-9021-a9459d9a1e3f.jpg)
简单概括一下:
......@@ -482,7 +478,7 @@ public interface UserRepository {
基础服务层不仅仅包括资源库,与第三方的调用,都需要放到该层,Demo 中没有该示例,我们可以看一个小米内部具体的实际项目,他把第三方的调用放到了 remote 目录中:
![](https://mmbiz.qpic.cn/mmbiz_png/sXFqMxQoVLESpJibWtYnlHsuuI2wOYE4gPYETyldgWBibEwayiaHvUpqlrlrMYEx1AKp66NKGAwrA6PWKib1LgCic2w/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-ganlygyddddywdnzw-b2c62061-fb0f-414d-8b93-c804e90b9668.jpg)
### 4.5 领域层
......@@ -531,7 +527,7 @@ public class AuthorizeDomainServiceImpl implements AuthorizeDomainService {
我们其实可以把领域服务再进一步抽象,可以抽象出领域能力,通过这些领域能力去构建应用层逻辑,比如账号相关的领域能力可以包括授权领域能力、身份认证领域能力等,这样每个领域能力相对独立,就不会全部揉到一个文件中,下面是实际项目的领域层截图:
![](https://mmbiz.qpic.cn/mmbiz_png/sXFqMxQoVLESpJibWtYnlHsuuI2wOYE4gmkUttpBicdc9jg9iaKqYWqL1VQG4mJ8BFEgxZXpqCOaHyofUwqOpENibg/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-ganlygyddddywdnzw-9a6e50c2-61a5-4a87-8fbd-5e0fc962ac67.jpg)
##### 4.5.3 领域事件
......@@ -704,4 +700,12 @@ _没有什么使我停留——除了目的,纵然岸旁有玫瑰、有绿荫
- [离开北京?](https://mp.weixin.qq.com/s/-LNhq_OBHDBZzAEMurqBJw)
- [编程喵实战项目可以在本地跑起来辣!](https://mp.weixin.qq.com/s/PZcWj0NbWRGdS0I9ACMqbg)
![](https://img-blog.csdnimg.cn/img_convert/29e81f023caee3bdfdb6698a3ad2178f.png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-ganlygyddddywdnzw-a487294e-13a8-402c-afc6-e63baffa671b.png)
----
最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
关注二哥的原创公众号 **沉默王二**,回复**111** 即可免费领取。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
......@@ -2,26 +2,23 @@
title: 不到 20 人的 IT 公司该去吗?
shortTitle: 不到 20 人的 IT 公司该去吗?
author: Shawn
tags:
- 学习建议
category:
- 微信公众号
- 学习建议
---
> **近期文章精选** :
>
> * [完结撒花!时隔 596 天,《JavaGuide 面试突击版》5.0 来啦!](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247529453&idx=1&sn=f1b3245f023aa2b9890071bb9a9c318c&scene=21#wechat_redirect)
> * [热乎的美团一面,1 小时 40 分钟,问的很全面!](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247529365&idx=1&sn=a933939d0d38779502c6f9c4d7094bba&scene=21#wechat_redirect)
> * [什么是 CDN ?CDN 工作原理是什么?](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247529365&idx=2&sn=cede039a89fa340584f7226b709e86ad&scene=21#wechat_redirect)
> * [为什么建议使用 BigDecimal 进行浮点数运算?](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247529249&idx=1&sn=b847fd68d576bd713250acd166617ad7&scene=21#wechat_redirect)
> * [上岸 2022 字节 Java 后端实习面经](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247528162&idx=1&sn=81bf1255c923cffae384a5a38e51da91&scene=21#wechat_redirect)
>[二哥的编程星球](https://mp.weixin.qq.com/s/e5Q4aJCX9xccTzBBGepx4g)已经有 **740 多名** 球友加入了,如果你也需要一个良好的学习氛围,[戳链接](https://mp.weixin.qq.com/s/e5Q4aJCX9xccTzBBGepx4g)加入我们吧!这是一个Java学习指南+编程实战+LeetCode 刷题的私密圈子,你可以向二哥提问、帮你制定学习计划、和球友一起打卡成长,冲冲冲。
原回答地址:https://sourl.cn/hy9TD
周末就不分享技术了。今天早上在知乎看到一个挺有意思的话题:不到 20 人的 IT 公司该去吗?。
周末就不分享技术了。今天早上在知乎看到一个挺有意思的话题:**不到 20 人的 IT 公司该去吗**
![](https://mmbiz.qpic.cn/mmbiz_png/iaIdQfEric9TwXFujfEZQx8kzKKQaW3F5iaeDPCibtAdBT4ItV8f1DMhqd7pkwTwOAq1ib7IrkOd8ubR7tNvdUmpNug/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-budrditgsgqm-092ccdf7-12ac-4ca0-81b0-0d7fc193ffdc.jpg)
回答区有一位老哥分享了自己在一个20 来人的小公司的奇葩工作经历,分享一下。
>原回答地址:https://sourl.cn/hy9TD
下面是正文。
刚到西安有幸加入了一个 20 来人的 it 公司。
......@@ -213,16 +210,29 @@ category:
不过,还是有少部分不错的小公司的,这个也不能一棒子打死。
**·········· END ··············**
----
没有什么使我停留——除了目的,纵然岸旁有玫瑰、有绿荫、有宁静的港湾,我是不系之舟。
- [再见,GitHub trending](https://mp.weixin.qq.com/s/E2ko0I0Lts2yoIF-HLBOgw)
- [钱付了订单还是未支付,怎么解决?](https://mp.weixin.qq.com/s/nzR9eKFgEbpPFIkMF40vYw)
- [涨薪40%,从国企跳到一家小公司!](https://mp.weixin.qq.com/s/NT4fVbI8hDdN7MQkG2RNdQ)
- [暑假在富士康打工50天,感受如何?](https://mp.weixin.qq.com/s/luKyE0O1eGBhUyBuoAONqA)
- [35 岁危机怎么破?](https://mp.weixin.qq.com/s/duEzl6qiM59cHVdFhWB2FA)
- [面试通过,背调凉了!](https://mp.weixin.qq.com/s/R8IonWhFfNk0H1vUgjEadg)
- [推荐一些小而美的互联网公司](https://mp.weixin.qq.com/s/iiGGsfvPzNIcWFdH0LStjw)
- [有哪些值得计算机专业加入的国企?](https://mp.weixin.qq.com/s/WO0MYpWI3m_18Yohe0SzMA)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-rumrabbitmqzypjdg-53717e59-63c9-44bd-99d3-dd2c26fe68bb.png)
**推荐阅读**
----
* [曾经真是网瘾少年](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247523651&idx=1&sn=f0f4cff906c8e5febb7097fa6716c1d3&scene=21#wechat_redirect)
* [害,毕业三年了!](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247521759&idx=1&sn=60965fc8c51f65f7cd271f59fd19e124&scene=21#wechat_redirect)
* [一个普通程序员的周末](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247505539&idx=1&sn=721dd80d064afbaf8ea71e6b211f304d&scene=21#wechat_redirect)
* [做公众号这一年的经历和一件“大事”](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247484746&idx=1&sn=a519a9e3d638bff5c65008f7de167e4b&chksm=cea24a81f9d5c397ca9ac5668ba6cb18b38065e0e282a34ebc077a2dea98de3f1eb285ea5f09&token=330978132&lang=zh_CN&scene=21#wechat_redirect)
* [简单聊聊我的 Java 后端开发求职之路](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247500276&idx=1&sn=09acfc2b4ba6c0c9c335c1ee296f7d6c&chksm=cea18e3ff9d6072933adf0e130412a952d37e43345f665953b6d07b234a3753f9a546677fce3&token=330978132&lang=zh_CN&scene=21#wechat_redirect)
最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
👉 如果本文对你有帮助的话,欢迎 **点赞&在看&分享** ,这对我继续分享&创作优质文章非常重要。非常感谢!
关注二哥的原创公众号 **沉默王二**,回复**111** 即可免费领取。
>参考链接:[https://mp.weixin.qq.com/s/Dhd7mWfYl-evUxdQSXXA1w](https://mp.weixin.qq.com/s/Dhd7mWfYl-evUxdQSXXA1w),出处:JavaGuide,整理:沉默王二
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
\ No newline at end of file
......@@ -2,27 +2,41 @@
title: 程序员 35 岁危机,如何破局 ?
shortTitle: 程序员 35 岁危机,如何破局 ?
description: 工作可以是事业、是热爱,也可以只是一份工作,给自己留出转身的空间很有必要!
author: 楼仔
tags:
- 学习建议
category:
- 微信公众号
- 学习建议
head:
- - meta
- name: keywords
content: 程序员,35岁,危机
---
![](https://mmbiz.qpic.cn/mmbiz_png/sXFqMxQoVLH88nXxMO4SS0I3DayH71Q9106u6STibSsKb3REbnicFGeFUricACWhDnticd23iaPKDYNcbyBW7fMCI6A/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chengxyswjrhpj-a1c73ba1-4f12-4bb9-a64b-14bb7cc86ec5.png)
大家好,我是楼仔!
作者:沉默王二<br>
Java 程序员进阶之路:https://tobebetterjavaer.com
这篇文章其实是我去年写的,当时看的同学不多,**经历大半年的历练,对这个话题的理解更深刻**,文章已重新整理,真心希望更多同学能看到这篇文章
大家好,我是二哥呀!今天周六,咱精神就不要绷那么紧了,来谈一个超级“轻松”的话题:35 岁中年危机
相信很多同学对这个话题感到焦虑,担心自己 35 岁之后会失业,因为前几年我也这样,不过目前要好很多,文末会讲。
写这篇文章前,为了让文章的内容保持客观,**我对 “35 岁大龄程序员” 这个话题调研了 2 周,然后才开始落笔**,文中很多观点都是摘录其它优秀的文章,然后再结合自己工作中的所感、所悟所得。
不得不说,任总的把寒气传递给每一个老百姓,杀伤力拉满,不少小伙伴都绷不住了,开始危机重重。[二哥的编程星球](https://mp.weixin.qq.com/s/e5Q4aJCX9xccTzBBGepx4g) VIP 群里,也有不少小伙伴唉声叹气,感觉情况糟糕至极。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chengxyswjrhpj-cc32ca43-8165-413b-9c8a-24cf0ebbe84b.png)
就连一个**不满 25 岁的球友,也开始担心起 35 岁程序员中年危机**了,问二哥该怎么办?
说句实在话,环境是没有以前好,但还没有到恐慌的地步啊,再说,25 岁就开始担心中年危机,着实有点早了呀!这期间还有 10 多年的美好岁月呀!
我们是该未雨绸缪,但不应该杞人忧天啊,这种“**危机病**”必须得治。下面这部分内容是二哥的“四贱客”,哦不,“四剑客”团队之一的楼仔写的,可以说是治好“35 岁”危机的良药!理解的非常深刻,道和术全都具备!
相信很多小伙伴对这个话题感到焦虑,担心自己 35 岁之后会失业,因为前几年我也这样,不过目前要好很多,文末会讲。
不 BB,上文章目录。
![](https://mmbiz.qpic.cn/mmbiz_png/sXFqMxQoVLH88nXxMO4SS0I3DayH71Q95HZRCTHxj5VRfxibw1uomwm9vvQqzfTgSce09jt4HtNN37kjhEscaaA/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chengxyswjrhpj-a5f7d6a6-756e-44d8-95c7-7a5593e56c7f.jpg)
## 1\. 为什么会危机
## 1\. 为什么会危机?
### 1.1 35 岁年龄特点
......@@ -83,7 +97,7 @@ head:
那如何才能延长职业生命线呢?答案是**持续学习!**
![](https://mmbiz.qpic.cn/mmbiz_png/sXFqMxQoVLH88nXxMO4SS0I3DayH71Q9TWgaicaibWBicDPPpRZVBkhzdeNsnzGRbibxmXjJdCkZgbibVj4rmP5jAJw/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chengxyswjrhpj-ff036054-7e53-4a61-bf10-95ac18dbff2f.jpg)
IT 行业的技术更新换代非常快,对个人综合能力要求非常高,如果你不持续学习,等到年龄危机到来时还想躺赢,下一批裁员的可能就是你了。
......@@ -100,7 +114,7 @@ IT 行业的技术更新换代非常快,对个人综合能力要求非常高
下面是更加详细的职业规划,尽量延长自己的生命线,甚至可以摆脱年龄的限制(能摆脱年龄限制,都是大神级别):
* 在某种开发技能上**建立个人品牌**,比如微服务、Hadoop、高并发、C++ 等,而且你的品牌要被业内认可,这样的开发者实际上是以 “技术专家” 的身份存在。
* 在某种开发技能上**建立个人品牌**,比如Java、微服务、Hadoop、高并发、C++ 等,而且你的品牌要被业内认可,这样的开发者实际上是以 “技术专家” 的身份存在。
* 在组织内**开发技能过硬、精通业务,成为复合型选手,占据难以替代的位置**。这样的开发者,可以称之为高级开发工程师或者资深开发者,这样的角色,在一个合适的平台上可以受到重视,可以跟着平台发展,不用在意年龄。退一步讲,即便所在的平台倒掉了,也会有很多公司愿意要。
* 成为**善于架构某类软件服务的架构师**。这是从高级开发工程师演进过来的更高级的角色,当你真正做过一些大型系统的架构工作,会有很多公司需要你,不必担心你的年龄,你工作自由了。
* **走向管理岗位,成为职业经理人**。很多公司都有项目经理、技术经理、研发经理等管理角色,你需要能够真正做好管理工作。
......@@ -154,7 +168,7 @@ IT 行业的技术更新换代非常快,对个人综合能力要求非常高
《软件架构师的 12 项修炼》这本书里给出了软件架构师的金字塔能力模型:
![](https://mmbiz.qpic.cn/mmbiz_png/sXFqMxQoVLH88nXxMO4SS0I3DayH71Q9D3YyNauNIXHX7RGwYibD4oBcyqmmumqHfEicX2xulvxTgnDRbf0kOvNg/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chengxyswjrhpj-c24a3550-d551-4f71-b209-f66d4675afc8.jpg)
这个模型,适用于绝大多数软件开发工程师,在这本书里,作者说这么一句话。
......@@ -179,7 +193,7 @@ IT 行业的技术更新换代非常快,对个人综合能力要求非常高
**身体是 1,其他都是 0,没有 1,再多的 0 都是空。**
![](https://mmbiz.qpic.cn/mmbiz_png/sXFqMxQoVLH88nXxMO4SS0I3DayH71Q9oGIhagVFkhC2TXDAtIQnrzWH61X429P2bpnzY8RfRq0GHgh0rBDrPQ/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chengxyswjrhpj-bc05d1ad-558b-420c-a033-0cf639e66953.jpg)
魔都一位技术人员,总以为自己年轻,身体硬扛得住,结果一次晕倒后,医院检查发现自己得了尿毒症,没有好的身体,你挣再多钱都没有意义,一旦你因为身体而离开人间,配偶、孩子、钱都是别人的了。
......@@ -189,7 +203,7 @@ IT 行业的技术更新换代非常快,对个人综合能力要求非常高
做副业的目的,就是增加自己的收入,同时也是倒逼你去学习更多的知识,让你的技术能力提升更快,也为你未来创业做准备,增加你抗风险的能力。
![](https://mmbiz.qpic.cn/mmbiz_png/sXFqMxQoVLH88nXxMO4SS0I3DayH71Q9mibjmibP2XFLM3sV9qNfSsjWH3tKTv5MovibCibA9iaLYZkSFtWyQ4rFbEA/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chengxyswjrhpj-ccd0adf8-31a0-4931-9cae-d53270fa5890.jpg)
除了以上好处,副业也会提升你的个人能力、扩大你的圈子。
......@@ -197,11 +211,11 @@ IT 行业的技术更新换代非常快,对个人综合能力要求非常高
越是成功的人,他的圈子就越广,资源也越多,人生的路自然就越走越宽。
最近几年关注的一些公众号的大佬们,就都在抱团取暖,各种互推,实现资源共享
最近一段时间认识二哥后,我就发现,生活工作又了新的不一样,我进入了另外一个资源共享的圈子,我们做开源,做的不亦乐乎
所以多向上拓展你的圈子,多走近结交那些正能量、有想法、志同道合的人。
![](https://mmbiz.qpic.cn/mmbiz_jpg/sXFqMxQoVLH88nXxMO4SS0I3DayH71Q9p5leddWc7iaP6qAy5Dic3FnVKQfkicTTB7XaASRcE9ZXh7uXL50KCl5Qw/640?wx_fmt=jpeg)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chengxyswjrhpj-a7825336-07e5-4414-8858-dec7c0a14b5b.jpg)
兴许下次换工作,是圈子里的人脉直接内推让你找到一份满意的工作,更有可能,圈子里的几个朋友因为某一个好点子直接走向创业之路。
......@@ -221,18 +235,62 @@ IT 行业的技术更新换代非常快,对个人综合能力要求非常高
最后送上大家一句话:工作可以是事业、是热爱,也可以只是一份工作,**给自己留出转身的空间很有必要**,如果把工作看作一份经历和沿途的风景,在乎过程中的经历、感受多过最后的结果,可能会让人生更加充满期待。
![](https://mmbiz.qpic.cn/mmbiz_jpg/sXFqMxQoVLH88nXxMO4SS0I3DayH71Q9JWeCa060meEEoRKT5TOFiaBXg7ergibfapwK8SJU86iaf5CiaibCIibGIAKw/640?wx_fmt=jpeg)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chengxyswjrhpj-13911d3c-6806-4eab-81dc-319fbc0d2a0d.jpg)
## ending
一个人可以走得很快,但一群人才能走得更远。欢迎加入[二哥的编程星球](https://mp.weixin.qq.com/s/e5Q4aJCX9xccTzBBGepx4g),目前已经有 **710 多名** 球友加入了。
最近一段时间,二哥也没闲着,和球友炳源一起,正在紧锣密鼓地更新 Java 版LeetCode 题解,我们并不刻意追求 beat 100%,但效率总是出乎意料的优秀。与此同时,我们也在力求每一个题解都能通俗易懂,深入到底层,给大家举一反三的能力。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chengxyswjrhpj-5788d535-ff4a-4af0-8ef5-0c56ffeedf0a.png)
就比如说为了讲清楚暴力算法和 KMP 算法的区别,我们可以说是煞费苦心。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chengxyswjrhpj-f0984121-b3cb-4476-961c-ae55f0eb7c5b.png)
除了星球提供的三份高质量专栏,《Java 面试指南》、《编程喵 🐱(Spring Boot+Vue 前后端分离)实战项目笔记》、《Java 版 LeetCode 刷题笔记》,这里也沉淀了非常多优质的内容,包括球友和二哥分享的精华贴,还有二哥精心回答过的球友提问。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chengxyswjrhpj-589510f2-4281-4ac3-b9ba-787d0d3105d3.png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-chengxyswjrhpj-826265f7-cead-4325-9d39-ec94951c0823.png)
如果你也需要一个良好的学习氛围,[戳链接加入我们的大家庭吧](https://mp.weixin.qq.com/s/e5Q4aJCX9xccTzBBGepx4g)!这是一个 Java 学习指南 + 编程实战 + LeetCode 刷题的私密圈子,你可以向二哥提问、帮你制定学习计划、跟着二哥一起做实战项目,和球友一起打卡学习,自律得飞起!
欢迎点击左下角**阅读原文**了解二哥的编程星球详情,这可能是你学习求职路上最有含金量的一次点击。
* * *
##### 硬核推荐:
没有什么使我停留——除了目的,纵然岸旁有玫瑰、有绿荫、有宁静的港湾,我是不系之舟。
- [面试通过,背调凉了!](https://mp.weixin.qq.com/s/R8IonWhFfNk0H1vUgjEadg)
- [推荐一些小而美的互联网公司](https://mp.weixin.qq.com/s/iiGGsfvPzNIcWFdH0LStjw)
- [有哪些值得计算机专业加入的国企?](https://mp.weixin.qq.com/s/WO0MYpWI3m_18Yohe0SzMA)
- [三十岁的我,自由了!](https://mp.weixin.qq.com/s/WjYQR90VHJ7OPDhA-55Iug)
- [今年这情况,真有点想读研了](https://mp.weixin.qq.com/s/ja_fEGFBBWM3TLhdT0aeMw)
- [如何防止订单重复支付?](https://mp.weixin.qq.com/s/lCdFvto1A7X4wHkJk4_iNA)
- [专升本上岸的秘诀](https://mp.weixin.qq.com/s/yH42DxmRBSjrr0SW9N3MFg)
- [愤怒,一个破培训班要价 28 万](https://mp.weixin.qq.com/s/miOagyv4x3HrqVaU38uh4w)
* [源码深度解析,Spring 如何解决循环依赖?](https://mp.weixin.qq.com/s?__biz=Mzg3OTU5NzQ1Mw==&mid=2247491100&idx=1&sn=c0662cbe9319970d0778f82e553ef693&chksm=cf035cfef874d5e817f5f8cda42a15a2e8fa5d0479f7a7c92c3f23e2b31e6246d7161a0b691e&scene=21#wechat_redirect)
* [总监又来了,人狠话不多,这篇 gRPC,小弟佩服!](https://mp.weixin.qq.com/s?__biz=Mzg3OTU5NzQ1Mw==&mid=2247490689&idx=1&sn=273eee9f2e182e6c176822d949a44f53&chksm=cf035e63f874d775cc4a0cfcffdadc79a45bde8f57c2a4a91f14ae4ee2a67588ee20026aab83&token=1068187151&lang=zh_CN&scene=21#wechat_redirect)
* [百度一面:谈谈 @Transactional 的原理和坑](https://mp.weixin.qq.com/s?__biz=Mzg3OTU5NzQ1Mw==&mid=2247490574&idx=1&sn=d07043a044b0f4b7971d270026fd90be&chksm=cf035eecf874d7fa312a6bfa92200b49695f81108546a3c447b842c21aaff60c51a6aa66e6d0&token=1068187151&lang=zh_CN&scene=21#wechat_redirect)
* [如何才能达到阿里 P7 水平 ?](https://mp.weixin.qq.com/s?__biz=Mzg3OTU5NzQ1Mw==&mid=2247489731&idx=1&sn=fa509f677c6daf4ac90ef9a27473eeb3&chksm=cf035a21f874d3373c1fa0964c1605681d239dee5d721289c0877f7d20beea24c38760d369f9&token=1383401310&lang=zh_CN&scene=21#wechat_redirect)
* [新来个技术总监,把 RabbitMQ 讲的那叫一个透彻,佩服!](https://mp.weixin.qq.com/s?__biz=Mzg3OTU5NzQ1Mw==&mid=2247489667&idx=1&sn=910f851309f822b9473d08e7f6d4ab6c&chksm=cf035a61f874d377dd08c9303655afe7a385e9dc2421fe61a377ac156d62a01bfb48bb12ec1b&token=331236693&lang=zh_CN&scene=21#wechat_redirect)
![](https://mmbiz.qpic.cn/mmbiz_png/sXFqMxQoVLH88nXxMO4SS0I3DayH71Q93ictEeuTTS9BOjicJKQAkvhmdmhaJMfcFgDYAOVt89DxUqFaIufNa3zQ/640?wx_fmt=png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/nice-article/weixin-rumrabbitmqzypjdg-53717e59-63c9-44bd-99d3-dd2c26fe68bb.png)
>参考链接:[https://mp.weixin.qq.com/s/jtwD0Iodg7-HsHEJh2ubZw](https://mp.weixin.qq.com/s/jtwD0Iodg7-HsHEJh2ubZw),出处:楼仔,整理:沉默王二
----
最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
关注二哥的原创公众号 **沉默王二**,回复**111** 即可免费领取。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
\ No newline at end of file
---
title: 本科生如何才能进入腾讯、阿里等一流的互联网公司?
shortTitle: 本科生如何才能进入腾讯、阿里等一流的互联网公司?
description: 研究生强答一波,阿里和腾讯都拿到了校招offer,除此之外也拿了百度头条网易滴滴亚马逊。我本科不是计算…
shortTitle: 本科生如何进入一流的互联网公司?
tags:
- 学习建议
author: 黄小斜
category:
- 学习建议
head:
- - meta
- name: description
content: 研究生强答一波,阿里和腾讯都拿到了校招offer,除此之外也拿了百度头条网易滴滴亚马逊。我本科不是计算…
- - meta
- name: keywords
content: 信息技术(IT),软件工程师,就业
......
--- title: 大文件上传时如何做到 秒传? shortTitle: 大文件上传时如何做到 秒传? description: 大文件上传时如何做到 秒传? tags: - 学习建议 category: - 学习建议 head: - - meta - name: keywords content: 大文件,秒传 --- 大家好,我是二哥呀~ 文件上传是一个老生常谈的话题了,在文件相对比较小的情况下,可以直接把文件转化为字节流上传到服务器,但在文件比较大的情况下,用这种方式进行上传,可不是一个好的办法,毕竟很少有用户能忍受,尤其是当文件上传到一半中断后,继续上传却只能重头开始上传,让用户的体验尤其不爽。 那有没有比较好的上传体验呢,答案有的,就是下边要介绍的几种上传方式。 ## 秒传 ### 1、什么是秒传 通俗的说,你把要上传的东西上传,服务器会先做 MD5 校验,如果服务器上有同样的东西,它就直接给你个新地址,其实你下载的都是服务器上的同一个文件,想要不秒传,其实只要让 MD5 改变,就是对文件本身做一下修改(改名字不行),例如一个文本文件,你多加几个字,MD5 就变了,就不会秒传了. ### 2、本文实现的秒传核心逻辑 a、利用 redis 的 set 方法存放文件上传状态,其中 key 为文件上传的 md5,value 为是否上传完成的标志位; b、当标志位为 true 表示上传已经完成,此时如果有相同文件上传,则进入秒传逻辑。如果标志位为 false,则说明还没上传完成,此时需要再调用 set 方法,保存块号文件记录的路径,其中 key 为上传文件的 md5 + 一个固定前缀,value 为块号文件的记录路径 ## 分片上传 ### 1、什么是分片上传 分片上传,就是将所要上传的文件,按照一定的大小,将整个文件分隔成多个数据块(我们称之为 Part)来进行上传,上传完之后再由服务端对所有上传的文件进行汇总整合成原始的文件。 ### 2、分片上传的场景 1.大文件上传 2.网络环境环境不好,存在需要重传风险的场景 ## 断点续传 ### 1、什么是断点续传 断点续传是在下载或上传时,将下载或上传任务(一个文件或一个压缩包)人为的划分为几个部分,每一个部分采用一个线程进行上传或下载,如果碰到网络故障,可以从已经上传或下载的部分开始继续上传或者下载未完成的部分,而没有必要从头开始上传或者下载。 PS:本文的断点续传主要是针对断点上传场景。 ### 2、应用场景 断点续传可以看成是分片上传的一个衍生,因此可以使用分片上传的场景,都可以使用断点续传。 ### 3、实现断点续传的核心逻辑 在分片上传的过程中,如果因为系统崩溃或者网络中断等异常因素导致上传中断,这时候客户端需要记录上传的进度。在之后支持再次上传时,可以继续从上次上传中断的地方进行继续上传。 为了避免客户端在上传之后的进度数据被删除而导致重新开始从头上传的问题,服务端也可以提供相应的接口便于客户端对已经上传的分片数据进行查询,从而使客户端知道已经上传的分片数据,从而从下一个分片数据开始继续上传。 ### 4、实现流程步骤 a、方案一,常规步骤 - 将需要上传的文件按照一定的分割规则,分割成相同大小的数据块; - 初始化一个分片上传任务,返回本次分片上传唯一标识; - 按照一定的策略(串行或并行)发送各个分片数据块; - 发送完成后,服务端根据判断数据上传是否完整,如果完整,则进行数据块合成得到原始文件。 b、方案二、本文实现的步骤 - 前端(客户端)需要根据固定大小对文件进行分片,请求后端(服务端)时要带上分片序号和大小 - 服务端创建 conf 文件用来记录分块位置,conf 文件长度为总分片数,每上传一个分块即向 conf 文件中写入一个 127,那么没上传的位置就是默认的 0,已上传的就是 Byte.MAX_VALUE 127(这步是实现断点续传和秒传的核心步骤) - 服务器按照请求数据中给的分片序号和每片分块大小(分片大小是固定且一样的)算出开始位置,与读取到的文件片段数据,写入文件。 #### 5、分片上传/断点上传代码实现 a、前端采用百度提供的 webuploader 插件,进行分片。因本文主要介绍服务端代码实现,webuploader 如何进行分片,具体实现可以查看如下链接: [http://fex.baidu.com/webuploader/getting-started.html](http://fex.baidu.com/webuploader/getting-started.html) b、后端用两种方式实现文件写入,一种是用 RandomAccessFile,如果对 RandomAccessFile 不熟悉的朋友,可以查看如下链接: [https://blog.csdn.net/dimudan2015/article/details/81910690](https://blog.csdn.net/dimudan2015/article/details/81910690) 另一种是使用 MappedByteBuffer,对 MappedByteBuffer 不熟悉的朋友,可以查看如下链接进行了解: [https://www.jianshu.com/p/f90866dcbffc](https://www.jianshu.com/p/f90866dcbffc) ## 后端进行写入操作的核心代码 ### 1、RandomAccessFile 实现方式 ``` @UploadMode(mode = UploadModeEnum.RANDOM_ACCESS)   @Slf4j   public class RandomAccessUploadStrategy extends SliceUploadTemplate {        @Autowired     private FilePathUtil filePathUtil;        @Value("${upload.chunkSize}")     private long defaultChunkSize;        @Override     public boolean upload(FileUploadRequestDTO param) {       RandomAccessFile accessTmpFile = null;       try {         String uploadDirPath = filePathUtil.getPath(param);         File tmpFile = super.createTmpFile(param);         accessTmpFile = new RandomAccessFile(tmpFile, "rw");         //这个必须与前端设定的值一致         long chunkSize = Objects.isNull(param.getChunkSize()) ? defaultChunkSize * 1024 * 1024             : param.getChunkSize();         long offset = chunkSize * param.getChunk();         //定位到该分片的偏移量         accessTmpFile.seek(offset);         //写入该分片数据         accessTmpFile.write(param.getFile().getBytes());         boolean isOk = super.checkAndSetUploadProgress(param, uploadDirPath);         return isOk;       } catch (IOException e) {         log.error(e.getMessage(), e);       } finally {         FileUtil.close(accessTmpFile);       }      return false;     }      }   ``` ### 2、MappedByteBuffer 实现方式 ``` @UploadMode(mode = UploadModeEnum.MAPPED_BYTEBUFFER)   @Slf4j   public class MappedByteBufferUploadStrategy extends SliceUploadTemplate {        @Autowired     private FilePathUtil filePathUtil;        @Value("${upload.chunkSize}")     private long defaultChunkSize;        @Override     public boolean upload(FileUploadRequestDTO param) {          RandomAccessFile tempRaf = null;       FileChannel fileChannel = null;       MappedByteBuffer mappedByteBuffer = null;       try {         String uploadDirPath = filePathUtil.getPath(param);         File tmpFile = super.createTmpFile(param);         tempRaf = new RandomAccessFile(tmpFile, "rw");         fileChannel = tempRaf.getChannel();            long chunkSize = Objects.isNull(param.getChunkSize()) ? defaultChunkSize * 1024 * 1024             : param.getChunkSize();         //写入该分片数据         long offset = chunkSize * param.getChunk();         byte[] fileData = param.getFile().getBytes();         mappedByteBuffer = fileChannel   .map(FileChannel.MapMode.READ_WRITE, offset, fileData.length);         mappedByteBuffer.put(fileData);         boolean isOk = super.checkAndSetUploadProgress(param, uploadDirPath);         return isOk;          } catch (IOException e) {         log.error(e.getMessage(), e);       } finally {            FileUtil.freedMappedByteBuffer(mappedByteBuffer);         FileUtil.close(fileChannel);         FileUtil.close(tempRaf);          }          return false;     }      }   ``` ### 3、文件操作核心模板类代码 ``` @Slf4j   public abstract class SliceUploadTemplate implements SliceUploadStrategy {        public abstract boolean upload(FileUploadRequestDTO param);        protected File createTmpFile(FileUploadRequestDTO param) {          FilePathUtil filePathUtil = SpringContextHolder.getBean(FilePathUtil.class);       param.setPath(FileUtil.withoutHeadAndTailDiagonal(param.getPath()));       String fileName = param.getFile().getOriginalFilename();       String uploadDirPath = filePathUtil.getPath(param);       String tempFileName = fileName + "_tmp";       File tmpDir = new File(uploadDirPath);       File tmpFile = new File(uploadDirPath, tempFileName);       if (!tmpDir.exists()) {         tmpDir.mkdirs();       }       return tmpFile;     }        @Override     public FileUploadDTO sliceUpload(FileUploadRequestDTO param) {          boolean isOk = this.upload(param);       if (isOk) {         File tmpFile = this.createTmpFile(param);         FileUploadDTO fileUploadDTO = this.saveAndFileUploadDTO(param.getFile().getOriginalFilename(), tmpFile);         return fileUploadDTO;       }       String md5 = FileMD5Util.getFileMD5(param.getFile());          Map<Integer, String> map = new HashMap<>();       map.put(param.getChunk(), md5);       return FileUploadDTO.builder().chunkMd5Info(map).build();     }        /**      * 检查并修改文件上传进度      */     public boolean checkAndSetUploadProgress(FileUploadRequestDTO param, String uploadDirPath) {          String fileName = param.getFile().getOriginalFilename();       File confFile = new File(uploadDirPath, fileName + ".conf");       byte isComplete = 0;       RandomAccessFile accessConfFile = null;       try {         accessConfFile = new RandomAccessFile(confFile, "rw");         //把该分段标记为 true 表示完成         System.out.println("set part " + param.getChunk() + " complete");         //创建conf文件文件长度为总分片数,每上传一个分块即向conf文件中写入一个127,那么没上传的位置就是默认0,已上传的就是Byte.MAX_VALUE 127         accessConfFile.setLength(param.getChunks());         accessConfFile.seek(param.getChunk());         accessConfFile.write(Byte.MAX_VALUE);            //completeList 检查是否全部完成,如果数组里是否全部都是127(全部分片都成功上传)         byte[] completeList = FileUtils.readFileToByteArray(confFile);         isComplete = Byte.MAX_VALUE;         for (int i = 0; i < completeList.length && isComplete == Byte.MAX_VALUE; i++) {           //与运算, 如果有部分没有完成则 isComplete 不是 Byte.MAX_VALUE           isComplete = (byte) (isComplete & completeList[i]);           System.out.println("check part " + i + " complete?:" + completeList[i]);         }          } catch (IOException e) {         log.error(e.getMessage(), e);       } finally {         FileUtil.close(accessConfFile);       }    boolean isOk = setUploadProgress2Redis(param, uploadDirPath, fileName, confFile, isComplete);       return isOk;     }        /**      * 把上传进度信息存进redis      */     private boolean setUploadProgress2Redis(FileUploadRequestDTO param, String uploadDirPath,         String fileName, File confFile, byte isComplete) {          RedisUtil redisUtil = SpringContextHolder.getBean(RedisUtil.class);       if (isComplete == Byte.MAX_VALUE) {         redisUtil.hset(FileConstant.FILE_UPLOAD_STATUS, param.getMd5(), "true");         redisUtil.del(FileConstant.FILE_MD5_KEY + param.getMd5());         confFile.delete();         return true;       } else {         if (!redisUtil.hHasKey(FileConstant.FILE_UPLOAD_STATUS, param.getMd5())) {           redisUtil.hset(FileConstant.FILE_UPLOAD_STATUS, param.getMd5(), "false");           redisUtil.set(FileConstant.FILE_MD5_KEY + param.getMd5(),               uploadDirPath + FileConstant.FILE_SEPARATORCHAR + fileName + ".conf");         }            return false;       }     }   /**      * 保存文件操作      */     public FileUploadDTO saveAndFileUploadDTO(String fileName, File tmpFile) {          FileUploadDTO fileUploadDTO = null;          try {            fileUploadDTO = renameFile(tmpFile, fileName);         if (fileUploadDTO.isUploadComplete()) {           System.out               .println("upload complete !!" + fileUploadDTO.isUploadComplete() + " name=" + fileName);           //TODO 保存文件信息到数据库            }          } catch (Exception e) {         log.error(e.getMessage(), e);       } finally {          }       return fileUploadDTO;     }   /**      * 文件重命名      *      * @param toBeRenamed 将要修改名字的文件      * @param toFileNewName 新的名字      */     private FileUploadDTO renameFile(File toBeRenamed, String toFileNewName) {       //检查要重命名的文件是否存在,是否是文件       FileUploadDTO fileUploadDTO = new FileUploadDTO();       if (!toBeRenamed.exists() || toBeRenamed.isDirectory()) {         log.info("File does not exist: {}", toBeRenamed.getName());         fileUploadDTO.setUploadComplete(false);         return fileUploadDTO;       }       String ext = FileUtil.getExtension(toFileNewName);       String p = toBeRenamed.getParent();       String filePath = p + FileConstant.FILE_SEPARATORCHAR + toFileNewName;       File newFile = new File(filePath);       //修改文件名       boolean uploadFlag = toBeRenamed.renameTo(newFile);          fileUploadDTO.setMtime(DateUtil.getCurrentTimeStamp());       fileUploadDTO.setUploadComplete(uploadFlag);       fileUploadDTO.setPath(filePath);       fileUploadDTO.setSize(newFile.length());       fileUploadDTO.setFileExt(ext);       fileUploadDTO.setFileId(toFileNewName);          return fileUploadDTO;     }   }   ``` ## 总结 在实现分片上传的过程,需要前端和后端配合,比如前后端上传块号的文件大小,前后端必须得要一致,否则上传就会有问题。其次文件相关操作正常都是要搭建一个文件服务器的,比如使用 fastdfs、hdfs 等。 本示例代码在电脑配置为 4 核内存 8G 情况下,上传 24G 大小的文件,上传时间需要 30 多分钟,主要时间耗费在前端的 md5 值计算,后端写入的速度还是比较快。 如果项目组觉得自建文件服务器太花费时间,且项目的需求仅仅只是上传下载,那么推荐使用阿里的 oss 服务器,其介绍可以查看官网: [https://help.aliyun.com/product/31815.html](https://help.aliyun.com/product/31815.html) 阿里的 oss 它本质是一个对象存储服务器,而非文件服务器,因此如果有涉及到大量删除或者修改文件的需求,oss 可能就不是一个好的选择。 文末提供一个 oss 表单上传的链接 demo,通过 oss 表单上传,可以直接从前端把文件上传到 oss 服务器,把上传的压力都推给 oss 服务器: [https://www.cnblogs.com/ossteam/p/4942227.html](https://www.cnblogs.com/ossteam/p/4942227.html) ---- 最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html) 关注二哥的原创公众号 **沉默王二**,回复**111** 即可免费领取。 ![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
\ No newline at end of file
---
title: 阿里二面:为什么要分库分表?
shortTitle: 阿里二面:为什么要分库分表?
shortTitle: 为什么要分库分表?
description: 在高并发系统当中,分库分表是必不可少的技术手段之一,同时也是BAT等大厂面试时,经常考的热门考题。
author: 苏三呀
tags:
- 学习建议
category:
- 微信公众号
head:
- - meta
- name: description
content: 在高并发系统当中,分库分表是必不可少的技术手段之一,同时也是BAT等大厂面试时,经常考的热门考题。
- 学习建议
---
## 前言
......@@ -310,3 +308,11 @@ head:
>转载链接:[https://mp.weixin.qq.com/s/klkD8xea0gQ96Mh1Q1MHLw](https://mp.weixin.qq.com/s/klkD8xea0gQ96Mh1Q1MHLw),出处:macrozheng,整理:沉默王二
----
最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
关注二哥的原创公众号 **沉默王二**,回复**111** 即可免费领取。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
---
title: 大厂的优惠券系统是如何设计的?
shortTitle: 大厂的优惠券系统是如何设计的?
author: JavaEdge
description: 大厂的优惠券系统是如何设计的?
tags:
- 学习建议
category:
- 微信公众号
- 学习建议
head:
- - meta
- name: keywords
content: 优惠券
---
......@@ -471,3 +477,11 @@ alter table t_notify_msg
>参考链接:[https://mp.weixin.qq.com/s/r9lgiOwV5cw8XmfCBUTcUA](https://mp.weixin.qq.com/s/r9lgiOwV5cw8XmfCBUTcUA),出处:JavaEdge,整理:沉默王二
----
最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
关注二哥的原创公众号 **沉默王二**,回复**111** 即可免费领取。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册