diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 0b228509..9b027607 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -337,6 +337,7 @@ jobs:
+
@@ -349,7 +350,6 @@ jobs:
-
diff --git a/README.md b/README.md
index 2eb52f98..3b8d61da 100644
--- a/README.md
+++ b/README.md
@@ -56,6 +56,7 @@ Quick Reference
[Dockerfile](./docs/dockerfile.md)
[Django](./docs/django.md)
[Elixir](./docs/elixir.md)
+[Erlang](./docs/erlang.md)
[Flask](./docs/flask.md)
[FastAPI](./docs/fastapi.md)
[Flutter](./docs/flutter.md)
@@ -77,7 +78,7 @@ Quick Reference
[Scala](./docs/scala.md)
[Swift](./docs/swift.md)
[SwiftUI](./docs/swiftui.md)
-[Spring Boot](./docs/springboot.md)
+[Spring Boot](./docs/springboot.md)
[Lua](./docs/lua.md)
[Pytorch](./docs/pytorch.md)
@@ -100,6 +101,7 @@ Quick Reference
[JavaScript](./docs/javascript.md)
[jQuery](./docs/jquery.md)
[Next.js](./docs/nextjs.md)
+[RxJS](./docs/rxjs.md)
[React](./docs/react.md)
[React Router](./docs/reactrouter.md)
[React Native](./docs/react-native.md)
@@ -284,6 +286,7 @@ Quick Reference
+
@@ -296,7 +299,6 @@ Quick Reference
-
diff --git a/assets/erlang.svg b/assets/erlang.svg
new file mode 100644
index 00000000..a4b941c2
--- /dev/null
+++ b/assets/erlang.svg
@@ -0,0 +1,12 @@
+
\ No newline at end of file
diff --git a/assets/rxjs.svg b/assets/rxjs.svg
new file mode 100644
index 00000000..8cde0f51
--- /dev/null
+++ b/assets/rxjs.svg
@@ -0,0 +1,27 @@
+
\ No newline at end of file
diff --git a/docs/erlang.md b/docs/erlang.md
new file mode 100644
index 00000000..26c473f7
--- /dev/null
+++ b/docs/erlang.md
@@ -0,0 +1,450 @@
+Erlang 备忘清单
+===
+
+[Erlang](https://www.erlang.org/) 是一种用于构建并发、分布式和容错系统的编程语言。以下是一些常用的命令和操作。
+
+入门
+---
+
+### 启动 Erlang Shell
+
+```shell
+erl
+```
+
+### 编译代码
+
+
+```shell
+# 在 Erlang Shell 中编译
+c(module).
+# 在命令行中编译
+erlc module.erl
+```
+
+### 运行代码
+
+
+```shell
+# 在 Erlang Shell 中运行
+module:function().
+# 从命令行运行
+erl -noshell -s module function -s init stop
+```
+
+### 退出 Erlang Shell
+
+```shell
+q().
+```
+
+代码结构
+---
+
+### 模块定义
+
+```erlang
+-module(module_name).
+-export([function_name/arity, ...]).
+
+function_name(Args) ->
+ % Function body.
+ Result.
+```
+
+### 导出函数
+
+```erlang
+-export([function1/0, function2/1]).
+```
+
+### 注释
+
+```erlang
+% 单行注释
+% 这是一个注释
+```
+
+### 变量
+
+```erlang
+VarName = Value. % 变量名必须以大写字母开头
+Age = 25.
+Name = "Alice".
+```
+
+数据类型
+---
+
+### 原子
+
+```erlang
+atom. % 例子:atom, 'Atom with spaces'
+```
+
+### 数字
+
+```erlang
+123. % 整数
+3.14. % 浮点数
+```
+
+### 布尔值
+
+```erlang
+true.
+false.
+```
+
+### 字符串
+
+```erlang
+"Hello, World!".
+```
+
+### 元组
+
+```erlang
+{ok, "Success"}.
+```
+
+### 列表
+
+```erlang
+[1, 2, 3].
+[H|T] = [1, 2, 3]. % H = 1, T = [2, 3]
+```
+
+### 字典 (Map)
+
+```erlang
+#{key1 => value1, key2 => value2}.
+```
+
+控制结构
+---
+
+### 条件语句
+
+```erlang
+if
+ Condition1 -> Expression1;
+ Condition2 -> Expression2;
+ true -> DefaultExpression
+end.
+```
+
+### case 表达式
+
+```erlang
+case Expression of
+ Pattern1 -> Expression1;
+ Pattern2 -> Expression2;
+ _ -> DefaultExpression
+end.
+```
+
+### 函数定义
+
+```erlang
+% 无参函数
+my_function() ->
+ ok.
+
+% 有参函数
+add(A, B) ->
+ A + B.
+```
+
+列表操作
+---
+
+### 列表生成
+
+```erlang
+% 生成 1 到 10 的列表
+[ X || X <- lists:seq(1, 10)].
+
+% 生成 1 到 10 中的偶数
+[ X || X <- lists:seq(1, 10), X rem 2 == 0].
+```
+
+并发
+---
+
+### 启动进程
+
+```erlang
+spawn(Module, Function, Args).
+
+% 示例
+Pid = spawn(fun() -> io:format("Hello from process~n") end).
+```
+
+### 发送消息
+
+```erlang
+Pid ! Message.
+
+% 示例
+Pid ! {hello, self()}.
+```
+
+### 接收消息
+
+```erlang
+receive
+ Pattern1 -> Expression1;
+ Pattern2 -> Expression2;
+ after Timeout -> TimeoutExpression
+end.
+```
+
+### 模式匹配
+
+```erlang
+{ok, Value} = {ok, 42}.
+```
+
+常用内置函数 (BIFs)
+---
+
+### 列表操作
+
+```erlang
+lists:append(List1, List2).
+lists:map(Function, List).
+lists:filter(Function, List).
+lists:foldl(Function, Acc, List).
+```
+
+### 元组操作
+
+```erlang
+element(N, Tuple).
+setelement(N, Tuple, Value).
+tuple_size(Tuple).
+```
+
+### 字符串操作
+
+```erlang
+string:len(String).
+string:concat(String1, String2).
+string:tokens(String, Delimiters).
+```
+
+### 文件操作
+
+```erlang
+file:read_file(Filename).
+file:write_file(Filename, Data).
+file:delete(Filename).
+```
+
+### 列表操作
+
+```erlang
+lists:map(fun(X) -> X * 2 end, [1, 2, 3]).
+lists:filter(fun(X) -> X rem 2 == 0 end, [1, 2, 3, 4]).
+```
+
+### 字符串操作
+
+```erlang
+string:len("Hello").
+string:upper("hello").
+```
+
+### 文件操作
+
+```erlang
+{ok, File} = file:open("test.txt", [write]).
+file:write(File, "Hello, file!").
+file:close(File).
+```
+
+### 示例:简单的服务器
+
+```erlang
+-module(server).
+-export([start/0, loop/0]).
+
+start() ->
+ spawn(fun loop/0).
+
+loop() ->
+ receive
+ {echo, Msg} ->
+ io:format("Echo: ~p~n", [Msg]),
+ loop();
+ stop ->
+ io:format("Server stopping~n"),
+ ok;
+ _ ->
+ io:format("Unknown message~n"),
+ loop()
+ end.
+```
+
+并发编程
+---
+
+### 创建进程
+
+```erlang
+Pid = spawn(Module, Function, Args).
+```
+
+### 发送消息
+
+```erlang
+Pid ! Message.
+```
+
+### 接收消息
+
+```erlang
+receive
+ Pattern1 -> Actions1;
+ Pattern2 -> Actions2;
+ ...
+end.
+```
+
+### 链接进程
+
+```erlang
+link(Pid).
+unlink(Pid).
+```
+
+### 监控进程
+
+```erlang
+MonitorRef = erlang:monitor(process, Pid).
+erlang:demonitor(MonitorRef).
+```
+
+错误处理
+---
+
+### 捕获异常
+
+```erlang
+try Expression of
+ Pattern -> Result
+catch
+ Class:Reason -> Handler
+end.
+```
+
+### 常见异常类型
+
+- `throw`
+- `error`
+- `exit`
+
+### 错误处理
+
+```erlang
+try Expression of
+ Pattern -> Result
+catch
+ Type:Reason -> ErrorHandlingExpression
+end.
+```
+
+分布式编程
+---
+
+### 启动分布式节点
+
+```shell
+erl -name nodename@hostname -setcookie Cookie
+```
+
+### 连接节点
+
+```erlang
+net_adm:ping(Node).
+```
+
+### 发送消息到远程节点
+
+```erlang
+{remote_process, 'remote_node@host'} ! Message.
+```
+
+OTP 框架
+---
+
+### 定义 GenServer
+
+```erlang
+-module(my_gen_server).
+-behaviour(gen_server).
+
+-export([start_link/0, init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
+
+start_link() ->
+ gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
+
+init([]) ->
+ {ok, #state{}}.
+
+handle_call(Request, From, State) ->
+ {reply, Reply, State}.
+
+handle_cast(Msg, State) ->
+ {noreply, State}.
+
+handle_info(Info, State) ->
+ {noreply, State}.
+
+terminate(Reason, State) ->
+ ok.
+
+code_change(OldVsn, State, Extra) ->
+ {ok, State}.
+```
+
+### 使用 GenServer
+
+```erlang
+gen_server:start_link({local, Name}, Module, Args, Options).
+gen_server:call(ServerRef, Request).
+gen_server:cast(ServerRef, Msg).
+```
+
+测试
+---
+
+### 编写 EUnit 测试
+
+```erlang
+-module(module_name_tests).
+-include_lib("eunit/include/eunit.hrl").
+
+simple_test() ->
+ ?assertEqual(Expected, Actual).
+
+complex_test_() ->
+ [
+ {"Test case 1", ?_assertEqual(Expected1, Actual1)},
+ {"Test case 2", ?_assertEqual(Expected2, Actual2)}
+ ].
+```
+
+### 运行 EUnit 测试
+
+```shell
+# 在命令行中运行
+erl -eval "eunit:test(module_name)" -s init stop
+```
+
+另见
+---
+
+- [Erlang 官方文档](https://www.erlang.org/docs)
+- [Erlang 编程书籍](https://www.erlang.org/books)
diff --git a/docs/rxjs.md b/docs/rxjs.md
new file mode 100644
index 00000000..d19ec882
--- /dev/null
+++ b/docs/rxjs.md
@@ -0,0 +1,419 @@
+RxJS 备忘清单
+===
+
+[RxJS](https://rxjs.dev/)(Reactive Extensions for JavaScript)是一个强大的库,用于处理异步事件和数据流。以下是 RxJS 的一些关键概念、操作符和方法的总结。
+
+## 入门
+
+### 安装 RxJS
+
+```bash
+npm install rxjs
+```
+
+### 清晰
+
+
+RxJS 的强大之处在于它使用纯函数生成值的能力。这意味着您的代码更不容易出错。通常情况下,您会创建一个不纯的函数,而代码的其他部分可能会弄乱您的状态。
+
+```js
+let count = 0;
+document.addEventListener('click', () => {
+ console.log(`Clicked ${++count} times`)
+});
+```
+
+使用 RxJS 可以隔离状态。
+
+```js
+import { fromEvent, scan } from 'rxjs';
+
+fromEvent(document, 'click')
+ .pipe(scan((count) => count + 1, 0))
+ .subscribe((count) => {
+ console.log(`Clicked ${count} times`)
+ });
+```
+
+扫描操作符的工作原理与数组的 `reduce` 类似。它接受一个暴露给回调函数的值。回调的返回值将成为下次回调运行时公开的下一个值。
+
+### 流
+
+
+RxJS 拥有一整套运算符,可以帮助您控制事件如何流经您的可观察对象。这是使用纯 JavaScript 每秒最多允许一次点击的方式:
+
+```js
+let count = 0;
+let rate = 1000;
+let lastClick = Date.now() - rate;
+document.addEventListener('click', () => {
+ if (Date.now() - lastClick >= rate) {
+ console.log(`Clicked ${++count}times`);
+ lastClick = Date.now();
+ }
+});
+```
+
+使用 RxJS:
+
+```js
+import { fromEvent, throttleTime, scan
+ } from 'rxjs';
+
+fromEvent(document, 'click')
+ .pipe(throttleTime(1000),
+ scan((count) => count + 1, 0)
+ )
+ .subscribe((count) => {
+ console.log(`Clicked ${count} times`)
+ });
+```
+
+### 第一个示例
+
+通常情况下,您需要注册事件监听器。
+
+```js
+document.addEventListener('click', () => {
+ console.log('Clicked!')
+});
+```
+
+使用 [RxJS](https://rxjs.dev/),您可以创建一个可观察对象。
+
+```js
+import { fromEvent } from 'rxjs';
+
+fromEvent(document, 'click')
+ .subscribe(() => {
+ console.log('Clicked!')
+ });
+```
+
+### 导入所需的 Observable 和操作符
+
+
+```javascript
+import { Observable, of, from, interval, fromEvent } from 'rxjs';
+
+import { map, filter, switchMap, mergeMap, catchError, debounceTime,
+ distinctUntilChanged, take, tap, concatMap, delay, retryWhen, scan,
+ combineLatest, concat, merge, forkJoin, withLatestFrom, startWith, reduce
+} from 'rxjs/operators';
+```
+
+## 创建 Observable
+
+### of
+
+```javascript
+const obs = of(1, 2, 3);
+obs.subscribe(console.log);
+// 输出: 1 2 3
+```
+
+创建一个立即发送指定值并完成的 Observable
+
+### from
+
+```javascript
+const obs = from([1, 2, 3]);
+obs.subscribe(console.log);
+// 输出: 1 2 3
+```
+
+从 Promise、数组、可迭代对象创建 Observable
+
+### interval
+
+```javascript
+const obs = interval(1000);
+obs.subscribe(console.log);
+// 每秒输出一次递增的数字
+```
+
+创建一个定时发送递增整数的 Observable
+
+### fromEvent
+
+
+```javascript
+const button = document.querySelector('button');
+const obs = fromEvent(button, 'click');
+obs.subscribe(event => {
+ console.log('Button clicked!', event)
+});
+```
+
+从 DOM 事件创建 Observable
+
+## 操作符
+
+### map
+
+```javascript
+const obs = of(1, 2, 3).pipe(
+ map(x => x * 2)
+);
+obs.subscribe(console.log);
+// 输出: 2 4 6
+```
+
+对 Observable 发出的每个值应用一个函数
+
+### filter
+
+```javascript
+const obs = of(1, 2, 3).pipe(
+ filter(x => x % 2 === 0)
+);
+obs.subscribe(console.log);
+// 输出: 2
+```
+
+过滤 Observable 发出的值
+
+### switchMap
+
+```javascript
+const obs = interval(1000).pipe(
+ switchMap(() => of('Hello'))
+);
+
+obs.subscribe(console.log);
+// 每秒输出一次 "Hello"
+```
+
+将 Observable 每个值映射成 Observable 并订阅,前一个订阅将被取消
+
+### mergeMap
+
+```javascript
+const obs = interval(1000).pipe(
+ mergeMap(() => of('Hello'))
+);
+
+obs.subscribe(console.log);
+// 每秒输出一次 "Hello"
+```
+
+类似 switchMap,但允许多个内部 Observable 并发执行
+
+### catchError
+
+```javascript
+const obs = of(1, 2, 3).pipe(
+ map(x => {
+ if (x === 2) throw 'Error!';
+ return x;
+ }),
+ catchError(err => of('发现一个错误:'+err))
+);
+obs.subscribe(console.log);
+// 输出: 1 发现一个错误:Error!
+```
+
+捕获 Observable 链中的错误
+
+### debounceTime
+
+```javascript
+const obs = fromEvent(document,'mousemove')
+ .pipe(debounceTime(300));
+
+obs.subscribe(event => {
+ console.log('Mouse moved!', event)
+});
+```
+
+延迟处理,直到源 Observable 停止发出数据一定时间
+
+### distinctUntilChanged
+
+```javascript
+const obs = of(1, 1, 2, 2, 3, 3).pipe(
+ distinctUntilChanged()
+);
+obs.subscribe(console.log);
+// 输出: 1 2 3
+```
+
+忽略连续重复的值
+
+### take
+
+```javascript
+const obs = interval(1000).pipe(
+ take(3)
+);
+obs.subscribe(console.log);
+// 输出: 0 1 2
+```
+
+只发出前 n 个值
+
+## 组合操作符
+
+### combineLatest
+
+```javascript
+const obs1 = interval(1000);
+const obs2 = of('A', 'B', 'C');
+const combined = combineLatest(
+ [obs1, obs2]
+);
+
+combined.subscribe(console.log);
+// 每秒输出一次两个 observables 的最新值
+```
+
+当两个 Observable 都发出新的值时,发出它们的组合
+
+### concat
+
+```javascript
+const obs1 = of(1, 2, 3);
+const obs2 = of(4, 5, 6);
+const combined = concat(obs1, obs2);
+combined.subscribe(console.log);
+// 输出: 1 2 3 4 5 6
+```
+
+按顺序连接多个 Observable
+
+### merge
+
+```javascript
+const obs1 = interval(1000).pipe(
+ map(x => 'A' + x)
+);
+const obs2 = interval(500).pipe(
+ map(x => 'B' + x)
+);
+const combined = merge(obs1, obs2);
+combined.subscribe(console.log);
+// 每秒输出 "A" 和 "B" 开头的递增数字
+```
+
+将多个 Observable 合并为一个
+
+### forkJoin
+
+```javascript
+const obs1 = of(1, 2, 3);
+const obs2 = of('A', 'B', 'C');
+const combined = forkJoin([obs1, obs2]);
+combined.subscribe(console.log);
+// 输出: [3, 'C']
+```
+
+等待所有 Observable 完成,然后发出它们的最后一个值的数组
+
+## 错误处理
+
+### retryWhen
+
+
+```javascript
+const obs = throwError('出了些问题!')
+ .pipe(
+ retryWhen(errors =>
+ errors.pipe(delayWhen(() => interval(1000)))
+ )
+ );
+obs.subscribe(console.log, console.error);
+// 输出: 出了些问题! (每秒重试一次)
+```
+
+在 Observable 发出错误时重试
+
+## 实用操作符
+
+### tap
+
+```javascript
+const obs = of(1, 2, 3).pipe(
+ tap(x => console.log(`Before: ${x}`)),
+ map(x => x * 2),
+ tap(x => console.log(`After: ${x}`))
+);
+obs.subscribe();
+// 输出: Before: 1, After: 2, Before: 2,
+// After: 4, Before: 3, After: 6
+```
+
+用于记录、测量或执行副作用操作
+
+### startWith
+
+```javascript
+const obs = of(1, 2, 3).pipe(
+ startWith(0)
+);
+obs.subscribe(console.log);
+// 输出: 0 1 2 3
+```
+
+在 `Observable` 序列前添加值
+
+### scan
+
+```javascript
+const obs = of(1, 2, 3).pipe(
+ scan((acc, value) => acc + value, 0)
+);
+obs.subscribe(console.log);
+// 输出: 1 3 6
+```
+
+对 `Observable` 发出的每个值应用累加器函数
+
+### reduce
+
+
+```javascript
+const obs = of(1, 2, 3).pipe(reduce((acc, value) => acc + value, 0));
+obs.subscribe(console.log);
+// 输出: 6
+```
+
+对 `Observable` 发出的值进行累加
+
+### delay
+
+```javascript
+const obs = of('Hello').pipe(delay(2000));
+obs.subscribe(console.log);
+// 输出: 'Hello' (延迟2秒)
+```
+
+延迟 `Observable` 发出数据的时间
+
+调度器
+---
+
+### 调度器说明
+
+调度器(Scheduler)控制着 RxJS 操作的执行时机。常见的调度器有:
+
+- `asyncScheduler`:异步执行任务
+- `queueScheduler`:按队列顺序执行任务
+- `animationFrameScheduler`:在浏览器的下一次重绘前执行任务
+
+### 示例
+
+
+```javascript
+const obs = of(1, 2, 3).pipe(observeOn(asyncScheduler));
+
+console.log('Before subscribe');
+obs.subscribe(console.log);
+console.log('After subscribe');
+// 输出: Before subscribe, After subscribe, 1, 2, 3
+```
+
+## 另见
+
+- [RxJS 官方文档](https://rxjs.dev/)
+- [RxJS 学习资源](https://rxjs.dev/guide/overview)
+- [RxJS 操作符参考](https://rxjs.dev/guide/operators)