image frame

String引用传值问题

     Java 中是没有引用传递的,Java 中只有值传递。Java 中所谓的引用传递,也只是传递了"引用变量保存的地址值"。 Java 中判断"引用传递"有没有达到你预期的效果,前提要基于内存模型,并结合你的上下文,根据有没有利用引用变量"传递"的这个地址值去修改实际内存对象的数据来判断。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package edu.zjnu;

/**
* @author 杨海波
* @date 2024/2/29 20:49
* @description String 引用传值
*/
public class Main {

public static void main(String[] args) {
test01();
test02();
}

private static void test01() {
String str = "out";
// str = "out2";
f01(str);
System.out.println(str);
}

/**
* 工程实践表明,java 中没有引用传递,只有值传递。
* <p>
* Java 中所谓的引用传递,也只是传递了"引用变量保存的地址值",如果无法做到
* 根据这个引用指向的地址去修改实际对象的值,那么函数外部的实际对象无法被修改。
* 特别的,String 是不可变对象:
* 在 test01 这个例子中, 外部的 ' str = "out2"; 这行代码只是在方法区的
* 字符串常量池新建了一个字符串常量对象 "out2",并将该对象的地址赋值给引用变
* 量 str。内部的 str = "in"; 也是同理,但是当 f01 函数执行 str = "in";
* 这行代码时,引用变量保存的值(该值是尊从值传递的)是新的字符串常量对象 "in"
* 的地址,当 f01 执行完毕,这个值尊从函数作用域规则消失了。
*
* @param str
*/
private static void f01(String str) {
str = "in";
}


/**
* 解决办法如下
*/
private static void test02() {
StringWrapper str = new StringWrapper("out");
f02(str);
System.out.println(str.value);
}

private static void f02(StringWrapper str) {
str.value = "in";
}


static class StringWrapper {
// 实际值
public String value;

public StringWrapper(String value) {
this.value = value;
}
}
}

云原生之于服务端开发

     每个服务端开发人员都应该了解云原生。云原生视角,是一个全栈的服务端视角—自下而上从硬件设备到应用架构。在云原生视角下回过头来看服务端开发的问题,有点降维打击的感觉。现在看服务端开发的问题,再复杂的问题,也只是局部的一个点,很小的问题。

像专业开发人员那样调试程序

进程间通信的5种方式

以下是类UNIX操作系统(如Linux)中常见的5种通讯机制。

进程间通信的5种方式

     管道(Pipes):管道是指连接两个或多个进程的输入和输出,常用于流式传输数据。例如,shell脚本通常使用管道运算符“|” 将命令链接在一起:

1
cat /var/log/syslog | grep 'error' | less

     消息队列(Message Queues):消息队列通过允许进程以消息的形式交换数据来提供异步通信。写入队列的消息按先进先出的顺序处理。

例如,服务器可能将作业分派到队列中,消费守护进程从中拉取并独立处理。

     信号(Signals):信号提供了一种通知系统,能够让进程立即收到重要事件,如被强制终止。例如,SIGKILL提供了一种可靠的方法来结束无响应的应用程序。

     信号量(Semaphores):信号量是是一种在多线程环境中使用的同步机制,旨在确保多个线程不会同时访问同一块共享内存区域或其他临界资源。

     共享内存(Shared Memory):共享内存是允许直接访问共享内存区域,以便多个进程可以高效地读取和修改数据,而无需复制。一个示例用例是处理大型图像帧的程序,其中多个进程可以同时访问和处理图像的不同部分。

     这些IPC机制有时被组合在一起以实现高效的进程通信。

HTTPS是如何工作的

     超文本传输协议安全(HTTPS)是超文本传输协议(HTTP)的扩展。

     HTTPS使用传输层安全协议(TLS)来传输加密数据。如果数据在网上被劫持,劫持者得到的只是二进制代码。那么数据是如何加密和解密的呢?

HTTPS是如何工作的

  • 步骤1 - 客户端(浏览器)和服务器建立TCP连接。

  • 步骤2 - 客户端向服务器发送“客户端hello”。该消息包含一组必要的加密算法(密码套件)以及它可以支持的最新TLS版本。服务器通过发送“服务器hello”来响应,以便浏览器知道它是否支持算法和TLS版本。服务器然后向客户端发送SSL证书。证书包含公钥、主机名、过期日期等。客户端验证证书。

  • 步骤3 - 在验证SSL证书后,客户端生成会话密钥并使用公钥对其进行加密。服务器接收加密的会话密钥并使用私钥进行解密。

  • 步骤4 - 现在客户端和服务器都持有相同的会话密钥(对称加密),加密数据通过安全的双向通道进行传输。

     为什么HTTPS在数据传输期间会切换到对称加密?主要有两个原因:

  • 1、安全:非对称加密只适用于单向。这意味着如果服务器尝试将加密数据发送回客户端,任何人都可以使用公钥解密数据。

  • 2、服务器资源:非对称加密增加了大量的数学开销。它不适合长会话中的数据传输。

Java 开发常见面试知识点梳理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
1、Java 部分

设计模式:
单例模式(懒汉式、饿汉式、双重锁)
工厂模式(简单工厂、工厂方法、抽象工厂)
代理模式(静态代理、动态代理)
策略模式(解耦算法与业务)
观察者模式(发布-订阅模式)
装饰者模式(功能扩展)

并发:
Java 线程基础(线程创建、状态、生命周期)
线程池(ThreadPoolExecutor 原理、线程池优化)
并发工具类(CountDownLatch、CyclicBarrier、Semaphore)
锁机制(synchronized、ReentrantLock、公平锁、读写锁)
CAS 与原子操作(Atomic 类的实现原理、ABA 问题)
volatile 与内存可见性(happens-before 原则)
AQS(AbstractQueuedSynchronizer)原理(锁的底层实现)
并发容器(ConcurrentHashMap 原理、CopyOnWriteArrayList)

集合框架:
List(ArrayList、LinkedList 区别)
Set(HashSet、TreeSet、LinkedHashSet)
Map(HashMap、TreeMap、LinkedHashMap、ConcurrentHashMap)
Fail-fast 与 fail-safe(遍历过程中修改问题)
HashMap 的底层原理(链表转红黑树的条件)

JVM:
JVM 内存模型(堆、栈、方法区、程序计数器)
类加载机制(双亲委派模型、类加载器)
垃圾回收算法(标记-清除、标记-整理、复制算法)
垃圾回收器(Serial、Parallel、CMS、G1 原理)
JVM 性能调优(JVM 参数、内存分析工具、GC 日志分析)
类文件结构(字节码结构、方法区细节)


2、框架部分

Spring:
Spring IOC 容器(Bean 的生命周期、依赖注入)
AOP 原理(动态代理、CGLib 实现)
事务管理(声明式事务、事务传播机制)
Spring MVC(请求处理流程、DispatcherServlet、HandlerMapping)
Spring Boot(自动配置原理、嵌入式容器)
Spring Cloud(服务注册与发现、负载均衡、断路器)

MyBatis:
MyBatis 基础(SQL 映射、动态 SQL、缓存机制)
一级缓存、二级缓存的原理和区别
MyBatis 插件机制(拦截器实现、性能优化)
性能调优(懒加载、批量处理、SQL 优化)


3、缓存

Redis 的基本数据结构:
String、List、Set、Sorted Set、Hash、Bitmap、HyperLogLog、Geo

大Key 和 热Key:
概念,如何解决

大Key问题:
如何拆分大Key,避免阻塞 Redis 线程

热Key问题:
热点数据导致单节点压力过大,如何通过分片或缓存穿透防止单点瓶颈

持久化:
RDB(快照)机制(优点、缺点、触发条件)
AOF(Append Only File)机制(优点、缺点、重写策略)
混合持久化(RDB+AOF 的结合)

Redis 高可用:
主从复制(异步复制的原理)
哨兵模式(自动故障转移)
Redis Cluster(分片、槽位映射、Gossip 协议)
持久化与高可用的权衡


4、MySQL

事务相关:
ACID 原则(原子性、一致性、隔离性、持久性)
事务隔离级别(读未提交、读已提交、可重复读、串行化)
锁机制(共享锁、排他锁、行锁、表锁)
MVCC(多版本并发控制,InnoDB 如何实现可重复读)

死锁:
概念及其解决办法(死锁检测、回滚机制)

SQL 优化:
索引设计与优化(覆盖索引、最左前缀原则、索引下推)
慢查询分析(explain、索引扫描、全表扫描)
分库分表(垂直拆分、水平拆分、分片策略)
读写分离(主从复制、读从库、写主库)


5、消息队列

消息类型:
点对点(Queue):消息只能由一个消费者消费
发布-订阅(Topic):消息广播给多个订阅者
延时消息:如 RabbitMQ 的 TTL 队列或 Kafka 延时消息
事务消息:RocketMQ 事务消息,用于实现分布式事务

消息队列架构:
Broker、Producer、Consumer 模型(生产者、消费者、Broker 的架构)

消息确认机制:
消息成功消费的确认流程,避免消息丢失

负载均衡:
如何平衡消费者之间的消费压力

可靠投递:
消息持久化(消息落盘,防止 Broker 宕机导致消息丢失)
幂等性保障(如何避免重复消费的问题,如幂等消费逻辑)
消息投递重试机制(失败后重试策略,死信队列)

消息堆积:
消息积压问题:由于消费速度跟不上生产速度,消息在队列中堆积
如何应对:增加消费者并行消费能力、削峰填谷


6、分布式

CAP 理论:
Consistency:一致性
Availability:可用性
Partition Tolerance:分区容错性
CAP 不可能三角:只能同时满足两者,典型场景举例

微服务架构:
服务拆分与通信(REST、RPC、gRPC)
服务发现(Zookeeper、Eureka、Consul)
负载均衡(Ribbon、Nginx、Spring Cloud LoadBalancer)
服务容错(Hystrix、Sentinel 实现熔断降级)

服务治理:
配置管理(Spring Cloud Config、Nacos)
服务监控(Prometheus、Grafana、Sleuth)
链路追踪(Zipkin、Jaeger,分布式追踪系统)

7、项目准备

日志框架简史

  • Copyrights © 2017 - 2025 杨海波
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信