一份2021年03月10日的信息流提炼
每天学点运维
完全/增量备份/还原PostgreSQL
原文:[Full/Incremental Backup/Restore PostgreSQL](Full/Incremental Backup/Restore PostgreSQL)
构成
- pg-primary (master): 读写db服务器
- pg-standby (slave):只读db服务器
- 备份仓库 (repository)
pgBackRest
-
- 关于备份 Backup
- 完全备份 Full Backup:将数据库群集的全部内容复制到备份中。数据库群集的第一次备份始终是完整备份。pgBackRest总是能够直接还原完整备份。
- 差别备份 Differential Backup:只复制自上次完整备份以来发生变化的数据库群集文件。差分备份和完整备份必须同时有效才能恢复差分备份。
- 增量备份 Incremental Backup:只复制自上次备份以来发生变化的数据库群集文件。由于增量备份只包括自上次备份以来的文件,因此要执行增量备份的还原,所有之前的增量备份、之前的差分备份和之前的完整备份都必须有效。
- 关于备份 Backup
-
还原 Restore: 将备份复制到系统中,并在该系统中作为实时数据库群集启动的行为。
-
利用Ansible playbook来安装
pgbackrest -
为了实现服务器之间的通信,
pgBackRest需要无密码SSH登录。- hosts: repository tasks: - name: Create repository host key pair - command: ssh-keygen -f /home/pgbackrest/.ssh/id_rsa -t rsa -b 4096 -N "" args: creates: /home/pgbackrest/.ssh/id_rsa - name: Copy repository public key to pg-primary and pg-standby command: cat /home/pgbackrest/.ssh/id_rsa.pub register: repo_ssh_keys
每天学点Golang
数组
- 声明数组需要同时指定长度和数据类型。
- 可以对数组进行写入、读取、删除、遍历等操作。
var a [5]int
// 初始化, 最后1个元素为int类型零值(0)
var b = [5]int{1, 2, 3, 4}
// 数组的遍历
for index, value := range c {
fmt.Printf("c[%d]=%d\n", index, value)
}
切片
- Go语言的数组不支持自动扩容,不支持删除元素,数组是值类型,切片是引用类型,在向函数传参时切片拥有更好的性能。
- 切片支持取范围操作,新切片和原切片共享底层数组,因此对切片的修改会同时影响两个切片。
- 范围操作符语法如下:a[begin:end],左闭右开区间。
var a = make([]int, 0) // 声明一个大小为0的int类型切片
a = append(a, 1, 2, 3) // 添加三个元素
// 声明一个大小为4的切片,并复制a的元素
var b = make([]int, 4)
copy(b, a)
// 直接使用值初始化切片并删除第2、3个元素
a = []int{1, 2, 3, 4, 5}
a = append(a[:1], a[3:]...)
映射
- 映射也叫字典、哈希表,数组和切片是通过数字索引访问的顺序集合,而映射是通过键来访问的无序集合。
- 映射在查找方面非常高效,有着O(1)的时间复杂度。
- 映射必须初始化之后才能使用。
// 使用make初始化映射
var a = make(map[string]int)
// 使用值初始化映射
var b = map[string]int{
"zhangsan": 18,
"lisi": 28,
}
每天学点前端
关于Svelte与Vue
Vue实现 Reactivity 的原理:使用 defineProperty 或者 Proxy, 在 setter 这一层,当对象的某个成员被赋值的时候,执行更新逻辑。
const reactive = {}
Object.defineProperty(reactive, 'a', {
set(value) { console.log('a was updated') }
})
reactive.a = 'changed' //=> a was updated
这是一种「运行时」的手段,它需要在运行时改变了赋值行为,所以在用 Vue 的时候,你必需把需要 Reactivity 的对象包在 data 里,上文的例子用 Vue 需要这么写:
const yourData = {
data() {
return { a: 1, b: 2 }
},
computed: {
c() { return this.a + this.b }
}
}
const reactive = new Vue(yourData)
console.log(reactive.c) //=> 3
reactive.a = 2
console.log(reactive.c) //=> 4
Svelte不用 defineProperty, 而是在编译时,每当遇到赋值语句,就让它在赋值语句的后面自动加一个调用更新的方法。实际上的实现要更加复杂一些(比如需要把更新放在同一个 microtask 里) 。
let a = 1
let b = 2
let c = a + b
function update() {
c = a + b
}
console.log(c) //=> 3
a = 2; update()
console.log(c) //=> 4
- 实现 Reactivity 的原理都是依赖收集,但 Svelte 是在编译时完成了,Vue 在运行时收集。
- Vue 用了 Virtual DOM, Svelte 在编译时就知道它应该操作哪个 DOM
每天学点AI
什么是神经网络
原文:(1) 虎嗅 | 什么是神经网络? (2) 什么是卷积神经网络(CNN)? (3) 两分钟看懂什么是决策树?
人脑中有约860亿个神经元(Neural):神经细胞+神经突触。
神经网络中的神经元抽象为节点来存储数字,神经突触被抽象为有权重的连接。
CNN(Convolutional Neural Network)卷积神经网络
在 CNN 的卷积层中,存在着数字矩阵,它们被称为卷积核(Kernel)。原始图片经过输入层后会变为灰度或是 RGB 数值填充的矩阵,将卷积核与图片矩阵对齐,对应格子中的数字相乘后再相加,再将得到的数字填入新矩阵,这就是卷积。
卷积核以一定的距离在图像上移动运算,这被称为步长(Stride),得到的新矩阵能反映图像的部分特征,因此被称为特征图(Feature Map)。它们既是这一层的输出,也是下一层的输入。
对于 CNN 来说,训练就是让网络根据已有的数据和它们的标签,自动确定卷积核中的数字。以拥有 5 个卷积层的 AlexNet 为例,边缘、纹理、组成……以人眼的角度观察,越靠后的卷积层提取出的特征越抽象。
除了卷积层, CNN 还有另外两个重要配件:池化层(Pooling)和全连接层。
池化层能选取图像的主要特征。常用的 Maxpooling 是保留窗口覆盖区域的最大数值,矩阵被池化后,参数会大量减少。
全连接层通常在网络的最后,能将提取到的特征集合在一起,给出图片可能是某种事物的概率。
决策树 (Decision Tree)
决策树模型非常经典,在机器学习中常被用来分类。构成它的元素是节点和边,节点会根据样本的特征做出判断,边则指示着方向。
-
构造树的基本思路:让熵 (Entropy) 快速降低
-
完美分类=过拟合的问题解决:预剪枝(Pre-Pruning), 后剪枝(Post-Pruning)
-
过拟合(Overfitting) : If we have too many features, the learned hypothesis may fit the training set vey well, but fail to generalize to new examples.
简单说就是预测值和样本标签值几乎完全一致的情况
-
每天学点bash
27个简单的给新手的bash建议
原文:27 Simple Bash Scripting Tips for Beginners
代码片段参考附录。
-
清晰的结构
-
给编辑器安装ShellCheck
-
提供Usage方法
-
错误消息,Google shell style guide 推荐使用方法打印出消息和状态信息
-
方法注释(描述,全局变量,参数,输出,返回)
-
set -xDebug模式 -
检查bash版本
-
用户输入转换大小写,e.g. y/Y → Y
-
类三元表达式:
[ $foo -ge $bar ] && baz="Smile!" || baz="Sleep!" -
字符和数组长度:
str_len=${#string},arr_len=${#array[@]} -
设置默认值:
${foo-$DEFAULT},${foo=$DEFAULT} -
获取OS类型,系统自带HTTP Get工具,Python版本
-
获取脚本名和目录:
basename "$0",c=$0 && echo "${c%/*}" -
Bash中的类型提示可以利用
declare来实现 -
利用变量保存Exit Status
-
利用Trap来对应异常退出
-
Subshell 和 Exit Status
# 括号会使命令在一个SubShell中运行 no_func1 || ( echo "there is nothing" exit 1 ) echo $? # 大括号不创建子SubShell,exit退出主shell进程,所以它永远不会达到运行echo $? no_func2 || { echo "there is nothing" exit 1 } echo $?
其他值得阅读
-
你可以学习所有领域吗?Could you learn every subject?
- 知识树(Knowdege Tree)的概念。
- 对自己的知识树进行进度评估。
- 怎样学习 | 学习目的:知识掌握or技能学习?。线上课程(e.g. MITOPENCOURSEWARE) → 书籍 → 应用
今日收获
-
owner意识 。所谓 owner 意识,其实就是主动去兜底。 v2ex | 对程序员的晋升之路有疑问
- 所有技术岗都是极其容易被替代的,管理岗的人是很难做改动的。
-
成长心态 growth mindset
"相信自己的才能可以发展(通过努力工作、良好的策略和他人的投入)的人具有成长的心态。他们往往比那些思维方式比较固定的人(那些认为自己的才能是与生俱来的天赋的人)取得更大的成就"。 -- Carol Dweck
附录:snippets
- bash scripting tips
# 清晰的结构
#!/usr/bin/env bash
#####################################
# Author: Your name
# Version: v1.0.0
# Date: 2021-02-20
# Description: This script does this and that.
# Usage: myscript <directory_name> <file_name>
###########################
# Global variables ##############
# Functions #####################
# Main body #####################
exit 0
# 提供Usage方法
usage(){
# Simple Message
echo "Usage: $0 [ -d DAYS ] [ -f FROM_DIR ] [ -t TO_DIR ]"
# Full Message with Heredoc
cat <<EOF
my_script_name
Description: Your description.
Usage: movies [flag] or movies [movieToSearch]
-u Update
-h Show the help
-v Get the tool version
-d Show detailed information
Examples:
my_script_name something
my_script_name anything
EOF
}
while getopts "f:d:t:?h" opt; do
case $opt in
f) FROM_DIR=$OPTARG ;;
d) DAYS=$OPTARG ;;
t) TO_DIR=$OPTARG ;;
h | *) usage ;;
esac
done
# Error Message
err() {
echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $*" >&2
}
if ! do_something; then
err "Unable to do_something"
exit 1
fi
# 检查用户的bash版本
if ((BASH_VERSINFO[0] < 4)); then
printf '%s\n' "Error: This requires Bash v4.0 or higher. You have version $BASH_VERSION." 1>&2
exit 2
fi
# 改变大小写
set -x
echo -n "Can you say Hello in Japanese?"
read -r answer
answer=$(echo "$answer" | cut -c 1-1 | tr "[:lower:]" "[:upper:]")
if [ "$answer" = Y ]
then
echo "Wow you are awesome."
else
echo "Neither can I."
fi
# 用变量保存 Exit Status
test -d /tmp/tmp_dir
test_es=$?
if [[ ${test_es} -ne 0 ]]; then
echo "No dir found. Exiting script!"
exit 1
fi
个人博客发布地址:Digest 2021.03.10 | DB备份方案,2分钟神经网络