From 28ae9dc3fe5aaba2639e8aab445a76d57c6b7c36 Mon Sep 17 00:00:00 2001 From: Guide Date: Fri, 18 Oct 2024 15:48:44 +0800 Subject: [PATCH] =?UTF-8?q?[docs=20update]=E6=96=B0=E5=A2=9E=E5=87=A0?= =?UTF-8?q?=E4=B8=AAai=E5=BC=80=E6=BA=90=E9=A1=B9=E7=9B=AE&typo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../operating-system-basic-questions-01.md | 18 +++++++++--------- docs/database/redis/redis-skiplist.md | 2 +- .../message-queue/kafka-questions-01.md | 2 +- docs/java/basis/syntactic-sugar.md | 9 ++++----- docs/open-source-project/machine-learning.md | 11 +++++++++-- 5 files changed, 24 insertions(+), 18 deletions(-) diff --git a/docs/cs-basics/operating-system/operating-system-basic-questions-01.md b/docs/cs-basics/operating-system/operating-system-basic-questions-01.md index ad102982..a0a06b0c 100644 --- a/docs/cs-basics/operating-system/operating-system-basic-questions-01.md +++ b/docs/cs-basics/operating-system/operating-system-basic-questions-01.md @@ -201,10 +201,10 @@ _玩玩电脑游戏还是必须要有 Windows 的,所以我现在是一台 Win 下面是几种常见的线程同步的方式: -1. **互斥锁(Mutex)**:采用互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限。因为互斥对象只有一个,所以可以保证公共资源不会被多个线程同时访问。比如 Java 中的 `synchronized` 关键词和各种 `Lock` 都是这种机制。 -2. **读写锁(Read-Write Lock)**:允许多个线程同时读取共享资源,但只有一个线程可以对共享资源进行写操作。 -3. **信号量(Semaphore)**:它允许同一时刻多个线程访问同一资源,但是需要控制同一时刻访问此资源的最大线程数量。 -4. **屏障(Barrier)**:屏障是一种同步原语,用于等待多个线程到达某个点再一起继续执行。当一个线程到达屏障时,它会停止执行并等待其他线程到达屏障,直到所有线程都到达屏障后,它们才会一起继续执行。比如 Java 中的 `CyclicBarrier` 是这种机制。 +1. **互斥锁(Mutex)** :采用互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限。因为互斥对象只有一个,所以可以保证公共资源不会被多个线程同时访问。比如 Java 中的 `synchronized` 关键词和各种 `Lock` 都是这种机制。 +2. **读写锁(Read-Write Lock)** :允许多个线程同时读取共享资源,但只有一个线程可以对共享资源进行写操作。 +3. **信号量(Semaphore)** :它允许同一时刻多个线程访问同一资源,但是需要控制同一时刻访问此资源的最大线程数量。 +4. **屏障(Barrier)** :屏障是一种同步原语,用于等待多个线程到达某个点再一起继续执行。当一个线程到达屏障时,它会停止执行并等待其他线程到达屏障,直到所有线程都到达屏障后,它们才会一起继续执行。比如 Java 中的 `CyclicBarrier` 是这种机制。 5. **事件(Event)** :Wait/Notify:通过通知操作的方式来保持多线程同步,还可以方便的实现多线程优先级的比较操作。 ### PCB 是什么?包含哪些信息? @@ -238,12 +238,12 @@ PCB 主要包含下面几部分的内容: > 下面这部分总结参考了:[《进程间通信 IPC (InterProcess Communication)》](https://www.jianshu.com/p/c1015f5ffa74) 这篇文章,推荐阅读,总结的非常不错。 -1. **管道/匿名管道(Pipes)**:用于具有亲缘关系的父子进程间或者兄弟进程之间的通信。 +1. **管道/匿名管道(Pipes)** :用于具有亲缘关系的父子进程间或者兄弟进程之间的通信。 2. **有名管道(Named Pipes)** : 匿名管道由于没有名字,只能用于亲缘关系的进程间通信。为了克服这个缺点,提出了有名管道。有名管道严格遵循 **先进先出(First In First Out)** 。有名管道以磁盘文件的方式存在,可以实现本机任意两个进程通信。 -3. **信号(Signal)**:信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生; -4. **消息队列(Message Queuing)**:消息队列是消息的链表,具有特定的格式,存放在内存中并由消息队列标识符标识。管道和消息队列的通信数据都是先进先出的原则。与管道(无名管道:只存在于内存中的文件;命名管道:存在于实际的磁盘介质或者文件系统)不同的是消息队列存放在内核中,只有在内核重启(即,操作系统重启)或者显式地删除一个消息队列时,该消息队列才会被真正的删除。消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取.比 FIFO 更有优势。**消息队列克服了信号承载信息量少,管道只能承载无格式字 节流以及缓冲区大小受限等缺点。** -5. **信号量(Semaphores)**:信号量是一个计数器,用于多进程对共享数据的访问,信号量的意图在于进程间同步。这种通信方式主要用于解决与同步相关的问题并避免竞争条件。 -6. **共享内存(Shared memory)**:使得多个进程可以访问同一块内存空间,不同进程可以及时看到对方进程中对共享内存中数据的更新。这种方式需要依靠某种同步操作,如互斥锁和信号量等。可以说这是最有用的进程间通信方式。 +3. **信号(Signal)** :信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生; +4. **消息队列(Message Queuing)** :消息队列是消息的链表,具有特定的格式,存放在内存中并由消息队列标识符标识。管道和消息队列的通信数据都是先进先出的原则。与管道(无名管道:只存在于内存中的文件;命名管道:存在于实际的磁盘介质或者文件系统)不同的是消息队列存放在内核中,只有在内核重启(即,操作系统重启)或者显式地删除一个消息队列时,该消息队列才会被真正的删除。消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取.比 FIFO 更有优势。消息队列克服了信号承载信息量少,管道只能承载无格式字 节流以及缓冲区大小受限等缺点。 +5. **信号量(Semaphores)** :信号量是一个计数器,用于多进程对共享数据的访问,信号量的意图在于进程间同步。这种通信方式主要用于解决与同步相关的问题并避免竞争条件。 +6. **共享内存(Shared memory)** :使得多个进程可以访问同一块内存空间,不同进程可以及时看到对方进程中对共享内存中数据的更新。这种方式需要依靠某种同步操作,如互斥锁和信号量等。可以说这是最有用的进程间通信方式。 7. **套接字(Sockets)** : 此方法主要用于在客户端和服务器之间通过网络进行通信。套接字是支持 TCP/IP 的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程。 ### 进程的调度算法有哪些? diff --git a/docs/database/redis/redis-skiplist.md b/docs/database/redis/redis-skiplist.md index 1eb23400..1194f736 100644 --- a/docs/database/redis/redis-skiplist.md +++ b/docs/database/redis/redis-skiplist.md @@ -603,7 +603,7 @@ Node{data=23, maxLevel=1} 1. 采用**双向链表**,不同于上面的示例,存在一个回退指针。主要用于简化操作,例如删除某个元素时,还需要找到该元素的前驱节点,使用回退指针会非常方便。 2. `score` 值可以重复,如果 `score` 值一样,则按照 ele(节点存储的值,为 sds)字典排序 -3. Redis 跳跃表默认允许最大的层数是32,被源码中 `ZSKIPLIST_MAXLEVEL` 定义。 +3. Redis 跳跃表默认允许最大的层数是 32,被源码中 `ZSKIPLIST_MAXLEVEL` 定义。 ## 和其余三种数据结构的比较 diff --git a/docs/high-performance/message-queue/kafka-questions-01.md b/docs/high-performance/message-queue/kafka-questions-01.md index 7e690399..070858cc 100644 --- a/docs/high-performance/message-queue/kafka-questions-01.md +++ b/docs/high-performance/message-queue/kafka-questions-01.md @@ -120,7 +120,7 @@ ZooKeeper 主要为 Kafka 提供元数据的管理的功能。 不过,要提示一下:**如果要使用 KRaft 模式的话,建议选择较高版本的 Kafka,因为这个功能还在持续完善优化中。Kafka 3.3.1 版本是第一个将 KRaft(Kafka Raft)共识协议标记为生产就绪的版本。** -![]( production-ready.png) +![](https://oss.javaguide.cn/github/javaguide/high-performance/message-queue/kafka3.3.1-kraft-production-ready.png) ## Kafka 消费顺序、消息丢失和重复消费 diff --git a/docs/java/basis/syntactic-sugar.md b/docs/java/basis/syntactic-sugar.md index 3d658c6e..3ce9bfc1 100644 --- a/docs/java/basis/syntactic-sugar.md +++ b/docs/java/basis/syntactic-sugar.md @@ -379,9 +379,9 @@ public class OutterClass } ``` -**为什么内部类可以使用外部类的private属性**: +**为什么内部类可以使用外部类的 private 属性**: -我们在InnerClass中增加一个方法,打印外部类的userName属性 +我们在 InnerClass 中增加一个方法,打印外部类的 userName 属性 ```java //省略其他属性 @@ -411,7 +411,7 @@ class OutterClass$InnerClass { ``` -实际上,在编译完成之后,inner实例内部会有指向outer实例的引用`this$0`,但是简单的`outer.name`是无法访问private属性的。从反编译的结果可以看到,outer中会有一个桥方法`static String access$000(OutterClass)`,恰好返回String类型,即userName属性。正是通过这个方法实现内部类访问外部类私有属性。所以反编译后的`printOut()`方法大致如下: +实际上,在编译完成之后,inner 实例内部会有指向 outer 实例的引用`this$0`,但是简单的`outer.name`是无法访问 private 属性的。从反编译的结果可以看到,outer 中会有一个桥方法`static String access$000(OutterClass)`,恰好返回 String 类型,即 userName 属性。正是通过这个方法实现内部类访问外部类私有属性。所以反编译后的`printOut()`方法大致如下: ```java public void printOut() { @@ -421,7 +421,7 @@ public void printOut() { 补充: -1. 匿名内部类、局部内部类、静态内部类也是通过桥方法来获取private属性。 +1. 匿名内部类、局部内部类、静态内部类也是通过桥方法来获取 private 属性。 2. 静态内部类没有`this$0`的引用 3. 匿名内部类、局部内部类通过复制使用局部变量,该变量初始化之后就不能被修改。以下是一个案例: @@ -456,7 +456,6 @@ class OutterClass$1Inner { ``` - ### 条件编译 —般情况下,程序中的每一行代码都要参加编译。但有时候出于对程序代码优化的考虑,希望只对其中一部分内容进行编译,此时就需要在程序中加上条件,让编译器只对满足条件的代码进行编译,将不满足条件的代码舍弃,这就是条件编译。 diff --git a/docs/open-source-project/machine-learning.md b/docs/open-source-project/machine-learning.md index 9feaaf4a..6ace75ac 100644 --- a/docs/open-source-project/machine-learning.md +++ b/docs/open-source-project/machine-learning.md @@ -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、文心一言等等。