mirror of
https://github.com/Snailclimb/JavaGuide
synced 2025-08-01 16:28:03 +08:00
Compare commits
7 Commits
1ba08ab91f
...
7619f23556
Author | SHA1 | Date | |
---|---|---|---|
|
7619f23556 | ||
|
28ae9dc3fe | ||
|
e36a2745fe | ||
|
dc712a83f6 | ||
|
3c28da8047 | ||
|
82b576eb2f | ||
|
eb9cd6be3b |
@ -241,7 +241,7 @@ PCB 主要包含下面几部分的内容:
|
||||
1. **管道/匿名管道(Pipes)** :用于具有亲缘关系的父子进程间或者兄弟进程之间的通信。
|
||||
2. **有名管道(Named Pipes)** : 匿名管道由于没有名字,只能用于亲缘关系的进程间通信。为了克服这个缺点,提出了有名管道。有名管道严格遵循 **先进先出(First In First Out)** 。有名管道以磁盘文件的方式存在,可以实现本机任意两个进程通信。
|
||||
3. **信号(Signal)** :信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生;
|
||||
4. **消息队列(Message Queuing)**:消息队列是消息的链表,具有特定的格式,存放在内存中并由消息队列标识符标识。管道和消息队列的通信数据都是先进先出的原则。与管道(无名管道:只存在于内存中的文件;命名管道:存在于实际的磁盘介质或者文件系统)不同的是消息队列存放在内核中,只有在内核重启(即,操作系统重启)或者显式地删除一个消息队列时,该消息队列才会被真正的删除。消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取.比 FIFO 更有优势。**消息队列克服了信号承载信息量少,管道只能承载无格式字 节流以及缓冲区大小受限等缺点。**
|
||||
4. **消息队列(Message Queuing)** :消息队列是消息的链表,具有特定的格式,存放在内存中并由消息队列标识符标识。管道和消息队列的通信数据都是先进先出的原则。与管道(无名管道:只存在于内存中的文件;命名管道:存在于实际的磁盘介质或者文件系统)不同的是消息队列存放在内核中,只有在内核重启(即,操作系统重启)或者显式地删除一个消息队列时,该消息队列才会被真正的删除。消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取.比 FIFO 更有优势。消息队列克服了信号承载信息量少,管道只能承载无格式字 节流以及缓冲区大小受限等缺点。
|
||||
5. **信号量(Semaphores)** :信号量是一个计数器,用于多进程对共享数据的访问,信号量的意图在于进程间同步。这种通信方式主要用于解决与同步相关的问题并避免竞争条件。
|
||||
6. **共享内存(Shared memory)** :使得多个进程可以访问同一块内存空间,不同进程可以及时看到对方进程中对共享内存中数据的更新。这种方式需要依靠某种同步操作,如互斥锁和信号量等。可以说这是最有用的进程间通信方式。
|
||||
7. **套接字(Sockets)** : 此方法主要用于在客户端和服务器之间通过网络进行通信。套接字是支持 TCP/IP 的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程。
|
||||
|
@ -64,12 +64,12 @@ SELECT * FROM t_order WHERE id > 100000 LIMIT 10
|
||||
|
||||
```sql
|
||||
# 通过子查询来获取 id 的起始值,把 limit 1000000 的条件转移到子查询
|
||||
SELECT * FROM t_order WHERE id >= (SELECT id FROM t_order limit 1000000, 1) LIMIT 10;
|
||||
SELECT * FROM t_order WHERE id >= (SELECT id FROM t_order where id > 1000000 limit 1) LIMIT 10;
|
||||
```
|
||||
|
||||
**工作原理**:
|
||||
|
||||
1. 子查询 `(SELECT id FROM t_order LIMIT 1000000, 1)` 会利用主键索引快速定位到第 1000001 条记录,并返回其 ID 值。
|
||||
1. 子查询 `(SELECT id FROM t_order where id > 1000000 limit 1)` 会利用主键索引快速定位到第 1000001 条记录,并返回其 ID 值。
|
||||
2. 主查询 `SELECT * FROM t_order WHERE id >= ... LIMIT 10` 将子查询返回的起始 ID 作为过滤条件,使用 `id >=` 获取从该 ID 开始的后续 10 条记录。
|
||||
|
||||
不过,子查询的结果会产生一张新表,会影响性能,应该尽量避免大量使用子查询。并且,这种方法只适用于 ID 是正序的。在复杂分页场景,往往需要通过过滤条件,筛选到符合条件的 ID,此时的 ID 是离散且不连续的。
|
||||
@ -84,12 +84,12 @@ SELECT * FROM t_order WHERE id >= (SELECT id FROM t_order limit 1000000, 1) LIMI
|
||||
-- 使用 INNER JOIN 进行延迟关联
|
||||
SELECT t1.*
|
||||
FROM t_order t1
|
||||
INNER JOIN (SELECT id FROM t_order LIMIT 1000000, 10) t2 ON t1.id = t2.id;
|
||||
INNER JOIN (SELECT id FROM t_order where id > 1000000 LIMIT 10) t2 ON t1.id = t2.id;
|
||||
```
|
||||
|
||||
**工作原理**:
|
||||
|
||||
1. 子查询 `(SELECT id FROM t_order LIMIT 1000000, 10)` 利用主键索引快速定位目标分页的 10 条记录的 ID。
|
||||
1. 子查询 `(SELECT id FROM t_order where id > 1000000 LIMIT 10)` 利用主键索引快速定位目标分页的 10 条记录的 ID。
|
||||
2. 通过 `INNER JOIN` 将子查询结果与主表 `t_order` 关联,获取完整的记录数据。
|
||||
|
||||
除了使用 INNER JOIN 之外,还可以使用逗号连接子查询。
|
||||
@ -97,7 +97,7 @@ INNER JOIN (SELECT id FROM t_order LIMIT 1000000, 10) t2 ON t1.id = t2.id;
|
||||
```sql
|
||||
-- 使用逗号进行延迟关联
|
||||
SELECT t1.* FROM t_order t1,
|
||||
(SELECT id FROM t_order limit 1000000, 10) t2
|
||||
(SELECT id FROM t_order where id > 1000000 LIMIT 10) t2
|
||||
WHERE t1.id = t2.id;
|
||||
```
|
||||
|
||||
|
@ -120,7 +120,7 @@ ZooKeeper 主要为 Kafka 提供元数据的管理的功能。
|
||||
|
||||
不过,要提示一下:**如果要使用 KRaft 模式的话,建议选择较高版本的 Kafka,因为这个功能还在持续完善优化中。Kafka 3.3.1 版本是第一个将 KRaft(Kafka Raft)共识协议标记为生产就绪的版本。**
|
||||
|
||||

|
||||

|
||||
|
||||
## Kafka 消费顺序、消息丢失和重复消费
|
||||
|
||||
|
@ -300,7 +300,7 @@ int d = c--;
|
||||
int e = --d;
|
||||
```
|
||||
|
||||
答案:`a = 11` 、`b = 9` 、 `c = 10` 、 `d = 10` 、 `e = 10`。
|
||||
答案:`a = 11` 、`b = 9` 、 `c = 11` 、 `d = 11` 、 `e = 10`。
|
||||
|
||||
### 移位运算符
|
||||
|
||||
|
@ -456,7 +456,6 @@ class OutterClass$1Inner {
|
||||
|
||||
```
|
||||
|
||||
|
||||
### 条件编译
|
||||
|
||||
—般情况下,程序中的每一行代码都要参加编译。但有时候出于对程序代码优化的考虑,希望只对其中一部分内容进行编译,此时就需要在程序中加上条件,让编译器只对满足条件的代码进行编译,将不满足条件的代码舍弃,这就是条件编译。
|
||||
|
@ -4,11 +4,18 @@ category: 开源项目
|
||||
icon: a-MachineLearning
|
||||
---
|
||||
|
||||
由于 Java 在 AI 领域应用较少,因此相关的开源项目也非常少:
|
||||
由于 Java 在 AI 领域目前的应用较少,因此相关的开源项目也非常少。
|
||||
|
||||
## 基础框架
|
||||
|
||||
- [Spring AI](https://github.com/spring-projects/spring-ai):人工智能工程应用框架,为开发 AI 应用程序提供了 Spring 友好的 API 和抽象。
|
||||
- [Spring AI Alibaba](https://github.com/alibaba/spring-ai-alibaba):一款 Java 语言实现的 AI 应用开发框架,旨在简化 Java AI 应用程序开发,让 Java 开发者像使用 Spring 开发普通应用一样开发 AI 应用。
|
||||
- [LangChain4j](https://github.com/langchain4j/langchain4j):LangChiain 的 Java 版本,用于简化将 LLM(Large Language Model,大语言模型) 集成到 Java 应用程序的过程。
|
||||
- [Deeplearning4j](https://github.com/eclipse/deeplearning4j):Deeplearning4j 是第一个为 Java 和 Scala 编写的商业级,开源,分布式深度学习库。
|
||||
- [Smile](https://github.com/haifengl/smile):基于 Java 和 Scala 的机器学习库。
|
||||
- [GdxAI](https://github.com/libgdx/gdx-ai):完全用 Java 编写的人工智能框架,用于使用 libGDX 进行游戏开发。
|
||||
- [chatgpt-java](https://github.com/Grt1228/chatgpt-java):ChatGPT Java SDK。
|
||||
|
||||
## 实战
|
||||
|
||||
- [springboot-openai-chatgpt](https://github.com/274056675/springboot-openai-chatgpt):一个基于 SpringCloud 微服务架构,已对接 GPT-3.5、GPT-4.0、百度文心一言、Midjourney 绘图等等。
|
||||
- [ai-beehive](https://github.com/hncboy/ai-beehive):AI 蜂巢,基于 Java 使用 Spring Boot 3 和 JDK 17,支持的功能有 ChatGPT、OpenAi Image、Midjourney、NewBing、文心一言等等。
|
||||
|
@ -197,7 +197,7 @@ Maven 在遇到这种问题的时候,会遵循 **路径最短优先** 和 **
|
||||
|
||||
根据路径最短优先原则,X(1.0) 会被解析使用,也就是说实际用的是 1.0 版本的 X。
|
||||
|
||||
但是!!!这会一些问题:如果 D 依赖用到了 1.5 版本的 X 中才有的一个类,运行项目就会报`NoClassDefFoundError`错误。如果 D 依赖用到了 1.5 版本的 X 中才有的一个方法,运行项目就会报`NoSuchMethodError`错误。
|
||||
但是!!!这会一些问题:如果 C 依赖用到了 1.5 版本的 X 中才有的一个类,运行项目就会报`NoClassDefFoundError`错误。如果 C 依赖用到了 1.5 版本的 X 中才有的一个方法,运行项目就会报`NoSuchMethodError`错误。
|
||||
|
||||
现在知道为什么你的 Maven 项目总是会报`NoClassDefFoundError`和`NoSuchMethodError`错误了吧?
|
||||
|
||||
@ -217,7 +217,7 @@ Maven 在遇到这种问题的时候,会遵循 **路径最短优先** 和 **
|
||||
|
||||
一般我们在解决依赖冲突的时候,都会优先保留版本较高的。这是因为大部分 jar 在升级的时候都会做到向下兼容。
|
||||
|
||||
如果高版本修改了低版本的一些类或者方法的话,这个时候就能直接保留高版本了,而是应该考虑优化上层依赖,比如升级上层依赖的版本。
|
||||
如果高版本修改了低版本的一些类或者方法的话,这个时候就不能直接保留高版本了,而是应该考虑优化上层依赖,比如升级上层依赖的版本。
|
||||
|
||||
还是上面的例子:
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user