forked from cotes2020/jekyll-theme-chirpy
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
developer
committed
Nov 9, 2024
1 parent
7707275
commit 2d6281f
Showing
7 changed files
with
1,625 additions
and
0 deletions.
There are no files selected for viewing
File renamed without changes.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
--- | ||
title: SPOOLing 模拟共享打印机 | ||
date: 2024-07-05 14:53:10 +0800 | ||
categories: [Study] # 目前有 Demo, Tutorial, Tech, Study | ||
tags: [操作系统] | ||
author: Zwei # 或 authors: [Zwei, another_author] | ||
description: "" | ||
image: | ||
path: https://testingcf.jsdelivr.net/gh/bestZwei/imgs@master/picgo/2549f2e7795a40158330ace02089a915.png | ||
permalink: '/w/spooling-printer' # 自定义永久链接 | ||
pin: false # 置顶文章 | ||
toc: true # 显示目录 | ||
comments: true # 允许评论 | ||
math: true # 启用数学公式 | ||
mermaid: true # 启用 Mermaid 图表 | ||
render_with_liquid: false # 禁用 Liquid 渲染 | ||
media_subpath: /blog/assets/ # 资源路径前缀 | ||
--- | ||
|
||
#### 什么是假脱机技术? | ||
|
||
**假脱机技术**(Spooling)是一种在多道程序环境下,将IO操作与CPU操作分离的技术。在打印系统中,多个打印任务可以同时提交到打印队列中,由假脱机技术对这些任务进行管理和调度,实现**打印机的共享**使用,**每个程序都认为自己独占了打印机**。本课程设计旨在通过**Java可视化实现假脱机技术的共享打印机模拟**,让其他学习者直观地了解假脱机技术的工作原理和优势。 | ||
|
||
![4f27e3522f8536dd5ed3f.png](https://pics.sputnik.cloudns.ch/file/4f27e3522f8536dd5ed3f.png) | ||
|
||
### 1. 如何模拟? | ||
|
||
**下图展示了模拟过程(输出队列是输出井,假脱机管理器是管理程序)** | ||
|
||
**通过事件监听器,用来处理用户界面的各种交互操作,如提交任务和重置打印队列的按钮。** | ||
|
||
![5a534dbf34f8d1c4fb7cc.png](https://pics.sputnik.cloudns.ch/file/5a534dbf34f8d1c4fb7cc.png) | ||
|
||
我使用一个**优先级阻塞队列**来**模拟打印任务的排队**过程,它可以视作逻辑上**磁盘缓冲区里的输出井**。每个任务按照优先级和时间戳进行排序。用户通过可视化界面提交打印任务,系统将为每个任务分配一个唯一的编号(ID),并将其加入到队列中。打印机模拟为一个单线程执行服务 ExecutorService,每当空闲,依次从队列中取出任务进行打印。打印过程中,系统会显示当前打印任务的信息,以及等待队列中的任务列表。用户还可以通过界面重置打印队列,**清空输出井里的任务**。 | ||
|
||
在传统SPOOLing系统中,会为每个打印请求创建一个**请求表**,记录请求的详细信息。在这个模拟程序中,`PrintTask`类的实例实际上就扮演了打印请求表的角色,它包含了打印内容、优先级、唯一ID(相当于请求标识)等信息。通过`outputQueue`(等待打印的任务队列、输出井)来管理这些请求,模拟了将请求表挂到假脱机文件队列上的过程。 | ||
|
||
最终,通过为每个用户进程分配一个逻辑上的存储区,系统实现了对打印机的共享。每个用户都感觉到自己在独占打印机,实际上是系统在快速地为多个用户服务。 | ||
|
||
#### **数据结构说明** | ||
|
||
1.打印任务类(PrintTask) | ||
|
||
``` java | ||
static int idCounter = 0; | ||
// 静态变量,用于生成唯一的任务编号 (构造方法里 this.id = ++idCounter;) | ||
private int id; // 任务编号 | ||
private String content; // 打印内容 | ||
private int priority; // 任务优先级 | ||
private long timestamp; // 任务提交时间戳 | ||
|
||
public PrintTask(String content, int priority) { ... } | ||
|
||
// 构造方法及访问器方法... | ||
|
||
``` | ||
|
||
2. 打印假脱机模拟类(PrintSpoolerSim) | ||
|
||
```java | ||
public class PrintSpoolerSim extends JFrame { | ||
private PriorityBlockingQueue<PrintTask> outputQueue = new PriorityBlockingQueue<>(10, Comparator.comparingInt(PrintTask::getPriority).thenComparingLong(PrintTask::getTimestamp)); | ||
// ... | ||
} | ||
``` | ||
|
||
+ outputQueue:这是一个PriorityBlockingQueue类型的队列,用于存储等待打印的任务。它是一个优先级队列,根据任务的优先级和提交时间戳进行排序,确保高优先级的任务或先提交的任务能够优先得到处理。假设队列的大小被初始化为10,那么意味着最多可以同时存储10个任务。 | ||
|
||
|
||
|
||
**submitTask()** | ||
|
||
![9e5deab921b34d7a9b27b.png](https://pics.sputnik.cloudns.ch/file/9e5deab921b34d7a9b27b.png) | ||
|
||
**processTasks()** | ||
|
||
![5de874408cebd20f0114b.png](https://pics.sputnik.cloudns.ch/file/5de874408cebd20f0114b.png) | ||
|
||
**resetQueue()**![becfa62b21e73d687d410.png](https://pics.sputnik.cloudns.ch/file/becfa62b21e73d687d410.png) | ||
|
||
|
||
|
||
### 2. PriorityBlockingQueue 的使用和优先级处理 | ||
|
||
**我是如何实现任务的优先级处理的?** | ||
|
||
答:为了实现任务的优先级处理,我使用了 `PriorityBlockingQueue`。这个队列支持优先级排序,任务按照优先级和时间戳进行排序。我们在**创建队列时传入了一个比较器**,**先比较任务的优先级,如果优先级相同再比较时间戳**。这确保了即使在多线程环境下,高优先级的任务也能优先处理。 | ||
|
||
```java | ||
private PriorityBlockingQueue<PrintTask> outputQueue = new PriorityBlockingQueue<>(10, | ||
Comparator.comparingInt(PrintTask::getPriority).thenComparingLong(PrintTask::getTimestamp)); | ||
``` | ||
|
||
### 3. 线程安全和任务执行 | ||
|
||
**我的系统如何保证线程安全和任务的顺序执行?** | ||
|
||
答:为了保证线程安全和任务的顺序执行,我使用了 `ExecutorService`,具体来说是 `SingleThreadExecutor`。这个执行器确保了任务是按顺序执行的,每次只运行一个任务,这避免了并发执行可能带来的问题。 | ||
|
||
```java | ||
private ExecutorService printerService = Executors.newSingleThreadExecutor(); | ||
``` | ||
|
||
### 4. GUI实时更新机制 | ||
|
||
我使用了 `SwingUtilities.invokeLater` 方法。这个方法确保所有的界面更新操作都在事件调度线程上执行,这样可以避免线程冲突和界面冻结。例如,在添加任务或更新打印状态时,都使用了这种方法来确保界面的响应性和数据的一致性。 | ||
|
||
```java | ||
SwingUtilities.invokeLater(() -> { | ||
queueArea.append("任务提交: " + task.getContent() + ",优先级 " + task.getPriority() + ",任务编号 " + task.getId() + "\n"); | ||
updateWaitingQueueArea(); | ||
}); | ||
``` | ||
|
||
### 5. 异常处理和用户输入验证 | ||
|
||
在用户输入方面,我设置了输入验证来确保数据的有效性。例如,优先级必须是整数。如果用户输入无效,系统会通过对话框提示他们。运行过程中,我也添加了异常处理机制,比如在打印任务执行时捕获中断异常,以确保系统稳定运行并及时响应用户操作。 | ||
|
||
```java | ||
try { | ||
int priority = Integer.parseInt(priorityField.getText()); | ||
submitTask(content, priority); | ||
} catch (NumberFormatException e) { | ||
JOptionPane.showMessageDialog(this, "优先级必须是整数", "输入错误", JOptionPane.ERROR_MESSAGE); | ||
} | ||
``` | ||
|
||
### 6. 性能优化和未来改进方向 | ||
|
||
答:目前系统的性能能满足基本的使用需求,但在处理大量任务或高并发场景下可能会有性能瓶颈。未来,我打算引入更复杂的任务调度算法,比如基于预估打印时间的动态优先级调整。此外,为了适应多用户环境,我计划支持多台打印机并行处理任务,这可以通过配置多个线程池来实现。这样,系统的处理能力和效率将大大提高。 | ||
|
||
### 7. 代码展示、实际运行示例 | ||
|
||
**简单演示一下系统的实际运行情况** | ||
|
||
+ 启动程序后,用户在上方的输入框中输入打印内容和优先级,点击提交按钮。任务会被添加到队列中,并显示在队列区。 | ||
+ 随后,系统会自动开始打印任务,每个字符打印间隔两秒。 | ||
|
||
+ 在打印过程中,打印区会实时更新显示当前打印的内容。 | ||
|
||
+ 用户也可以点击重置按钮,清空所有任务,包括正在执行的任务。 | ||
|
||
演示输入: | ||
|
||
``` | ||
任务提交: 打印测试文本打印测试文本打印测试文本打印测试文本,优先级 1,任务编号 1 | ||
任务提交: 打印测试文本1,优先级 2,任务编号 2 | ||
任务提交: 打印测试文本2,优先级 2,任务编号 3 | ||
任务提交: 打印测试文本3,优先级 3,任务编号 4 | ||
任务提交: 打印测试文本4,优先级 1,任务编号 5 | ||
任务提交: 打印测试文本5,优先级 1,任务编号 6 | ||
任务提交: 打印测试文本6,优先级 2,任务编号 7 | ||
任务提交: 打印测试文本7,优先级 3,任务编号 8 | ||
任务提交: 打印测试文本8,优先级 4,任务编号 9 | ||
任务提交: 打印测试文本9,优先级 1,任务编号 10 | ||
任务提交: 打印测试文本10,优先级 1,任务编号 11 | ||
任务提交: 打印测试文本11,优先级 1,任务编号 12 | ||
任务提交: 打印测试文本12,优先级 3,任务编号 13 | ||
打印队列已重置 | ||
``` | ||
|
||
|
||
|
||
### **8. 参考文献** | ||
|
||
1. Java API 文档 https://docs.oracle.com/javase/8/docs/api/ | ||
|
||
2. 《Java 核心技术 卷 I 基础知识》(第十版)凯 S. 霍斯特曼 | ||
|
||
3. 《Java 并发编程实战》布莱恩·戈茨 | ||
|
||
4. 《计算机操作系统》汤小丹等 | ||
5. mermaid 介绍文档,用于生成流程图 https://mermaid.js.org/intro/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
--- | ||
title: Git多账号配置 | ||
date: 2024-07-23 15:12:10 +0800 | ||
categories: [Tutorial] # 目前有 Demo, Tutorial, Tech, Study | ||
tags: [Git] | ||
author: Zwei # 或 authors: [Zwei, another_author] | ||
description: "Windows设备管理多个git账号" | ||
image: | ||
path: https://testingcf.jsdelivr.net/gh/bestZwei/imgs@master/picgo/3a9282f87f892c286c9a9ccebe9c95dd_1679484529_216.png | ||
permalink: '/w/Git-Multi-Account-Configuration' # 自定义永久链接 | ||
pin: false # 置顶文章 | ||
toc: true # 显示目录 | ||
comments: true # 允许评论 | ||
math: true # 启用数学公式 | ||
mermaid: true # 启用 Mermaid 图表 | ||
render_with_liquid: false # 禁用 Liquid 渲染 | ||
media_subpath: /blog/assets/ # 资源路径前缀 | ||
--- | ||
|
||
|
||
# Git 多账号配置 | ||
|
||
在日常开发中,我们可能会遇到这样的情况:一台电脑上既需要管理多个的Git账号以处理不同的项目代码,或者跨平台登录Git存储库。如果每次提交或拉取代码时都临时修改配置,不仅操作繁琐,而且容易出错。本文将记录一次性配置的方法,实现多账号管理。 | ||
|
||
|
||
|
||
## 环境 | ||
|
||
- 操作系统:Windows | ||
|
||
- 项目目录A:`D:/account1/` | ||
|
||
- 项目目录B:`D:/account2/` | ||
|
||
|
||
|
||
## 配置步骤 | ||
|
||
### 1. 修改全局Git配置文件 | ||
|
||
首先,打开全局Git配置文件`C:/Users/用户名/.gitconfig`,原始配置可能只设置了某一个Git用户名和邮箱: | ||
|
||
```bash | ||
[user] | ||
name = 用户名 | ||
email = 邮箱 | ||
``` | ||
|
||
将上面的内容删去,修改为条件引入配置: | ||
|
||
```bash | ||
[includeIf "gitdir:D:/work/"] | ||
path = .gitconfig-account1 | ||
[includeIf "gitdir:D:/personal/"] | ||
path = .gitconfig-account2 | ||
``` | ||
|
||
### 2. 创建多个的Git配置文件 | ||
|
||
在用户目录下新建两个(或更多)文件,分别用于存放两个(或更多)和邮箱配置: | ||
|
||
#### `C:/Users/用户名/.gitconfig-account1` | ||
|
||
```bash | ||
[user] | ||
name = 用户名A | ||
email = 邮箱A #选填 | ||
``` | ||
|
||
#### `C:/Users/用户名/.gitconfig-account2` | ||
|
||
```bash | ||
[user] | ||
name = 用户名B | ||
email = 邮箱B #选填 | ||
``` | ||
|
||
### 3. 生成SSH密钥 | ||
|
||
运行以下命令分别生成账号A和账号B的SSH密钥。`-f`参数可以指定生成的文件名,`account1_id_rsa`是账号A的,`account2_id_rsa`是账号B的。 | ||
|
||
```bash | ||
# 第一个账号的 SSH | ||
ssh-keygen -f c:/Users/用户名/.ssh/gitlab_id_rsa -t rsa -C name1 | ||
|
||
# 第二个账号的 SSH | ||
ssh-keygen -f c:/Users/用户名/.ssh/github_id_rsa -t rsa -C name2 | ||
``` | ||
|
||
完成后会得到以下文件: | ||
|
||
- `account1_id_rsa` 和 `account1_id_rsa.pub` | ||
- `account2_id_rsa` 和 `account2_id_rsa.pub` | ||
|
||
将`account1_id_rsa.pub`和`account2_id_rsa.pub`的内容分别复制到GitLab、GitHub或其他Git存储库对应的SSH设置页面。 | ||
|
||
### 4. 配置SSH | ||
|
||
新建`C:/Users/用户名/.ssh/config`文件,内容如下: | ||
|
||
```bash | ||
Host github-account1 | ||
HostName github.com #此处填你使用的Git存储库的域名 | ||
User git | ||
IdentityFile C:\\Users\\用户名\\.ssh\\account1_id_rsa | ||
PreferredAuthentications publickey | ||
|
||
Host github-account2 | ||
HostName gitlab.com #此处填你使用的Git存储库的域名 | ||
User git | ||
IdentityFile C:\\Users\\用户名\\.ssh\\account2_id_rsa | ||
PreferredAuthentications publickey | ||
|
||
``` | ||
|
||
至此,Git多账号管理配置完成。现在,您可以在`D:/account1/`和`D:/account2/`目录下,无需每次手动切换配置。 | ||
|
||
|
||
|
||
[参考文献](https://nikolausliu.github.io/2021-04-09/git%E5%A4%9A%E8%B4%A6%E5%8F%B7%E7%AE%A1%E7%90%86.html) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
--- | ||
title: 基于 Deeplx 的翻译网页 | ||
date: 2024-07-31 21:03:12 +0800 | ||
categories: [Tutorial] # 目前有 Demo, Tutorial, Tech, Study | ||
tags: [Cloudlfare, Deeplx, translate] | ||
author: Zwei # 或 authors: [Zwei, another_author] | ||
description: "LibreTranslator" | ||
image: | ||
path: https://pics.sputnik.cloudns.ch/file/bf4c270e2bfb23cc6a07e.png | ||
permalink: '/w/deeplx-web' # 自定义永久链接 | ||
pin: false # 置顶文章 | ||
toc: true # 显示目录 | ||
comments: true # 允许评论 | ||
math: true # 启用数学公式 | ||
mermaid: true # 启用 Mermaid 图表 | ||
render_with_liquid: false # 禁用 Liquid 渲染 | ||
media_subpath: /blog/assets/ # 资源路径前缀 | ||
--- | ||
|
||
#### 项目地址:https://github.com/bestZwei/LibreTranslator | ||
|
||
#### 效果展示:https://fy.is-a.dev | ||
|
||
### 部署 | ||
|
||
#### 1、使用 Cloudflare Pages 部署 | ||
|
||
1. Fork 本仓库。 | ||
2. 登录到 [Cloudflare](https://www.cloudflare.com/) ,在 Cloudflare Dashboard 中,选择 "Pages"。 | ||
3. 点击 "Create a Project"。 | ||
4. 连接到您的 GitHub 存储库,并选择该项目。 | ||
5. 在 "Configure your build" 步骤中,使用以下设置: | ||
- **Framework preset**: | ||
- **Build command**: `npm run build` | ||
- **Build directory**: `build` | ||
6. 点击 "Save and Deploy"。 | ||
|
||
#### 2、使用 Vercel 部署 | ||
|
||
1. Fork 本仓库。 | ||
2. 登录到 Vercel,点击 "New Project"。 | ||
3. 连接到您的 GitHub 存储库,并选择该项目。 | ||
4. Vercel 会自动检测到您使用的是 React 项目。您可以使用默认设置。 | ||
5. 点击 "Deploy"。 | ||
|
||
#### 所有部署方式都要配置环境变量 | ||
|
||
1. **REACT_APP_DEEPLX_API_URL**: `https://api.deeplx.org/<api-key>` ,不带 `/translate` | ||
|
||
用于存储 DeepLx API 的 URL,以便在请求翻译时使用。`<api-key> `可以从 https://connect.linux.do/ 获取。 | ||
|
||
或者你是Pro用户,参考 [DeepLx文档 ](https://deeplx.owo.network/endpoints/pro.html)使用 `/v1` 请求 ,`https://api.deeplx.org/v1` | ||
|
||
2. **REACT_APP_PASSWORD(可选)**: 访问密码 | ||
|
||
用于存储访问口令,限制其他人使用你部署的翻译网页。 | ||
|
||
3. **NODE_OPTIONS**:`--openssl-legacy-provider` | ||
|
||
这个变量用于配置 Node.js 的选项,通常用于解决某些依赖包的兼容性问题,不设置则可能部署失败。 | ||
|
||
4. **REACT_APP_API_TOKEN(可选)**:按需修改,如果你是**自建的DeepLx服务**,参考请求链接是 `REACT_APP_DEEPLX_API_URL/translate?token=REACT_APP_API_TOKEN`,填写这两个环境变量。 |
Oops, something went wrong.