1
0
mirror of https://github.com/Snailclimb/JavaGuide synced 2025-07-28 12:22:17 +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}
```
**Redis 跳表的特点**
1. 采用**双向链表**,不同于上面的示例,存在一个回退指针。主要用于简化操作,例如删除某个元素时,还需要找到该元素的前驱节点,使用回退指针会非常方便。
2. `score` 值可以重复,如果 `score` 值一样,则按照 ele节点存储的值为 sds字典排序
3. Redis 跳跃表默认允许最大的层数是32被源码中 `ZSKIPLIST_MAXLEVEL` 定义。
## 和其余三种数据结构的比较
最后,我们再来回答一下文章开头的那道面试题: “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
void afterNodeAccess(Node < K, V > e) { // move node to last
LinkedHashMap.Entry < K, V > last;
//如果accessOrder 且当前节点不链表尾节点
//如果accessOrder 且当前节点不链表尾节点
if (accessOrder && (last = tail) != e) {
//获取当前节点、以及前驱节点和后继节点

View File

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