🎀大更新:webp、valine、gulp

This commit is contained in:
DefectingCat
2020-10-30 11:22:33 +08:00
parent 0c5f25181f
commit 5d1b8836f9
284 changed files with 1387 additions and 13336 deletions

View File

@ -24,7 +24,7 @@ jobs:
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm -v
- run: apt install yarn -y
- name: setup hexo env
env:
@ -46,6 +46,4 @@ jobs:
- name: deploy
run: |
# publish
hexo cl
hexo g
hexo d
yarn go

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"compile-hero.disable-compile-files-on-did-save-code": false
}

12
Dockerfile Normal file
View File

@ -0,0 +1,12 @@
FROM node:15.0.1-alpine as builder
WORKDIR /root
COPY ./ ./
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
&& apk update \
&& apk upgrade \
&& apk add --no-cache yarn \
&& yarn \
&& yarn run go
FROM nginx:alpine
COPY --from=builder /root/public/ /usr/share/nginx/html

33
Gulpfile.js Normal file
View File

@ -0,0 +1,33 @@
const { series, parallel } = require('gulp');
const { src, dest } = require('gulp');
const cleanCSS = require('gulp-clean-css');
const htmlmin = require('gulp-htmlmin');
const uglify = require('gulp-uglify-es').default;
const htmlclean = require('gulp-htmlclean');
function html() {
return src('./public/**/*.html')
.pipe(htmlclean())
.pipe(htmlmin({
collapseWhitespace: true,
removeComments: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true
}))
.pipe(dest('./public'))
};
function css() {
return src('./public/**/*.css')
.pipe(cleanCSS())
.pipe(dest('./public'))
};
function js() {
return src('public/**/*.js')
.pipe(uglify())
.pipe(dest('./public'))
}
exports.default = parallel(html, css, js);

File diff suppressed because it is too large Load Diff

9777
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,9 @@
"build": "hexo generate",
"clean": "hexo clean",
"deploy": "hexo deploy",
"server": "hexo server"
"server": "hexo server",
"dev": "hexo cl && hexo g && gulp",
"go": "hexo cl && hexo g && gulp && hexo d"
},
"hexo": {
"version": "5.2.0"
@ -14,14 +16,11 @@
"dependencies": {
"babel": "^6.23.0",
"gulp": "^4.0.2",
"gulp-babel": "^8.0.0",
"gulp-clean-css": "^4.3.0",
"gulp-eslint": "^6.0.0",
"gulp-htmlclean": "^2.7.22",
"gulp-htmlmin": "^5.0.1",
"gulp-imagemin": "^7.1.0",
"gulp-shell": "^0.8.0",
"gulp-uglify": "^3.0.2",
"gulp-uglify-es": "^2.0.0",
"hexo": "^5.2.0",
"hexo-cli": "^4.2.0",
"hexo-deployer-git": "^2.1.0",
@ -35,8 +34,7 @@
"hexo-renderer-marked": "^3.3.0",
"hexo-renderer-stylus": "^2.0.1",
"hexo-server": "^2.0.0",
"hexo-theme-fluid": "^1.8.4",
"mozjpeg": "^7.0.0"
"hexo-theme-fluid": "^1.8.4"
},
"devDependencies": {
"@babel/core": "^7.12.3",

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?><XnView_script version="1.0" name="添加水印">
<Watermark filename="C:/Users/Defectink/OneDrive/Pictures/Logo/文字logo标题.png" opacity="85" no_alpha="false" position="8" delta_x="-25" delta_y="-25" perc="15" size="3"/>
<Output folder="" filename="{Filename}" case="0" startIndex="1" format="WEBP">
<Options overwrite="1" orgDate="false" keepMeta="false" keepICC="false" keepFolder="false" keepParentFolder="false" keepExtension="true" delOrg="true" multipage="false" allPages="false" openExplorer="false" openBrowser="false" clearItems="false"/>
<WEBP method="0" quality="75" filesize="128" compress="4" strength="60" sharpness="0" preset="0"/>
</Output>
</XnView_script>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?><XnView_script version="1.0" name="转换webp">
<Output folder="" filename="{Filename}" case="0" startIndex="1" format="WEBP">
<Options overwrite="1" orgDate="false" keepMeta="false" keepICC="false" keepFolder="false" keepParentFolder="false" keepExtension="true" delOrg="true" multipage="false" allPages="false" openExplorer="false" openBrowser="false" clearItems="false"/>
<WEBP method="0" quality="75" filesize="128" compress="4" strength="60" sharpness="0" preset="0"/>
</Output>
</XnView_script>

View File

@ -1,81 +0,0 @@
---
title: ES6解构赋值
index_img: /images/
date: 2020-08-30 16:50:30
tags:
categories:
url:
---
解构赋值是一种JavaScript的语法表达式通过解构赋值可以将属性/值从对象/数组等中提取出来,赋值给其他变量。
基本规则:
1. 数组的元素是按次序排列的,变量的取值由它的位置决定;
2. 对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
解构赋值采用和字面量类似的表达式,不同的是在表达式左边定义了要从原变量中提取出什么变量。
## 语法
```js
var a, b, rest;
[a, b] = [10, 20];
console.log(a); // 10
console.log(b); // 20
[a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(a); // 10
console.log(b); // 20
console.log(rest); // [30, 40, 50]
({ a, b } = { a: 10, b: 20 });
console.log(a); // 10
console.log(b); // 20
// Stage 4已完成提案中的特性
({a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40});
console.log(a); // 10
console.log(b); // 20
console.log(rest); // {c: 30, d: 40}
```
```js
var x = [1, 2, 3, 4, 5];
var [y, z] = x;
console.log(y); // 1
console.log(z); // 2
```
## 数组
数组的解构赋值是按顺序排列的,变量的取值由他的位置决定。先来几个简单的例子:
```js
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
let [a, b, c, d] = arr;
console.log(a, b, c, d); // 1, 2, 3, 4
```
与一般的字面量赋值不同,解构赋值数组是将等式由边的数组按顺序赋值给左边的变量。
### 默认值
当然等式的左右两边长度可能不一样没有获取到值的变量会被声明为undefined就和只声明不赋值变量一样。
不过解构赋值还可以为其赋予一个默认值,这样变量在为获取到值的情况下就会被赋予到默认的值。
```js
let [a = 123, b = 123] = [1];
// a: 1;
// b: 123;
```
```
[结构赋值|MDN](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)
```

View File

@ -0,0 +1,69 @@
为了深入了解同步与异步编程,和充分理解这一理念。打算详细的了解与对比这两种编程模式。
## Node编程风格
随便搜寻几篇Node.js的文章便会发现node主要的编程风格便是使用非阻塞异步编码风格。先通过一个日常的举例来了解下阻塞同步编码与非阻塞异步编码之间的差异。
## 同步与异步的对比 场景一
Node.js 官网关于阻塞式 I/O 的定义如下:
> “阻塞表示 Node.js 进程中其他 JavaScript 的执行必须等到非 JavaScript 操作完成后才能继续的情况。发生这种情况的原因在于,当发生阻塞操作时,事件循环无法继续运行 JavaScript。
> 在 Node.js 中,由于 CPU 占用率高而不是等待非 JavaScript 操作(如 I/O导致性能欠佳的 JavaScript 通常并不被称为阻塞。”
### 同步
普通的同步风格程序。它在 V8 线程上自上而下运行,仅占用少量 CPU这是非技术层面的阻塞。
```js
'use strict'
console.log(Date.now().toString() + ': 主进程开始;');
console.log(Date.now().toString() + ': 创造一个延迟;');
let start = Date.now();
let end = start;
while(end < start + 20) {
end = Date.now(); // 阻塞延迟
}
console.log(Date.now().toString() + ': 主进程结束;');
```
这里使用了`while`通过不断的检查系统时间来创建一个阻塞的延迟动作根据最后打印的时间戳总共运行时间在21~23毫秒之间。
### 异步
使用异步的方式创建了与上述同样效果的实例。
```js
'use strict'
console.log(Date.now().toString() + ': 主进程开始;');
setTimeout(() => {
console.log(Date.now().toString() + ': 事件循环回调');
}, 20);
console.log(Date.now().toString() + ': 主进程结束;');
```
这里的异步使用了`setTimeout`来将事件超时运行。根据最后打印的时间戳总共运行时间在25~30毫秒之间。
## 场景一小结
经过上述的小实验,不难发现同步的运行时间比异步还短那么几毫秒。异步反而更慢,异步编程风格并不关乎单纯的速度,而是关乎可扩展性。
## 模块系统
模块化是现代软件开发中的一个关键概念。它使我们能够构建更健壮的代码,并在多处复用代码,而无需重复编写相同的代码。
Node 模块化不仅为我们提供了上述所有好处,还提供了:
* 自动封装。默认情况下,一个模块中的所有代码都被打包到函数包装程序中,以便对模块外部的其他 JavaScript 代码隐藏。
* 一种公开模块接口的方式。模块中的函数、变量和其他构造必须通过 module.exports或者其简短表示exports对模块外部的 JavaScript 模块显式公开。
### 引入模块
在ES6发布后module成为标准。曾经的我们采用的是CommonJS规范使用`require()`来引入模块。目前的ES6标准使用`import`来引入模块。
```js
let fs = require('fs');
import fs from 'fs';
```

View File

@ -4,7 +4,7 @@ date: 2019-06-29 12:12:41
tags: Tools
categories: 实践
url: online-ascii-video
index_img: /images/ASCII在线视频流/logo.jpg
index_img: /images/ASCII在线视频流/logo.webp
---
什么是ASCII
@ -18,7 +18,7 @@ ASCIIAmerican Standard Code for Information Interchange美国信息交换
这是来自某位大佬胡乱起的名字。🤣
![图像-1](../images/ASCII在线视频流/图像-1.png)
![图像-1](../images/ASCII在线视频流/图像-1.webp)
## 那么如何安装呢?
@ -59,7 +59,7 @@ ffmpeg -i demo.mp4 -r 5 -ss 00:01:13 -t 00:00:15 %03d.png
将demo视频的第1分13秒后的15秒以每秒5帧的速度保存为图像图像名格式为001.png 002.png ……
效果如下:
![图像-2](../images/ASCII在线视频流/图像-2.png)
![图像-2](../images/ASCII在线视频流/图像-2.webp)
```bash
➜ ~ ls time

View File

@ -4,7 +4,7 @@ date: 2019-06-26 16:42:41
tags: typecho
categories: 踩坑
url: alioss-for-typecho
index_img: /images/AliOssForTypecho/logo.jpg
index_img: /images/AliOssForTypecho/logo.webp
---
原作大佬:

View File

@ -1,6 +1,6 @@
---
title: Can't install gifsicle
index_img: /images/Can't%20install%20gifsicle/index.png
index_img: /images/Can't%20install%20gifsicle/index.webp
date: 2020-08-04 14:03:00
tags: network
categories: 踩坑
@ -71,7 +71,7 @@ The `Command failed` just write some ips for hosts, then `npm install` will be w
So,
![批注 2020-08-04 135700](../images/Can't%20install%20gifsicle/批注%202020-08-04%20135700.jpg)
![批注 2020-08-04 135700](../images/Can't%20install%20gifsicle/批注%202020-08-04%20135700.webp)

View File

@ -4,7 +4,7 @@ date: 2019-12-19 11:11:33
tags: Linux
categories: 实践
url: docker-container-all
index_img: /images/Docker全面容器化/logo.png
index_img: /images/Docker全面容器化/logo.webp
---
自上篇[Docker - 构建属于自己的镜像](https://www.defectink.com/defect/docker-build-own-images.html)以来发现Docker非常的有意思。主要是非常的方便并且在可以跨平台的情况下部署环境对于以后迁移也是一件极其有利的事。研究了Dockerfile的编写以及实践。一些基础的实践之后对于Docker的工作方式以及操作命令都有了一些熟悉。也逐渐了发现了它的一些优点。
@ -72,7 +72,7 @@ apache与php-fpm通信借助Docker的网络实现内部的通信。
在Docker hub中的[httpd](https://hub.docker.com/_/httpd)当前支持的tag
![image-20191221185631177](../images/Docker全面容器化/image-20191221185631177.png)
![image-20191221185631177](../images/Docker全面容器化/image-20191221185631177.webp)
整个Dockerfile

View File

@ -4,7 +4,7 @@ date: 2019-11-29 09:30:33
tags: Linux
categories: 实践
url: docker-build-own-image
index_img: /images/Docker-构建属于自己的镜像/logo.png
index_img: /images/Docker-构建属于自己的镜像/logo.webp
---
以前一直在使用别人构建好的镜像来使用Docker容器在一次想搭建一个完整的Web环境时发现使用过多容器非常难以管理。并且容器之间的交互通信变的困难。当然也可以使用Docker Compose来捆绑多个镜像运行不过对于运行服务较少的来说使用Dockerfile来构建成一个镜像也是件好事。

View File

@ -4,7 +4,7 @@ date: 2019-06-19 15:42:41
tags: Linux
categories: 实践
url: try-the-gitlab
index_img: /images/Gitlab尝鲜/52152339.png
index_img: /images/Gitlab尝鲜/52152339.webp
---
## Gitlab?
@ -17,7 +17,7 @@ index_img: /images/Gitlab尝鲜/52152339.png
最早,它是完全免费的开源软件,按照 MIT 许可证分发。毕竟人家是公司后来Gitlab被拆分成GitLab CE社区版和 GitLab EE企业版。和如今的模式一样ce是完全免费使用的社区版而ee是可以进行试用且更多功能的收费版。
![52152339](../images/Gitlab尝鲜/52152339.png)
![52152339](../images/Gitlab尝鲜/52152339.webp)
## 安装部署
@ -25,7 +25,7 @@ index_img: /images/Gitlab尝鲜/52152339.png
我当前是部署在Ubuntu上的系统信息
![411390967](../images/Gitlab尝鲜/411390967.png)
![411390967](../images/Gitlab尝鲜/411390967.webp)
官方是推荐系统空闲内存在4GB以上的对于类似我们这样的个人使用的较少的来说推荐空闲内存是2GB以上。毕竟它会自己运行一套nginx、redis等服务端。
@ -71,7 +71,7 @@ sudo EXTERNAL_URL="https://gitlab.example.com" apt-get install gitlab-ce
## 使用
![99634888](../images/Gitlab尝鲜/99634888.png)
![99634888](../images/Gitlab尝鲜/99634888.webp)
简洁多彩的界面也时非常的好看的。默认没有配置邮件的情况下是可以随意注册的我们也可以在后台配置里关闭自动注册作为一个私人的git仓库。也可以手动添加用户给想尝鲜的小伙伴们。

View File

@ -4,7 +4,7 @@ date: 2019-12-18 16:42:53
tags: HTML
categories: 实践
url: header-practice-have-to-win-this-a
index_img: /images/Header实践-得拿下这个A/header-security.png
index_img: /images/Header实践-得拿下这个A/header-security.webp
---
[Header安全检测](https://securityheaders.com/)
@ -192,13 +192,13 @@ Feature-Policy: <directive> <allowlist>
## 测试
![image-20191218171928050](../images/Header实践-得拿下这个A/image-20191218171928050.png)
![image-20191218171928050](../images/Header实践-得拿下这个A/image-20191218171928050.webp)
### 为什么没有A+
因为CSP的一个报错拒绝加载内联的JS脚本。可以使用`unsafe-inline`来启用内联脚本。但是启用了`unsafe-inline`之后就得不到A+了。
![image-20191218172218399](../images/Header实践-得拿下这个A/image-20191218172218399.png)
![image-20191218172218399](../images/Header实践-得拿下这个A/image-20191218172218399.webp)
```
Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-eval' https://maxcdn.bootstrapcdn.com https://ajax.googleapis.com https://cdn.defectink.com". Either the 'unsafe-inline' keyword

View File

@ -1,6 +1,6 @@
---
title: Hexo and Github
index_img: /images/Hexo-and-Github/index.png
index_img: /images/Hexo-and-Github/index.webp
date: 2017-09-14 22:06:12
tags: [Linux, HTML]
categories: 实践
@ -21,9 +21,9 @@ url: hexo-and-github
在个人资料页面选择仓库Repositories并单击New来创建一个新的仓库
![profile](../images/Hexo-and-Github/profile.png)
![profile](../images/Hexo-and-Github/profile.webp)
![repository](../images/Hexo-and-Github/repository.png)
![repository](../images/Hexo-and-Github/repository.webp)
• Repository name仓库名称需要使用格式为"Your_github_name.github.io"。Your_github_name一定要为你的github昵称否则出现404状况
• Description仓库描述选填
@ -34,7 +34,7 @@ url: hexo-and-github
随后便能看到自己刚刚创建的仓库了下图为未创建一个README文件来初始化仓库
![create](../images/Hexo-and-Github/create.png)
![create](../images/Hexo-and-Github/create.webp)
## 关联Github
@ -99,11 +99,11 @@ npm install hexo-deployer-git --save
查看刚刚所部署的仓库
![ggg](../images/Hexo-and-Github/ggg.png)
![ggg](../images/Hexo-and-Github/ggg.webp)
访问域名测试
![web](../images/Hexo-and-Github/web.png)
![web](../images/Hexo-and-Github/web.webp)
到此就成功部署到Github并运行成功了呢。

View File

@ -0,0 +1,414 @@
---
title: JavaScript-可迭代对象与for-of
date: 2020-10-29 17:15:48
tags: JavaScript
categories: 笔记
url: javascript-iterable-object-and-for-of
index_img: /images/JavaScript-可迭代对象与for-of/logo.webp
---
## Iterable object可迭代对象
可迭代Iterable 对象是数组的泛化。这个概念是说任何对象都可以被定制为可在`for...of`循环中使用的对象。数组是可迭代的。但不仅仅是数组,很多其他的内建对象也是可迭代的。例如字符串就是可迭代的。
## 总最早开始
可能十年前或者更加久远的年代,我们遍历一个数组需要这样:
```js
let arr = [1, 2, 3, 4, 5];
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
```
或许也不是很久在我最初学习js的时候就是这样去尝试理解for循环的。
后来我们发现这样写或许太复杂了,于是有了`for...in`。我们遍历一个数组就变成了这样:
```js
for (let i in arr) {
console.log(arr[i]);
}
```
是不是和for循环有点类似`for...in`便是循环遍历对象的一个方式。
ES6也给了我们一个专门操作遍历数组的方法`forEach()`
```js
arr.forEach(element => {
console.log(element);
});
```
与其他的方法不同的是,`forEach()`同数组的`push()``pop()`等方法一样是在Array对象的原型上的也就是`Array.prototype.forEach()`。并且它除了抛出异常以外,没有办法中止或跳出`forEach()`循环。如果我们需要中止或跳出循环`forEach()`方法不是应当使用的工具。
### 弥补不足
我们有多种可以轻松遍历数组的方法,不过他们各有各的不足之处。`for...of`便是代替`for...in`来循环数组而诞生的。
首先来看看`for...in`对数组的小问题:
1. `for...in`是为对象设计的它遍历的是key而不是value。
2. `for...in`会一直查找可枚举的属性,直至原型链顶端。
先看第一条,`for...in`和直接for循环遍历数组类似他们循环的是数组的key需要使用数组的标准访问写法才能得到值。
```js
let arr = [1, 2, 3, 4, 5];
for (let i in arr) {
console.log(arr[i]);
// 1, 2, 3, ,4, 5
}
for (let i in arr) {
console.log(i);
// 0, 1, 2, 3, ,4
}
```
不过这看上去无伤大雅,第二条的问题就不像这么温柔了。在当前数组的原型链上的所有的可枚举的属性都会被遍历出来。
```js
Array.prototype.arrTest = function test() {};
Object.defineProperty(Array.prototype, 'push', {
enumerable: true
})
let arr = [1, 2, 3, 4, 5];
for (let i in arr) {
console.log(arr[i]);
}
```
无论是我们自定义的函数,还是修改属性为可枚举,`for...in`一条都不会放过。
![](../images/JavaScript-可迭代对象与for-of/2020-10-27-15-01-39.webp)
## 迭代协议
通常的对象是不可迭代的,它不是数组。通过自己创建一个不可迭代的对象,我们就可以轻松地掌握可迭代的概念。
首先来看一个最基本的对象,我们尝试使用`for...of`去遍历它,会得到一个其不是可迭代对象的是错误:
```js
let obj = {
start: 1,
end: 5
};
for (num of obj) {
console.log(num);
}
```
```
VM155:6 Uncaught TypeError: obj is not iterable
```
这是因为我们的Object对象不是可迭代的对象。而迭代协议可以使其成为一个可迭代的对象。
迭代协议作为 ECMAScript 2015 的一组补充规范,迭代协议并不是新的内置实现或语法,而是协议。这些协议可以被任何遵循某些约定的对象来实现。
### 迭代器
为了让`obj`对象可迭代(也就让`for..of`可以运行)我们需要为对象添加一个名为`Symbol.iterator`的方法一个专门用于使对象可迭代的内置symbol
1.`for..of` 循环启动时,它会调用这个方法(如果没找到,就会报错)。这个方法必须返回一个 **迭代器iterator** —— 一个有 `next` 方法的对象。
2. 从此开始,`for..of` **仅适用于这个被返回的对象**
3.`for..of` 循环希望取得下一个数值,它就调用这个对象的 `next()` 方法。
4. `next()` 方法返回的结果的格式必须是 `{done: Boolean, value: any}`,当 `done=true` 时,表示迭代结束,否则 `value` 是下一个值。
```js
let obj = {
start: 1,
end: 5
};
// for..of 调用首先会调用这个:
obj[Symbol.iterator] = function () {
return {
// 这个function还是属于obj所以this指向obj。
//接下来for..of 仅与此迭代器一起工作,要求它提供下一个值
current: this.start,
last: this.end,
// next() 在 for..of 的每一轮循环迭代中被调用
// 所以通常next都带有一个判断语句
next() {
// Symbol.iterator返回的是一个对象this不会多级指向所以这里用到了刚刚定义的属性
if (this.current <= this.last) {
return {
value: this.current++,
done: false
}
} else {
return {
done: true
}
}
}
}
};
// 可以迭代啦
for (let num of obj) {
console.log(num);
};
```
第一次见到迭代器的时候感觉它还是挺复杂的但仔细研究过后就会发现其实它大部分还都是固定搭配的。不过这里的this还是比较容易浑人的。
仔细观察下其核心的功能,发现迭代器是通过一个名为`Symbol.iterator`的方法返回的对象中的:
1. `obj` 自身没有 `next()` 方法。
2. 相反,是通过调用 `obj[Symbol.iterator]()` 创建了另一个对象,即所谓的“迭代器”对象,并且它的 `next` 会为迭代生成值
那么,既然都是对象,所以迭代器应该是可以放在`obj`自身的。
```js
let obj = {
start: 1,
end: 5,
// Symbol.iterator负责返回一个对象其对象中包含next方法这里直接返回this在obj中定义一个next方法
// this.count用于计数
[Symbol.iterator]() {
this.count = this.start;
return this;
},
next() {
if (this.count <= this.end) {
return {
value: this.count++,
done: false
}
} else {
return {
done: true
}
}
}
};
for (let num of obj) {
console.log(num);
};
```
这里的`[Symbol.iterator]()`定义为`obj`的一个属性,同时`[Symbol.iterator]()`需要返回一个带有`next()`方法的对象。所以直接将`next()`方法定义在`obj`身上,`[Symbol.iterator]()`通过返回this来返回这个对象。
这样的写法会比在外部定义`[Symbol.iterator]()`方法更加简洁this指向也更加清晰。但是在`[Symbol.iterator]()`方法中定义的属性会被添加到`obj`上。
```js
obj.count // 6
```
并且迭代器只用一个,现在不能在该对象上同时运行多个`for...of`循环了,它们将共享迭代状态,因为只有一个迭代器,即对象本身。但是两个并行的 for..of 是很罕见的,即使在异步情况下。
> 无穷迭代器
> 无穷迭代器也是可能的。例如,将`obj`设置为`obj.to = Infinity`,这时`obj`则成为了无穷迭代器。或者我们可以创建一个可迭代对象,它生成一个无穷伪随机数序列。也是可能的。
> `next`没有什么限制,它可以返回越来越多的值,这是正常的。
> 当然,迭代这种对象的`for..of`循环将不会停止。但是我们可以通过使用`break`来停止它。
### 展开语法
展开语法(Spread syntax), 可以在函数调用/数组构造时, 将数组表达式或者string在语法层面展开还可以在构造字面量对象时, 将对象表达式按key-value的方式展开。
字面量也就是常见的`[1, 2, 3]`或者`{name: "mdn"}`这种简洁的构造方式。
展开语法与`for...of`及其相似,无法迭代的对象也无法使用展开语法。错误信息也是一样:
![](../images/JavaScript-可迭代对象与for-of/2020-10-29-10-17-49.webp)
展开语法不仅仅只是和`for...of`行为比较像,它还有更多的用法。不过在此赘述也是没有多少意义了。
## 可迭代的字符串
在我最早学习js的基本类型的时候就被告知字符串可以被循环处理。类似于这样
```js
let str = 'xfy';
for (let i = 0; i < str.length; i++) {
console.log(str[i]);
}
// x, f, y;
```
虽然无法理解是什么一回事,但当时就感觉字符串和数组很相似,非常神奇。
根据包装对象的原理,很容易就联想到字符串可迭代是因为其构造函数`String`可迭代当然也有length属性。要验证这非常简单只需要找下`String`上有没有迭代器必备的`[Symbol.iterator]()`方法就可以了。
虽然包装对象的过程我们无法看到但是我们可以对一个字符串的原型链向上寻找就ok了。直接调用其原型链上的方法便会触发包装对象就像调用`toString()`一样,
```js
let str = 'xfy';
str.__proto__[Symbol.iterator];
```
直接访问原型链上的`[Symbol.iterator]()`方法,就会发现有这个方法存在,正是有它的存在,字符串才是可迭代的。
### 显式调用迭代器
为了能够更加深入的了解迭代器的工作,我们可以不使用`for...of`,反而使用显式的去操作迭代器:
```js
let str = 'xfy';
// 接收迭代器
let iterator = str[Symbol.iterator]();
let res;
while(true) {
res = iterator.next();
if (res.done) break;
console.log(res.value);
}
```
只要弄弄清楚了迭代器的工作方式,就能很轻松的理解显式调用。最终我们根据`next()`方法返回的固定格式的值来判断什么适合需要跳出循环以及取值。
正常情况下我们不需要显式的去迭代一个对象,但是这样做比`for...of`给了我们更多的控制权。我们可以拆分迭代的步骤,并在中途做一些其他的事情。
## 可迭代与类数组
可迭代对象与类数组很相似,但他们是两种不同的对象,有着不同的正式术语:
- **Iterable** 如上所述,是实现了 `Symbol.iterator` 方法的对象。
- **Array-like** 是有索引和 `length` 属性的对象,所以它们看起来很像数组。
当然也有两种特性都有的对象,例如字符串就是可迭代同时也是类数组(有数值索引和 `length` 属性)。
当光是类数组的对象是无法迭代的
```js
let obj = {
0: 'x',
1: 'f',
2: 'y',
length: 3
}
// Uncaught TypeError: object is not iterable
[...obj];
```
可迭代对象和类数组对象通常都**不是数组**,他们也没有数组的一些方法。不过出了字符串以外,我们手动创建的类数组可以使用`call`来改变数组方法的指向,从而使其能够使用一些数组的方法:
```js
Array.prototype.push.call(obj, 1);
obj[3];
// 1
```
而包装后的字符串其`length`属性是只读的,所以我们无法通过数组的方法去操作它:
```js
let str = 'xfy';
// Uncaught TypeError: Cannot assign to read only
Array.prototype.push.call(str, 1);
```
### Array.from
`Array.from`可以从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。通过创建一个浅拷贝的数组,就可以对其使用数组的方法了。
```js
let obj = {
0: 'x',
1: 'f',
2: 'y',
length: 3
};
let arr = Array.from(obj);
arr.push('嘤嘤嘤');
```
Array.from 方法接受对象,检查它是一个可迭代对象或类数组对象,然后创建一个新数组,并将该对象的所有元素浅拷贝到这个新数组。可迭代的对象也是同理。
```js
let obj = {
0: 'x',
1: 'f',
[Symbol.iterator]() {
this.sw = true;
return this;
},
next() {
if (this.sw) {
this.sw = false;
return {
value: Object.keys(this),
done: false
}
} else {
return {
done: true
}
}
}
}
let arr = Array.from(obj);
```
`Array.from`还有一个可选的参数,提供了类似于`forEach`的参数选项。
```js
Array.from(obj[, mapFn, thisArg])
```
可选的第二个参数 `mapFn` 可以是一个函数,该函数会在对象中的元素被添加到数组前,被应用于每个元素,此外 `thisArg` 允许我们为该函数设置 `this`
```js
Array.from([1, 2, 3], x => x + x);
// [2, 4, 6]
```
### 可用于代理对
对于代理对surrogate pairs UTF-16 的扩展字符),`Array.from`也可以正常识别并拷贝为数组。对于普通的字符串,虽然能够使用`slice()`方法,但是对于代理对的操作会导致乱码,两个不同 UTF-16 扩展字符碎片拼接的结果。
```js
let str = '𝒳😂𩷶';
console.log(str);
// "𝒳😂𩷶"
str.slice(1,3)
// "<22><>"
```
我们可以利用`Array.from`对代理对的正确操作特性来重写创建代理感知surrogate-aware`slice`方法。
```js
let str = '𝒳😂𩷶';
function aSlice(arr, star, end) {
return Array.from(arr).slice(star, end).join('');
}
```
## 总结
可以应用 `for..of` 的对象被称为 **可迭代的**
- 技术上来说,可迭代对象必须实现 `Symbol.iterator`方法。
- `obj[Symbol.iterator]` 的结果被称为 **迭代器iterator**。由它处理进一步的迭代过程。
- 一个迭代器必须有 `next()` 方法,它返回一个 `{done: Boolean, value: any}` 对象,这里 `done:true` 表明迭代结束,否则 `value` 就是下一个值。
- `Symbol.iterator` 方法会被 `for..of` 自动调用,但我们也可以直接调用它。
- 展开语法的操作结果与`for..of`类似。
- 内置的可迭代对象例如字符串和数组,都实现了 `Symbol.iterator`
- 字符串迭代器能够识别代理对surrogate pair
有索引属性和 `length` 属性的对象被称为 **类数组对象**。这种对象可能还具有其他属性和方法,但是没有数组的内建方法。
## 参考&推荐
* [迭代协议](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Iteration_protocols)
* [迭代器和生成器](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Iterators_and_Generators)
* [yield*](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/yield*)
* [展开语法](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Spread_syntax)
* [Iterable object可迭代对象](https://zh.javascript.info/iterable)

View File

@ -4,7 +4,7 @@ date: 2020-07-03 15:13:05
tags: JavaScript
categories: 笔记
url: javascript-scope-and-chain
index_img: /images/JavaScript的作用域与链/index.jpg
index_img: /images/JavaScript的作用域与链/index.webp
---
JavaScript是一门动态语言也常称呼为弱类型/解释型的语言。除了不需要明确写出数据类型外JavaScript的作用域也和其他类型的语言不同。并且作用域还以链的方式互相连接。

View File

@ -1,6 +1,6 @@
---
title: JavaScript的函数
index_img: /images/JavaScript的函数/index.jpg
index_img: /images/JavaScript的函数/index.webp
date: 2020-08-07 11:26:10
tags: JavaScript
categories: 笔记

View File

@ -4,12 +4,12 @@ date: 2020-01-06 09:14:53
tags: JavaScript
categories: 笔记
url: javascript-notes-reference-type
index_img: /images/JavaScript笔记-引用类型/javascript.jpg
index_img: /images/JavaScript笔记-引用类型/javascript.webp
---
> 这是来自Professional JavaScript for Web Develops第五章的笔记。
![javascript](../images/JavaScript笔记-引用类型/javascript.jpg)
![javascript](../images/JavaScript笔记-引用类型/javascript.webp)
## 基本类型和引用类型

View File

@ -4,7 +4,7 @@ date: 2020-07-27 16:42:32
tags: JavaScript
categories: 笔记
url: javascript-object-oriented-programming
index_img: /images/JavaScript面向对象的程序设计/logo.png
index_img: /images/JavaScript面向对象的程序设计/logo.webp
---
> Standing on Shoulders of Giants.
@ -17,7 +17,7 @@ ECMAScript中没有类的概念所以它的对象也与基于类的语言中
ECMAScript-262的对象定义为“无序属性的集合其属性可以是基本值、对象和函数。”也就是说对象是一个没有属性的键值映射对其值可以是数据和函数。
![logo](../images/JavaScript面向对象的程序设计/logo.png)
![logo](../images/JavaScript面向对象的程序设计/logo.webp)
## 属性类型
@ -526,7 +526,7 @@ for-in循环会便利所有能访问、可枚举(enumerated)的属性。无论
这里的two实例重写了`toString()`方法可以被for-in循环遍历出来。
![image-20200726171729248](../images/JavaScript面向对象的程序设计/image-20200726171729248.png)
![image-20200726171729248](../images/JavaScript面向对象的程序设计/image-20200726171729248.webp)
若要更方便的取出实例的自有属性,可以使用`Object.keys()`方法。它会返回所有自有的可枚举的属性。返回结果为一个数组出现顺序与for-in循环相同。

View File

@ -1,6 +1,6 @@
---
title: Node.js之旅
index_img: /images/Node.js之旅/2020-09-03-16-16-04.png
index_img: /images/Node.js之旅/2020-09-03-16-16-04.webp
date: 2020-09-03 16:09:29
tags: [JavaScript, Node]
categories: 笔记
@ -11,7 +11,7 @@ url: get-starting-for-node-js
Node.js不仅仅是服务器上的JavaScript。
![](../images/Node.js之旅/2020-09-03-14-54-53.png)
![](../images/Node.js之旅/2020-09-03-14-54-53.webp)
## 并不熟悉的JavaScript

View File

@ -4,7 +4,7 @@ date: 2019-05-29 16:21:15
tags: Network
categories: 网络
url: basic-knowledge-of-qinq
index_img: /images/QinQ基础操作/qinq.jpg
index_img: /images/QinQ基础操作/qinq.webp
---
> QwQ♥
@ -73,7 +73,7 @@ TipsDot1q终结子接口和QinQ终结子接口不支持透传不带VLAN的报
QinQ报文有着固定的格式就是在802.1Q的标签上再堆叠一层802.1Q标签。QinQ报文比普通的vlan标签多4个字节。vlan帧最小帧长为68字节。
![ethernet-QinQ-format2](../images/QinQ基础操作/ethernet-QinQ-format2.png)
![ethernet-QinQ-format2](../images/QinQ基础操作/ethernet-QinQ-format2.webp)
| 字段 | 长度 | 含义 |
| ------------------- | ----------- | ------------------------------------------------------------ |
@ -89,13 +89,13 @@ QinQ报文有着固定的格式就是在802.1Q的标签上再堆叠一层802.
### 报文示例
![报文](../images/QinQ基础操作/报文-1582421531943.png)
![报文](../images/QinQ基础操作/报文-1582421531943.webp)
### TPIDTag Protocol Identifier
TPID标签协议标识IDTag Protocol Identifier是Vlan tag中的一个字段标识该vlan tag的协议类型。IEEE 802.1Q协议规定QinQ的外层vlan标签的type值为0x8100
![外层type](../images/QinQ基础操作/外层type.png)
![外层type](../images/QinQ基础操作/外层type.webp)
> IEEE802.1Q协议定义的以太网帧的VLAN Tag。802.1Q Tag位于SASource Address和Length/Type之间。通过检查对应的TPID值设备可确定收到的帧承载的是运营商VLAN标记还是用户VLAN标记。接收到帧之后设备将配置的TPID值与帧中TPID字段的值进行比较。如果二者匹配则该帧承载的是对应的VLAN标记。例如如果帧承载TPID值为0x8100的VLAN标记而用户网络VLAN标记的TPID值配置为0x8200设备将认为该帧没有用户VLAN标记。也就是说设备认为该帧是Untagged报文。
> 另外不同运营商的系统可能将QinQ帧外层VLAN标记的TPID设置为不同值。为实现与这些系统的兼容性可以修改TPID值使QinQ帧发送到公网时承载与特定运营商相同的TPID值从而实现与该运营商设备之间的互操作性。以太网帧的TPID与不带VLAN标记的帧的协议类型字段位置相同。为避免在网络中转发和处理数据包时出现问题不可将TPID值设置为下表中的任意值
@ -118,7 +118,7 @@ TPID标签协议标识IDTag Protocol Identifier是Vlan tag中的一个
拓扑:
![基本qinq](../images/QinQ基础操作/基本qinq.png)
![基本qinq](../images/QinQ基础操作/基本qinq.webp)
如图示SW2和SW3用于模拟运营商之间的InternetSW1和SW4为客户内网。基本QinQ的配置就作用于SW2和SW3之间将客户内网内的vlan10与vlan20封装上一层vlan100用于再SW2和SW3之间传输。
@ -164,7 +164,7 @@ SW1的`G 0/0/1`为trunk接口对应连接的SW2的`G 0/0/1`为基本二层Qin
使用PC1发送ICMP包到PC3数据包内容为
![报文2](../images/QinQ基础操作/报文2.png)
![报文2](../images/QinQ基础操作/报文2.webp)
其中可以看到内层的802.1q的vlan标签ID为10type为0x0800外层的也就是SW2封装的vlan标签ID为100type为0x8100
@ -172,7 +172,7 @@ SW1的`G 0/0/1`为trunk接口对应连接的SW2的`G 0/0/1`为基本二层Qin
拓扑和上述一样:
![灵活拓扑](../images/QinQ基础操作/灵活拓扑.png)
![灵活拓扑](../images/QinQ基础操作/灵活拓扑.webp)
我们在模拟internet的SW2和SW3之间添加了一个vlan 200用于配置灵活的QinQ的vlan 20堆叠一个vlan 200的tag。
@ -201,11 +201,11 @@ interface GigabitEthernet0/0/2
* vlan10
![报文3](../images/QinQ基础操作/报文3.png)
![报文3](../images/QinQ基础操作/报文3.webp)
* vlan20
![vlan20](../images/QinQ基础操作/vlan20.png)
![vlan20](../images/QinQ基础操作/vlan20.webp)
当两台PC机正常通信的时候可以看到不同vlan封装的外层vlan tag也是不一样的。这就是基于vlan的灵活QinQ。
## 上述拓扑

View File

@ -4,7 +4,7 @@ date: 2019-05-18 12:31:45
tags: Tools
categories: 实践
url: multi-platform-real-time-synchronization-by-resilio-sync
index_img: /images/Resilio-Sync多平台实时同步/res.png
index_img: /images/Resilio-Sync多平台实时同步/res.webp
---
> 备份,同步一步到位。🏹
@ -74,16 +74,16 @@ Windows是我们平常接触最多的一款GUI操作系统了对于安装软
安装界面仅仅只需要一步
![rs安装](../images/Resilio-Sync多平台实时同步/rs安装.png)
![rs安装](../images/Resilio-Sync多平台实时同步/rs安装.webp)
合适的选择后对于较新的Windows平台可是直接打开一个软件窗口
![入门sync](../images/Resilio-Sync多平台实时同步/入门sync.png)
![入门sync](../images/Resilio-Sync多平台实时同步/入门sync.webp)
接受了几个隐私政策与EULA之后有空还是要多留意条款之类的我们就可以正常使用了。
打开后的简洁的界面
![打开](../images/Resilio-Sync多平台实时同步/打开.png)
![打开](../images/Resilio-Sync多平台实时同步/打开.webp)
配置之类的稍后再说,再将自己的其他平台的机器也给完成安装。
@ -310,7 +310,7 @@ root 29385 0.3 0.4 589864 9676 ? Ssl 15:43 0:00 /usr/bin/rslsyn
成后运行后的界面与Windows完全一样。毕竟二者是同一种方式展示的UI界面。
![home_centos](../images/Resilio-Sync多平台实时同步/home_centos.png)
![home_centos](../images/Resilio-Sync多平台实时同步/home_centos.webp)
## 同步
@ -318,19 +318,19 @@ root 29385 0.3 0.4 589864 9676 ? Ssl 15:43 0:00 /usr/bin/rslsyn
在保证权限都是正常的情况下添加在A机器添加我们需要进行同步的文件夹。选择好了之后就是三种分享链接的方式。
![开始同步](../images/Resilio-Sync多平台实时同步/开始同步.png)
![开始同步](../images/Resilio-Sync多平台实时同步/开始同步.webp)
分别是“链接”、“密钥”和二维码三种方式。
随后我们就可以使用三种方式的其中一种例如使用我最喜欢的密钥选择好读写权限后在需要同步的B机器上输入复制过来的密钥。
![输入密钥](../images/Resilio-Sync多平台实时同步/输入密钥.png)
![输入密钥](../images/Resilio-Sync多平台实时同步/输入密钥.webp)
然后等着他们自己开始同步就OK了。在多平台的环境下也是不会影响正常工作的。
除此之外,对于同步的文件夹还有一些其他的选项可以配置。具体就看自己的需要来配置了🌭
![其他选项](../images/Resilio-Sync多平台实时同步/其他选项.png)
![其他选项](../images/Resilio-Sync多平台实时同步/其他选项.webp)
## 参考&推荐阅读

View File

@ -11,7 +11,7 @@ index_img: /images/Teamspeak-Server/logo.jpg
## Teamspeak
![teamspeak](../images/Teamspeak-Server/teamspeak.png)
![teamspeak](../images/Teamspeak-Server/teamspeak.webp)
Teamspeak是一套专有的VoIP软件。所谓VoIP软件就是基于网络协议的语音通话。而Teamspeak就是和现在市面上大多数即时通讯软件差不多可以发送即时消息以及多人语音通话。
@ -219,7 +219,7 @@ firewall-cmd --reload
前面有介绍过TS使用的是C/S架构我们搭建好了服务端当然是为了连接它。连接它比我们想象的要简单的多打开软件后直接在工具栏就能找到连接这一选项。
单击连接,就可以根据服务器地来连接我们搭建好的服务端了。
![连接服务器](../images/Teamspeak-Server/连接服务器.png)
![连接服务器](../images/Teamspeak-Server/连接服务器.webp)
我们可以看到有三个选项框,第一个是服务器地址,其次是服务器密码,最后是用于展示给其他人的昵称
默认新安装的服务端是没有密码的,如果我们是连接一个新服务器的话,是可以将密码留空登陆。
@ -233,20 +233,20 @@ firewall-cmd --reload
如果是第一次连接至ts的新服务器那么我们连接成功后就会立马弹出一个用于输入token的对话框。我们将刚刚创建服务器时给我们的token填入即可。这样就可以直接在客户端修改自己的服务器了。
![token](../images/Teamspeak-Server/token.png)
![token](../images/Teamspeak-Server/token.webp)
因为ts默认在使用客户端时会自动创建一个用户身份每个身份都是不相同的。**那如果我们更换电脑连接自己的服务器时,或者想给其他人一个修改服务器的权限时该怎么办呢?**
- 导出当前的用户身份
在工具栏的“工具-身份”这个标签中,我们可以看到自己当前账户身份。直接右击便可以执行导出操作。在其他地方使用相同方法导入就可以继续使用这个身份了。
![身份](../images/Teamspeak-Server/身份.png)
![身份](../images/Teamspeak-Server/身份.webp)
- 新建token码
当我们想给其他身份的用户修改服务器的权限的时候,我们可以使用新建权限码的方式来提升其他用户的权限。
在工具栏的“权限-权限码清单”中就可以找的新建权限码的按钮以及已经新建过的权限码清单。新建时也可以选择不同的权限来进一步控制。使用权限码就和我们第一次使用时一样操作即可。
![权限码](../images/Teamspeak-Server/权限码.png)
![权限码](../images/Teamspeak-Server/权限码.webp)
### 翻译插件
@ -254,16 +254,16 @@ firewall-cmd --reload
打开软件后,打开“工具-选项”(Alt+P),找到“插件(add-ons)”这一选项卡。
![插件](../images/Teamspeak-Server/插件.png)
![插件](../images/Teamspeak-Server/插件.webp)
默认看到的是当前本地的插件我们可以选择“Browse online"来查看在线可以下载安装的插件。选择筛选器为”翻译“然后输入”Chinese“就可以找到一款繁体中文的插件。点击进入插件的详情页面就可以看到”install“。单击安装即可。
![繁体中文](../images/Teamspeak-Server/繁体中文.png)
![繁体中文](../images/Teamspeak-Server/繁体中文.webp)
Install完成之后重新打开软件就会应用上翻译了。如果没有成功应用可以再去刚刚插件地方看看有没有启用。
除了翻译插件之外TS还有很多种类的插件以及界面皮肤等。和刚刚安装翻译插件的方法一摸一样。
![TS3](../images/Teamspeak-Server/TS3-1582422801541.png)
![TS3](../images/Teamspeak-Server/TS3-1582422801541.webp)
## 参考

View File

@ -4,7 +4,7 @@ date: 2020-10-22 11:21:22
tags: [JavaScript, Vue]
categories: 笔记
url: Vue-js-get-started
index_img: /images/Vue.js-起步!/logo.png
index_img: /images/Vue.js-起步!/logo.webp
---
在我打算学习vue的时候正是其3.0版本发布不久的时候。很庆幸生活在这个时代但困扰我的是是否应该由旧版本的2.x开始学习一向选择困难的我最终打算两个版本一起学习从2.x开始入门顺便还能一睹其与3.0版本的变化。
@ -182,7 +182,7 @@ Vue还提供了`v-model`指令,它能够轻松实现对表单的双向绑定
组件系统是Vue的另一个重要概念它是一种抽象允许我们使用小型、独立和通常可复用的组件构建大型应用。一个大型的页面应用将由几个可重复利用的组件构成。
![](../images/Vue.js-起步!/2020-10-16-10-25-35.png)
![](../images/Vue.js-起步!/2020-10-16-10-25-35.webp)
在 Vue 里,一个组件本质上是一个拥有预定义选项的一个 Vue 实例。在 Vue 中注册组件很简单:
@ -473,4 +473,4 @@ Vue同样也暴露了一些内建的属性例如`$attrs`和`$emit`。他们
下图可以很清晰的看到Vue3的实例的一个生命周期。
![](../images/Vue.js-起步!/2020-10-22-11-03-33.png)
![](../images/Vue.js-起步!/2020-10-22-11-03-33.webp)

View File

@ -3,7 +3,7 @@ title: Hello World
tags:
date: 1999-06-05 17:42:58
url: hello-world
index_img: /images/hello-world/index.jpg
index_img: /images/hello-world/index.webp
---
Welcome to [Hexo](https://hexo.io/)! This is your very first post. Check [documentation](https://hexo.io/docs/) for more info. If you get any problems when using Hexo, you can find the answer in [troubleshooting](https://hexo.io/docs/troubleshooting.html) or you can ask me on [GitHub](https://github.com/hexojs/hexo/issues).

View File

@ -1,6 +1,6 @@
---
title: hexo
index_img: /images/hexo/index.png
index_img: /images/hexo/index.webp
date: 2017-08-30 11:08:19
tags: [Linux, HTML]
categories: 实践
@ -70,7 +70,7 @@ $ npm install
hexo init web
```
![init](../images/hexo/init.png)
![init](../images/hexo/init.webp)
过程略长,稍等即可
@ -119,7 +119,7 @@ hexo server -p 80 -s
正常情况下便可以直接进行访问,为如下页面。
![web](../images/hexo/web.png)
![web](../images/hexo/web.webp)
Cannot GET /

View File

@ -4,7 +4,7 @@ date: 2019-05-16 14:21:37
tags: Minecraft
categories: 实践
url: minecraft-bedrock-server
index_img: /images/Minecraft-bedrock服务端/217940907.jpg
index_img: /images/Minecraft-bedrock服务端/217940907.webp
---
## Minecraft

View File

@ -4,7 +4,7 @@ date: 2019-06-14 14:42:41
tags: Linux
categories: Linux
url: basic-knowledge-of-systemd
index_img: /images/systemd的基础操作/logo.png
index_img: /images/systemd的基础操作/logo.webp
---
## 什么是systemd

View File

@ -13,7 +13,7 @@ emoji是我们身边常见的且神奇的表情符号它被称为绘文字
Emoji的编码是Unicode字符集中的一部分特定形象的Emoji表情符号对应到特定的Unicode字节。也就是说emoji是unicode编码。好处是无论在什么地方使用都不像是图片那么难处理以及可以直接写在数据库内。
![emoji_unicode.png][1]
![emoji_unicode.webp][1]
### 词语发音
@ -29,7 +29,7 @@ Emoji的编码是Unicode字符集中的一部分特定形象的Emoji表情符
现在多数的软件、网站等都已经广泛的支持emoji表情了。自己也是非常的喜欢这类表情特别喜欢微软家的那种扁平的风格真的很招人喜爱。
![1557663679707.png][2]
![1557663679707.webp][2]
但是最近使用typecho的时候遇到点小问题发现新安装的typecho居然不支持使用emoji。在文章等页面使用了emoji之后保存会提示数据库查询错误。
@ -53,7 +53,7 @@ alter table typecho_users convert to character set utf8mb4 collate utf8mb4_unico
修改后就可以看到表的‘排序规则’(charset)为可以使用emoji的`utf8mb4`了。
![2019-05-12T12:27:33.png][3]
![2019-05-12T12:27:33.webp][3]
### 修改typecho配置文件
@ -72,11 +72,11 @@ $db->addServer(array (
全部修改完成后就能正常的在typecho中使用emoji了
![2019-05-12T12:31:18.png][4]
![2019-05-12T12:31:18.webp][4]
[1]: ../images/使typecho支持emoji/2721696195.png
[2]: ../images/使typecho支持emoji/1431864746.png
[3]: ../images/使typecho支持emoji/175217384.png
[4]: ../images/使typecho支持emoji/4188132525.png
[1]: ../images/使typecho支持emoji/2721696195.webp
[2]: ../images/使typecho支持emoji/1431864746.webp
[3]: ../images/使typecho支持emoji/175217384.webp
[4]: ../images/使typecho支持emoji/4188132525.webp

View File

@ -4,7 +4,7 @@ date: 2019-11-18 12:53:53
tags: Windows
categories: 踩坑
url: modify-icloud-storage-location-on-windows
index_img: /images/修改Windows端iCloud云盘存储位置/logo.jpeg
index_img: /images/修改Windows端iCloud云盘存储位置/logo.webp
---
@ -30,11 +30,11 @@ C:\WINDOWS\system32>mklink /D C:\Users\Defectink\iCloudDrive D:\iCloudDrive
没有退出按钮?
![image-20191029200503950](../images/修改Windows端iCloud云盘存储位置/image-20191029200503950.png)
![image-20191029200503950](../images/修改Windows端iCloud云盘存储位置/image-20191029200503950.webp)
> 如果先退出再复制文件可能会导致意外
![image-20191029200837325](../images/修改Windows端iCloud云盘存储位置/image-20191029200837325.png)
![image-20191029200837325](../images/修改Windows端iCloud云盘存储位置/image-20191029200837325.webp)
## 启动文件夹

View File

@ -1,6 +1,6 @@
---
title: 入坑IRC
index_img: /images/入坑IRC/logo.png
index_img: /images/入坑IRC/logo.webp
date: 2020-08-22 18:37:36
tags: [tools,IRC,Linux]
categories: 日常
@ -43,7 +43,7 @@ IRC并不像现代的聊天软件一样需要先注册账号才能使用。
输入注册命令后就会收到认证的邮件邮件大概是这样的freenode
![](../images/入坑IRC/2020-08-22-11-55-07.png)
![](../images/入坑IRC/2020-08-22-11-55-07.webp)
将邮件里的内容再输入一遍就注册完成了。
@ -75,7 +75,7 @@ IRC并不像现代的聊天软件一样需要先注册账号才能使用。
4. Select `SASL (username + password)` for the `Login method` field
5. In the `Password` field, enter your NickServ password
![](../images/入坑IRC/2020-08-22-15-28-26.png)
![](../images/入坑IRC/2020-08-22-15-28-26.webp)
## 频道

View File

@ -4,7 +4,7 @@ date: 2019-06-05 18:51:32
tags: Linux
categories: 实践
url: public-key-cryptgraphy
index_img: /images/公开密钥密码学/logo.jpeg
index_img: /images/公开密钥密码学/logo.webp
---
GPG/PGP赛高
@ -60,7 +60,7 @@ GPG/PGP赛高
既然上述已经介绍了它是自由软件,那么它跨平台的几率就很大了,支持的平台也非常的多。在官方网站里,我们可以看到它支持很多平台。
![GPG多平台](../images/公开密钥密码学/GPG多平台.png)
![GPG多平台](../images/公开密钥密码学/GPG多平台.webp)
#### Windows GPG4win
@ -70,9 +70,9 @@ GPG/PGP赛高
GPG4win是GPG在Windows平台的一款可视化的非对称加密软件。对于可视化的软件来说使用也非常的简单明了。 几乎常用的一些功能都非常直白的写在了刚开打的页面中。基本上只要使用者了解大概的非对称加密的运作原理,就可以很轻松的使用该软件了。
![Kleopatra](../images/公开密钥密码学/Kleopatra.png)
![Kleopatra](../images/公开密钥密码学/Kleopatra.webp)
![密钥](../images/公开密钥密码学/密钥.png)
![密钥](../images/公开密钥密码学/密钥.webp)
#### Ubuntu & CentOS

View File

@ -4,7 +4,7 @@ date: 2020-06-29 12:12:41
tags: Tools
categories: 实践
url: write-and-cooperation
index_img: /images/写作与协作/index.png
index_img: /images/写作与协作/index.webp
---
出于对速度无理的追求最终还是放弃了使用动态内容。转战静态blog。以前也稍微尝试过hexo所以决定还是主要为hexo为主了。
@ -51,7 +51,7 @@ Hexo的仓库直接push之后CI持续集成就会按照预设好的步骤来
除了外观从清新脱俗到繁重了一点余下就只剩方便了。对于我这种才转到hexo的写作半吊子一直很想找个与hexo契合度高的写作姿势。之前需要在Typora中写完然后再将文章和单独的图片文件夹复制到hexo的`souce/_post`目录。像我这种半年产出一篇文章的还好要是天天写那样会被麻烦死。况且如果有某一篇文章出了点小差错需要改。那就要同时动两个md文件和两组图片文件夹对着资源管理翻来覆去的找极为麻烦🌚
![vscode](../images/写作与协作/vscode.jpg)
![vscode](../images/写作与协作/vscode.webp)
#### 粘贴图片🖼
@ -104,7 +104,7 @@ Editor > Suggest: Snippets Prevent Quick Suggestions
使用CI持续部署的好处就是可以完全专心与创作而不用再去管部署之类的问题。只需要第一次写好流程剩下的就全部交给自动化吧。
![coding](../images/写作与协作/2020-08-07-09-30-54.png)
![coding](../images/写作与协作/2020-08-07-09-30-54.webp)
之前的我从来没有用过Coding对CI/CD也没有什么了解从来没考虑过自动化部署这类操作。后来在研究静态化网站时发现了新大陆完全可以将复杂重复的工作交给机器。并且随着后面文章的增加渲染markdown文件肯定会越来越慢于其手动繁琐的操作不如完全交给CI。
@ -112,7 +112,7 @@ Editor > Suggest: Snippets Prevent Quick Suggestions
在我研究CI姿势的这段时间里Github也推出了自己的CI钞能力。无论是谁家的CI除了部署步骤不一样其结果肯定是相同的。Github action也是能达到同样的效果对于各个厂家的云存储action也有同样的解决方法甚至是比coding的jenkins还要灵活一点。
![](../images/写作与协作/2020-08-27-16-32-48.png)
![](../images/写作与协作/2020-08-27-16-32-48.webp)
## Hexo插件📥
@ -160,7 +160,7 @@ image_minifier:
interlaced: false
multipass: false
optimizationLevel: 2
pngquant: false
webpquant: false
progressive: false
silent: false
```
@ -191,7 +191,7 @@ feed:
content_limit: 140
content_limit_delim: ' '
order_by: -date
icon: icon.png
icon: icon.webp
autodiscovery: true
template:
@ -312,7 +312,7 @@ sudo gdebi your_ossfs_package
成功了安装了之后就可以配置oss的账号信息来登陆。使用AccessKeyId/AccessKeySecret来代替账号密码进行访问。如果担心安全问题还可以使用阿里云的子账号只赋予oss的访问权限来最大程度的保护账户资产。在阿里云的[RAM访问控制](https://ram.console.aliyun.com/overview)中可以进行添加子账户并赋予特定的权限。
![image-20200229104812836](../images/写作与协作/image-20200229104812836.png)
![image-20200229104812836](../images/写作与协作/image-20200229104812836.webp)
AccessKeyId/AccessKeySecret信息存放在`/etc/passwd-ossfs`文件中。并且文件的权限必须正确设置建议设为640。
@ -365,5 +365,5 @@ ossfs#bucket_name mount_point fuse _netdev,url=url,allow_other 0 0
并且阿里云也早就支持了子目录首页了。只需要简单开一下就能解决这个问题。
![image-20200401100940056](../images/写作与协作/image-20200401100940056.png)
![image-20200401100940056](../images/写作与协作/image-20200401100940056.webp)

View File

@ -4,7 +4,7 @@ date: 2018-06-29 12:12:41
tags: [Linux, HTML]
categories: 实践
url: hexo-again
index_img: /images/想起来当年还折腾过hexo/index.png
index_img: /images/想起来当年还折腾过hexo/index.webp
---
## Hexo
@ -314,6 +314,6 @@ defect.ink
记录的虽然不是太多,也可能不是那么详细。但是还是大致的顺着搭建成功这么一个放向来的的。
所以就留下一个截图的纪念吧?
![截图纪念](https://cdn.defectink.com/2019/01/%E9%A1%B5%E9%9D%A2%E9%A2%84%E8%A7%88.png-shuiyin)
![截图纪念](https://cdn.defectink.com/2019/01/%E9%A1%B5%E9%9D%A2%E9%A2%84%E8%A7%88.webp-shuiyin)
~~图丢了~~

View File

@ -4,7 +4,7 @@ date: 2019-06-28 12:12:41
tags: Tools
categories: 踩坑
url: bark-custom-notification-for-apple
index_img: /images/水果自定义通知大法/logo.jpg
index_img: /images/水果自定义通知大法/logo.webp
---
> ding~
@ -23,7 +23,7 @@ App Store中有位大佬开发的[Bark](https://apps.apple.com/cn/app/bark-给
Github[Bark](https://github.com/Finb/Bark)
![1561705066368](../images/水果自定义通知大法/1561705066368.png)
![1561705066368](../images/水果自定义通知大法/1561705066368.webp)
默认它提供了自己的服务器如果我们需要推送一些较为隐私的消息可以使用自建服务端。它提供了http接口后端简单调用即可给自己的水果设备发送推送。
@ -107,7 +107,7 @@ RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
如果一切都没啥问题的话我们直接打开刚刚配置好证书的apache站点bark应该就是能够正常运行了。
![1561706128389](../images/水果自定义通知大法/1561706128389.png)
![1561706128389](../images/水果自定义通知大法/1561706128389.webp)
## Systemd
@ -135,4 +135,4 @@ WantedBy=multi-user.target
具体的效果就和平时使用其他的systemd控制的软件一样了并且不用再那么麻烦了。
![1561706516651](../images/水果自定义通知大法/1561706516651.png)
![1561706516651](../images/水果自定义通知大法/1561706516651.webp)

View File

@ -4,7 +4,7 @@ date: 2019-06-05 16:41:57
tags: Linux
categories: Linux
url: auto-backup
index_img: /images/自动备份大法/bakcup.jpg
index_img: /images/自动备份大法/bakcup.webp
---
## 引入
@ -13,7 +13,7 @@ index_img: /images/自动备份大法/bakcup.jpg
因为一个lsyncd的日志写了34GB。
![1.png/](../images/自动备份大法/2874899693.png)
![1.webp/](../images/自动备份大法/2874899693.webp)
## 操作
@ -113,7 +113,7 @@ find /root/backup/tar.gz/sql -mtime +3 -name "*.*" -exec rm -rf {} \;
先来简单的介绍下可爱的crontab文件的时间格式吧。
![2.png/](../images/自动备份大法/4160640759.png)
![2.webp/](../images/自动备份大法/4160640759.webp)
星号(*代表所有可能的值例如month字段如果是星号则表示在满足其它字段的制约条件后每月都执行该命令操作。

View File

@ -4,7 +4,7 @@ date: 2019-05-29 9:05:01
tags: Linux
categories: 踩坑
url: fixed-inotify-watch-not-enough
index_img: /images/解决inotify-watch不够/logo.jpg
index_img: /images/解决inotify-watch不够/logo.webp
---
> Failed to add /run/systemd/ask-password to directory watch: No space left on device

View File

@ -144,4 +144,34 @@ background: linear-gradient(to bottom,transparent 60%,rgba(189,202,219,.3) 0) no
.markdown-body h1, .markdown-body h2 {
padding-bottom: .3em;
border-bottom: 0px solid #eaecef !important;
}
}
/* 浪漫雅园!! */
/* @font-face {
font-family: "LMYY";
src: url("https://cdn.defectink.com/static/fonts/yayuan.woff")
}
* {
font-family: "LMYY" !important;
} */
/* 代码块里的字太小 */
/* .markdown-body pre code {
font-size: 100% !important;
} */
/* 滚动条webkit赛高 */
::-webkit-scrollbar {
width: 8px;
background-color: transparent;
}
::-webkit-scrollbar-thumb {
background-color: darkgray;
border-radius: 10px;
}
.v[data-class=v] .vwrap .vedit {
position: relative;
padding-top: 10px;
background: no-repeat right bottom url(https://cdn.defectink.com/static/images/iloli.gif);
background-size: 20%;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 410 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 838 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 936 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 387 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Some files were not shown because too many files have changed in this diff Show More