1
0
mirror of https://github.com/Snailclimb/JavaGuide synced 2025-08-01 16:28:03 +08:00

Compare commits

...

10 Commits

Author SHA1 Message Date
Guide
1ba08ab91f
Merge pull request #2504 from uncle-lv/fix-typo
docs(jwt-intro.md): 错别字校正
2024-10-16 07:21:00 +08:00
uncle-lv
0a0021c97c docs(load-balancing.md): 错别字校正 2024-10-15 22:25:01 +08:00
uncle-lv
dcf63ae84d docs(jwt-intro.md): 错别字校正 2024-10-14 21:50:20 +08:00
Guide
4b34db7018
Merge pull request #2494 from Samsara1994/patch-2
Update linkedhashmap-source-code.md
2024-10-13 08:20:57 +08:00
Guide
d6905064b7
Merge pull request #2502 from cjvox/main
增加内部类的知识点
2024-10-13 08:20:39 +08:00
Guide
f168d723ac Update redis-skiplist.md 2024-10-13 08:13:34 +08:00
vox
1dd05db8d2
Update syntactic-sugar.md
增加内部类的知识点
2024-10-12 22:03:01 +08:00
Guide
8cd0f88307
Merge pull request #2500 from cjvox/JavaGuideBranch
补充redis跳表部分,修改redis-skiplist.md
2024-10-12 20:08:59 +08:00
cjvox
8391c9b93e
Update redis-skiplist.md
补充redis跳表部分
2024-10-12 10:33:22 +08:00
Samsara1994
9145feec50
Update linkedhashmap-source-code.md
错别字更改
2024-09-25 14:56:25 +08:00
5 changed files with 87 additions and 3 deletions

View File

@ -599,6 +599,12 @@ Node{data=21, maxLevel=3}
Node{data=23, maxLevel=1} Node{data=23, maxLevel=1}
``` ```
**Redis 跳表的特点**
1. 采用**双向链表**,不同于上面的示例,存在一个回退指针。主要用于简化操作,例如删除某个元素时,还需要找到该元素的前驱节点,使用回退指针会非常方便。
2. `score` 值可以重复,如果 `score` 值一样,则按照 ele节点存储的值为 sds字典排序
3. Redis 跳跃表默认允许最大的层数是32被源码中 `ZSKIPLIST_MAXLEVEL` 定义。
## 和其余三种数据结构的比较 ## 和其余三种数据结构的比较
最后,我们再来回答一下文章开头的那道面试题: “Redis 的有序集合底层为什么要用跳表,而不用平衡树、红黑树或者 B+树?”。 最后,我们再来回答一下文章开头的那道面试题: “Redis 的有序集合底层为什么要用跳表,而不用平衡树、红黑树或者 B+树?”。

View File

@ -24,7 +24,7 @@ head:
负载均衡可以简单分为 **服务端负载均衡****客户端负载均衡** 这两种。 负载均衡可以简单分为 **服务端负载均衡****客户端负载均衡** 这两种。
服务端负载均衡涉及到的知识点更多,工作中遇到的也比较多,因,我会花更多时间来介绍。 服务端负载均衡涉及到的知识点更多,工作中遇到的也比较多,因,我会花更多时间来介绍。
### 服务端负载均衡 ### 服务端负载均衡

View File

@ -379,6 +379,84 @@ public class OutterClass
} }
``` ```
**为什么内部类可以使用外部类的private属性**
我们在InnerClass中增加一个方法打印外部类的userName属性
```java
//省略其他属性
public class OutterClass {
private String userName;
......
class InnerClass{
......
public void printOut(){
System.out.println("Username from OutterClass:"+userName);
}
}
}
// 此时使用javap -p命令对OutterClass反编译结果
public classOutterClass {
private String userName;
......
static String access$000(OutterClass);
}
// 此时InnerClass的反编译结果
class OutterClass$InnerClass {
final OutterClass this$0;
......
public void printOut();
}
```
实际上在编译完成之后inner实例内部会有指向outer实例的引用`this$0`,但是简单的`outer.name`是无法访问private属性的。从反编译的结果可以看到outer中会有一个桥方法`static String access$000(OutterClass)`恰好返回String类型即userName属性。正是通过这个方法实现内部类访问外部类私有属性。所以反编译后的`printOut()`方法大致如下:
```java
public void printOut() {
System.out.println("Username from OutterClass:" + OutterClass.access$000(this.this$0));
}
```
补充:
1. 匿名内部类、局部内部类、静态内部类也是通过桥方法来获取private属性。
2. 静态内部类没有`this$0`的引用
3. 匿名内部类、局部内部类通过复制使用局部变量,该变量初始化之后就不能被修改。以下是一个案例:
```java
public class OutterClass {
private String userName;
public void test(){
//这里i初始化为1后就不能再被修改
int i=1;
class Inner{
public void printName(){
System.out.println(userName);
System.out.println(i);
}
}
}
}
```
反编译后:
```java
//javap命令反编译Inner的结果
//i被复制进内部类且为final
class OutterClass$1Inner {
final int val$i;
final OutterClass this$0;
OutterClass$1Inner();
public void printName();
}
```
### 条件编译 ### 条件编译
—般情况下,程序中的每一行代码都要参加编译。但有时候出于对程序代码优化的考虑,希望只对其中一部分内容进行编译,此时就需要在程序中加上条件,让编译器只对满足条件的代码进行编译,将不满足条件的代码舍弃,这就是条件编译。 —般情况下,程序中的每一行代码都要参加编译。但有时候出于对程序代码优化的考虑,希望只对其中一部分内容进行编译,此时就需要在程序中加上条件,让编译器只对满足条件的代码进行编译,将不满足条件的代码舍弃,这就是条件编译。

View File

@ -258,7 +258,7 @@ public V get(Object key) {
```java ```java
void afterNodeAccess(Node < K, V > e) { // move node to last void afterNodeAccess(Node < K, V > e) { // move node to last
LinkedHashMap.Entry < K, V > last; LinkedHashMap.Entry < K, V > last;
//如果accessOrder 且当前节点不链表尾节点 //如果accessOrder 且当前节点不链表尾节点
if (accessOrder && (last = tail) != e) { if (accessOrder && (last = tail) != e) {
//获取当前节点、以及前驱节点和后继节点 //获取当前节点、以及前驱节点和后继节点

View File

@ -162,7 +162,7 @@ HMACSHA256(
3. JWT 存放在 localStorage 中而不是 Cookie 中,避免 CSRF 风险。 3. JWT 存放在 localStorage 中而不是 Cookie 中,避免 CSRF 风险。
4. 一定不要将隐私信息存放在 Payload 当中。 4. 一定不要将隐私信息存放在 Payload 当中。
5. 密钥一定保管好一定不要泄露出去。JWT 安全的核心在于签名,签名安全的核心在密钥。 5. 密钥一定保管好一定不要泄露出去。JWT 安全的核心在于签名,签名安全的核心在密钥。
6. Payload 要加入 `exp` JWT 的过期时间),永久有效的 JWT 不合理。并且JWT 的过期时间不过长。 6. Payload 要加入 `exp` JWT 的过期时间),永久有效的 JWT 不合理。并且JWT 的过期时间不过长。
7. …… 7. ……
<!-- @include: @article-footer.snippet.md --> <!-- @include: @article-footer.snippet.md -->