lkgBlog

  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

磁盘分区

发表于 2021-05-09

磁盘分区

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
fdisk -l
fdisk /dev/sdb # 开始分区
# p print the partition table #查看当前分区情况
# n add a new partition #添加一个新分区
# d delete a partition
# w write table to disk and exit

partprobe # 重新读取分区表信息
mkfs -t ext4 /dev/sdb1 # 格式化
mount /dev/sdb1 /disk1 # 挂载

# 修改 /etc/fstab 文件挂载
blkid /dev/sdb1 # 获取 UUID
vim /etc/fstab
mount -a

# list block,即用于列出所有可用块设备的信息
lsblk

算法图解读后感

发表于 2021-03-06 | 更新于 2021-05-09

算法图解读后感

这本书适合对算法感兴趣的入门读者,书中没有太多高深的算法公式,更多是生动形象的趣味图解。如果是一个已经有算法基础的人来看,显然说中说的知识不够深入,但对于想入门或者培养算法兴趣的人来说,这就是一本绝佳的图书。再被读后,我也被深深吸引了。

本来看知乎大神说花一个周末就能读完,但本人花了一周半,不过也是因为工作和生活的原因,并没有进行连续的阅读,只是分散时间阅读。大概合计有效阅读时间应该也在10个小时以内。所以如果用心专心读的话一个周末不成问题。前提是能静下心来去读。

第一次写读后感,希望自己也可以阅读更多书,顺便写一些读后感,算对自己的总结。

sql必知会读书笔记

发表于 2019-07-24 | 更新于 2021-05-09 | 分类于 数据库

sql必知会读书笔记

  1. sql是什么

    SQL (发音为字母 S-Q-L 或 sequel )是结构化查询语言( Structured Query Language )的缩写。 SQL 是一种专门用来与数据库沟通的语言。

  2. 为什么

    设计 SQL 的目的是很好地完成一项任务 —— 提供一种从数据库中读写数据的简单有效的方法。

    标准 SQL 由 ANSI 标准委员会管理,从而称为 ANSI SQL 。

1. 数据库基础

概念:

  1. 数据库(database)
    保存有组织的数据的容器
  2. 表(table)
    表是一种结构化的文件,可用来存储某种特定类型的数据。
  3. 模式(schema)
    关于数据库和表的布局及特性的信息。这些特性定义了数据在表中如何存储,包含存储什么样的数据,数据如何分解,各部分信息如何命名等信息。
  4. 列( column )
    表中的一个字段。所有表都是由一个或多个列组成的。
  5. 数据类型
    所允许的数据的类型。每个表列都有相应的数据类型,它限制(或允许)该列中存储的数据。

注意:数据类型兼容
数据类型及其名称是 SQL 不兼容的一个主要原因。虽然大多数基本数据类型得到了一致的支持,但许多高级的数据类型却没有。更糟的是,
偶然会有相同的数据类型在不同的 DBMS 中具有不同的名称。

  1. 行(row)

    表中的一个记录。表中的数据是按行存储的,所保存的每个记录存储在自己的行内。

  2. 主键( primary key )
    一列(或一组列),其值能够唯一标识表中每一行。

    主键的条件:

    1. 任意两行都不具有相同的主键值;
    2. 每一行都必须具有一个主键值(主键列不允许NULL值);
    3. 主键列中的值不允许修改或更新;
    4. 主键值不能重用(如果某行从表中删除,它的主键不能赋给以后的新行)。

2. 检索数据

提示:

  1. 结束 SQL 语句。多条 SQL 语句必须以分号(;)分隔。多数 DBMS 不需要在单条 SQL 语句后加分号。

  2. SQL 语句不区分大小写,因此SELECT与select是相同的。

  3. 使用空格。在处理 SQL 语句时,其中所有空格都被忽略。

  4. 当心逗号。在选择多个列时,一定要在列名之间加上逗号,但最后一个列名后不加。如果在最后一个列名后加了逗号,将出现错误

注释:

单行:“#” 开头

多行:/* */

3. 排序检索数据

ORDER BY 子句的位置
在指定一条ORDER BY子句时,应该保证它是SELECT语句中最后一条子句。如果它不是最后的子句,将会出现错误消息

按多个列排序

下面的代码检索 3 个列,并按其中两个列对结果进行排序 —— 首先按价格,然后按名称排序。

1
2
3
SELECT prod_id, prod_price, prod_name
FROM Products
ORDER BY prod_price, prod_name;

按列位置排序

1
2
3
SELECT prod_id, prod_price, prod_name
FROM Products
ORDER BY 2, 3;

ORDER BY 2,3表示先按prod_price,再按prod_name进行排序。

指定排序方向

DESC

DESC关键字只应用到直接位于其前面的列名。

警告:在多个列上降序排序
如果想在多个列上进行降序排序,必须对每一列指定DESC关键字。

4. 过滤数据

WHERE 子句

在SELECT语句中,数据根据WHERE子句中指定的搜索条件进行过滤。WHERE子句在表名(FROM子句)之后给出,

警告: WHERE 子句的位置
在同时使用ORDER BY和WHERE子句时,应该让ORDER BY位于WHERE之后,否则将会产生错误

WHERE 子句操作符

操作符 说 明
BETWEEN 在指定的两个值之间
IS NULL 为 NULL 值
< > 不等于
1
2
3
4
SELECT prod_name, prod_price
FROM Products
WHERE (vend_id = 'DLL01' OR vend_id = ‘BRS01’)
AND prod_price >= 10;

这条SELECT语句与前一条的唯一差别是,将前两个条件用圆括号括了起来。因为圆括号具有比AND或OR操作符更高的求值顺序,所以 DBMS 首先
过滤圆括号内的OR条件。这时, SQL 语句变成了选择由供应商DLL01或BRS01制造的且价格在 10 美元及以上的所有产品,这正是我们希望的结
果。

复杂查询

提示:在WHERE子句中使用圆括号
任何时候使用具有AND和OR操作符的WHERE子句,都应该使用圆括号明确地分组操作符。

IN操作符

为什么要使用IN操作符?其优点为:

在有很多合法选项时,IN操作符的语法更清楚,更直观。 在与其他AND和OR操作符组合使用IN时,求值顺序更容易管理。 IN操作符一般比一组OR操作符执行得更快(在上面这个合法选项很少的例子中,你看不出性能差异)。 IN的最大优点是可以包含其他SELECT语句,能够更动态地建立WHERE子句。

NOT操作符

5. 用通配符进行过滤

LIKE操作符

百分号(%)通配符

最常使用的通配符是百分号(%)。在搜索串中,%表示任何字符出现任意次数。

说明:区分大小写
根据DBMS的不同及其配置,搜索可以是区分大小写的。如果区分大小写,则’fish%’与Fish bean bag toy就不匹配。

警告:请注意NULL
通配符%看起来像是可以匹配任何东西,但有个例外,这就是NULL。子句WHERE prod_name LIKE ‘%’不会匹配产品名称为NULL的行。

下划线(_)通配符

另一个有用的通配符是下划线(_)。下划线的用途与%一样,但它只匹配单个字符,而不是多个字符。

说明:DB2通配符 DB2不支持通配符_。 _

_说明:Access通配符
如果使用的是Microsoft Access,需要使用?而不是_。

方括号([ ])通配符

方括号 ([]) 通配符用来指定一个字符集,它必须匹配指定位置(通配符的位置)的一个字符。

使用通配符的技巧

  • 不要过度使用通配符。如果其他操作符能达到相同的目的,应该使用其他操作符。

  • 在确实需要使用通配符时,也尽量不要把它们用在搜索模式的开始处。把通配符置于开始处,搜索起来是最慢的。

  • 仔细注意通配符的位置。如果放错地方,可能不会返回想要的数据。

7.计算字段

CustomersCustomers

拼接字段

执行算数计算

加减乘除(+ - * /)

8. 使用数据处理函数

DBMS 函数的差异

函  数 语  法
提取字符串的组成部分 Access 使用 MID() ; DB2 、 Oracle 、 PostgreSQL 和 SQLite 使用 SUBSTR() ; MySQL 和 SQL Server 使用 SUBSTRING()
数据类型转换 Access 和 Oracle 使用多个函数,每种类型的转换有一个函数; DB2 和 PostgreSQL 使用 CAST() ; MariaDB 、 MySQL 和 SQL Server 使用
CONVERT()
取当前日期 Access 使用 NOW() ; DB2 和 PostgreSQL 使用 CURRENT_DATE ; MariaDB 和 MySQL 使用 CURDATE() ; Oracle 使用 SYSDATE ; SQL Server
使用 GETDATE() ; SQLite 使用 DATE()

常用的文本处理函数

函  数 说  明
LEFT() (或使用子字符串函数) 返回字符串左边的字符
LENGTH() (也使用 DATALENGTH() 或 LEN() ) 返回字符串的长度
LOWER() ( Access 使用 LCASE() ) 将字符串转换为小写
LTRIM() 去掉字符串左边的空格
RIGHT() (或使用子字符串函数) 返回字符串右边的字符
RTRIM() 去掉字符串右边的空格
SOUNDEX() 返回字符串的 SOUNDEX 值
UPPER() ( Access 使用 UCASE() ) 将字符串转换为大写

数值处理函数

函  数 说  明
ABS() 返回一个数的绝对值
COS() 返回一个角度的余弦
EXP() 返回一个数的指数值
PI() 返回圆周率
SIN() 返回一个角度的正弦
SQRT() 返回一个数的平方根
TAN() 返回一个角度的正切

9. 聚集函数

SQL 聚集函数

函  数 说  明
AVG() 返回某列的平均值
COUNT() 返回某列的行数
MAX() 返回指定列的最大值
MIN() 返回某列的最小值
SUM() 返回某列值之和

AVG()

警告:只用于单个列

AVG()只能用来确定特定数值列的平均值,而且列名必须作为函数参数给出。为了获得多个列的平均值,必须使用多个AVG()函数。

AVG()函数忽略列值为NULL的行。

count

使用COUNT(*)对表中行的数目进行计数,不管表列中包含的是空值(NULL)还是非空值。

使用COUNT(column)对特定列中具有值的行进行计数,忽略NULL值。

MAX()函数

提示:对非数值数据使用MAX()

虽然MAX()一般用来找出最大的数值或日期值,但许多(并非所有)DBMS允许将它用来返回任意列中的最大值,包括返回文本列中的最大 值。在用于文本数据时,MAX()返回按该列排序后的最后一行。

说明:NULL值

MAX()函数忽略列值为NULL的行。

MIN()函数

SUM()函数

SUM()用来返回指定列值的和(总计)。

10. 分组数据

在使用GROUP BY子句前,需要知道一些重要的规定。

  • GROUP BY子句可以包含任意数目的列,因而可以对分组进行嵌套,更细致地进行数据分组。

  • 如果在GROUP BY子句中嵌套了分组,数据将在最后指定的分组上进行汇总。换句话说,在建立分组时,指定的所有列都一起计算(所以不能从个别的列取回数据)。

  • GROUP BY子句中列出的每一列都必须是检索列或有效的表达式(但不能是聚集函数)。如果在SELECT中使用表达式,则必须在GROUP BY子句中指定相同的表达式。不能使用别名。

  • 大多数SQL实现不允许GROUP BY列带有长度可变的数据类型(如文本或备注型字段)。

  • 除聚集计算语句外,SELECT语句中的每一列都必须在GROUP BY子句中给出。

  • 如果分组列中包含具有NULL值的行,则NULL将作为一个分组返回。如果列中有多行NULL值,它们将分为一组。

  • GROUP BY子句必须出现在WHERE子句之后,ORDER BY子句之前。

过滤分组

HAVING和WHERE的差别

WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤。这是一个重要的区别,WHERE排除的行不包括在分组 中。这可能会改变计算值,从而影响HAVING子句中基于这些值过滤掉的分组。

使用HAVING时应该结合GROUP BY子句,而WHERE子句用于标准的行级过滤。

分组和排序

18. 视图

视图为虚拟的表。它们包含的不是数据而是根据需要检索数据的查询。视图提供了一种封装SELECT语句的层次,可用来简化数据处理,重新格 式化或保护基础数据。

是什么

视图是虚拟的表。与包含数据的表不一样,视图只包含使用时动态检索数据的查询。

为什么

  1. 重用SQL语句。

  2. 简化复杂的SQL操作。在编写查询后,可以方便地重用它而不必知道其基本查询细节。

  3. 使用表的一部分而不是整个表。

  4. 保护数据。可以授予用户访问表的特定部分的权限,而不是整个表的访问权限。

  5. 更改数据格式和表示。视图可返回与底层表的表示和格式不同的数据。

警告:性能问题

因为视图不包含数据,所以每次使用视图时,都必须处理查询执行时需要的所有检索。如果你用多个联结和过滤创建了复杂的视图或者嵌套 了视图,性能可能会下降得很厉害。因此,在部署使用了大量视图的应用前,应该进行测试。

视图的规则和限制

  • 与表一样,视图必须唯一命名(不能给视图取与别的视图或表相同的名字)。

  • 对于可以创建的视图数目没有限制。

  • 创建视图,必须具有足够的访问权限。这些权限通常由数据库管理人员授予。

  • 视图可以嵌套,即可以利用从其他视图中检索数据的查询来构造视图。所允许的嵌套层数在不同的DBMS中有所不同(嵌套视图可能会严

  • 重降低查询的性能,因此在产品环境中使用之前,应该对其进行全面测试)。

  • 许多DBMS禁止在视图查询中使用ORDER BY子句。

  • 有些DBMS要求对返回的所有列进行命名,如果列是计算字段,则需要使用别名(关于列别名的更多信息,请参阅第7课)。

  • 视图不能索引,也不能有关联的触发器或默认值。

  • 有些DBMS把视图作为只读的查询,这表示可以从视图检索数据,但不能将数据写回底层表。详情请参阅具体的DBMS文档。

  • 有些DBMS允许创建这样的视图,它不能进行导致行不再属于视图的插入或更新。例如有一个视图,只检索带有电子邮件地址的顾客。如

  • 果更新某个顾客,删除他的电子邮件地址,将使该顾客不再属于视图。这是默认行为,而且是允许的,但有的DBMS可能会防止这种情况 发生。

视图的使用

创建和删除

视图用CREATE VIEW语句来创建

删除视图,可以使用DROP语句,其语法为DROP VIEW viewname。覆盖(或更新)视图,必须先删除它,然后再重新创建。

作用

  1. 利用视图简化复杂的联结

  2. 用视图重新格式化检索出的数据

  3. 用视图过滤不想要的数据

  4. 使用视图与计算字段

19. 存储过程

可以创建存储过程。简单来说,存储过程就是为以后使用而保存的一条或多条SQL语句。可将其视为批文件,虽然它们的作用不仅限于批处理。

是什么

为什么

  • 通过把处理封装在一个易用的单元中,可以简化复杂的操作(如前面例子所述)。

  • 由于不要求反复建立一系列处理步骤,因而保证了数据的一致性。如果所有开发人员和应用程序都使用同一存储过程,则所使用的代码都是相同的。

  • 这一点的延伸就是防止错误。需要执行的步骤越多,出错的可能性就越大。防止错误保证了数据的一致性。

  • 简化对变动的管理。如果表名、列名或业务逻辑(或别的内容)有变化,那么只需要更改存储过程的代码。使用它的人员甚至不需要知道 这些变化。

  • 这一点的延伸就是安全性。通过存储过程限制对基础数据的访问,减少了数据讹误(无意识的或别的原因所导致的数据讹误)的机会。 因为存储过程通常以编译过的形式存储,所以DBMS处理命令的工作较少,提高了性能。

  • 存在一些只能用在单个请求中的SQL元素和特性,存储过程可以使用它们来编写功能更强更灵活的代码。

换句话说,使用存储过程有三个主要的好处,即简单、安全、高性能。显然,它们都很重要。不过,在将SQL代码转换为存储过程前,也必须

知道它的一些缺陷。

  • 不同DBMS中的存储过程语法有所不同。事实上,编写真正的可移植存储过程几乎是不可能的。不过,存储过程的自我调用(名字以及数 据如何传递)可以相对保持可移植。因此,如果需要移植到别的DBMS,至少客户端应用代码不需要变动。

  • 一般来说,编写存储过程比编写基本SQL语句复杂,需要更高的技能,更丰富的经验。因此,许多数据库管理员把限制存储过程的创建作

为安全措施(主要受上一条缺陷的影响)。

创建

1
2
3
4
5
create procedure productpricing()
BEGIN
SELECT AVG(prod_price) AS priceaverage
FROM products;
END

用CREATE PROCEDURE productpricing()语句定义。如果存储过程接受参数,它们将在()中列举出来。存储过程的代码位于BEGIN和END语句内,

mysql命令行客户机的分隔符

DELIMITER //告诉命令行实用程序使用//作为新的语句结束分隔符,

使用

1
CALL productpricing()

删除

1
2
DROP PROCEDURE productpricing;
DROP PROCEDURE productpricing IF EXISTS;

使用参数

1
2
3
4
5
6
7
8
9
10
create procedure productpricing(
OUT p1 DECIMAL(8, 2),
OUT ph DECIMAL(8, 2),
OUT pa DECIMAL(8, 2)
)
BEGIN
SELECT MIN(prod_price) INTO p1 FROM products;
SELECT MAX(prod_price) INTO ph FROM products;
SELECT AVG(prod_price) INTO pa FROM products
END;

每个参数必须具有指定的类型,这里使用十进制值(DECIMAL 关键字)。关键字OUT指出相应的参数用来从存储过程传出一个值(返回给调用者)。MySQL支持IN(传递给存储过程)、OUT(从存储过程传出,如这里所用)和INOUT(对存储过程传入和传出)类型的参数。

使用

1
2
CALL productpricing(@procelow, @pricehigh, @priceAverage);
SELECT @procelow;

变量名: 所有MySQL变量都必须以@开始。

建立智能存储过程

只有在存储过程内包含业务规则和智能处理时,它们的威力才真正显现出来。

用DECLARE语句定义了两个局部变量。DECLARE要求指定变量名和数据类型,它也支持可选的默认值.

COMMENT关键字 本例子中的存储过程在CREATE PROCEDURE语
句中包含了一个COMMENT值。它不是必需的,但如果给出,将
在SHOW PROCEDURE STATUS的结果中显示。

检查存储过程

1
2
3
4
# 显示用来创建一个存储过程的CREATE语句
SHOW CREATE PROCEDURE ordertotal;
# 了获得包括何时、由谁创建等详细信息的存储过程列表
SHOW STATUS PROCEDURE ordertotal;

20. 管理事务处理

为什么

使用事务处理(transaction processing),通过确保成批的SQL操作要么完全执行,要么完全不执行,来维护数据库的完整

  • 事务(transaction)指一组SQL语句;
  • 回退(rollback)指撤销指定SQL语句的过程;
  • 提交(commit)指将未存储的SQL语句结果写入数据库表;
  • 保留点(savepoint)指事务处理中设置的临时占位符(placeholder),可以对它发布回退(与回退整个事务处理不同)

控制事务处理

管理事务处理的关键在于将SQL语句组分解为逻辑块,并明确规定数据何时应该回退,何时不应该回退。

1
2
3
4
5
6
7
8
9
10
11
12
# 开始事务
start transaction

# 回退
ROLLBACK

# 提交
COMMIT

# 保留点, 部分回退
SAVEPOINT point1;
ROLLBACK TO point1

ROLLBACK命令用来回退(撤销)MySQL语句

ROLLBACK** 只能在一个事务处理内使用(在执行一条STARTTRANSACTION命令之后)。

一般的MySQL语句都是直接针对数据库表执行和编写的。这就是所谓的隐含提交(implicit commit),即提交(写或保存)操作是自动进行的。

​ 但是,在事务处理块中,提交不会隐含地进行。为进行明确的提交,使用COMMIT语句.

隐含事务关闭 :当COMMIT或ROLLBACK语句执行后,事务会自动关闭(将来的更改会隐含提交)

保留点越多越好可以在SQL代码中设置任意多的保留点,越多越好。为什么呢?因为保留点越多,你就越能灵活地进行回退。

21. 使用游标

结果集(result set)SQL查询所检索出的结果。

为什么

有时,需要在检索出来的行中前进或后退一行或多行,这就是游标的用途所在。

是什么

游标(cursor)是一个存储在DBMS服务器上的数据库查询, 它不是一条SELECT语句,而是被该语句检索出来的结果集。

选项和特性

  • 能够标记游标为只读,使数据能读取,但不能更新和删除。

  • 能控制可以执行的定向操作(向前、向后、第一、最后、绝对位置、相对位置等)。

  • 能标记某些列为可编辑的,某些列为不可编辑的。

  • 规定范围,使游标对创建它的特定请求(如存储过程)或对所有请求可访问。

  • 指示DBMS对检索出的数据(而不是指出表中活动数据)进行复制,使数据在游标打开和访问期间不变化。

说明:游标与基于Web的应用

使用游标

步骤:

  1. 在使用游标前,必须声明(定义)它。这个过程实际上没有检索数据,它只是定义要使用的SELECT语句和游标选项。

  2. 一旦声明,就必须打开游标以供使用。这个过程用前面定义的SELECT语句把数据实际检索出来。

  3. 对于填有数据的游标,根据需要取出(检索)各行。

  4. 在结束游标使用时,必须关闭游标,可能的话,释放游标(有赖于具体的DBMS)。

使用DECLARE语句创建游标

创建

使用

22. 高级SQL特性

约束

是什么

约束(constraint) 管理如何插入或处理数据库数据的规则。

包括:主键、外键、唯一约束、检查约束

主键

满足条件:

  • 任意两行的主键值都不相同。

  • 每行都具有一个主键值(即列中不允许NULL值)。

  • 包含主键值的列从不修改或更新。(大多数DBMS不允许这么做,但如果你使用的DBMS允许这样做,好吧,千万别!)

  • 主键值不能重用。如果从表中删除某一行,其主键值不分配给新行。

指定列为主键: PRIMARY KEY

外键

外键是表中的一列,其值必须列在另一表的主键中。外键是保证引用完整性的极其重要部分。

外键有助防止意外删除

唯一约束

主键和唯一约束区别:

  • 表可包含多个唯一约束,但每个表只允许一个主唯一约束列可包含NULL值。
  • 唯一约束列可修改或更新。
  • 唯一约束列的值可重复使用。与
  • 主键不一样,唯一约束不能用来定义外键。

检查约束

检查约束用来保证一列(或一组列)中的数据满足一组指定的条件。检查约束的常见用途有以下几点。

  • 检查最小或最大值。例如,防止0个物品的订单(即使0是合法的数)。

  • 指定范围。例如,保证发货日期大于等于今天的日期,但不超过今天起一年后的日期。

  • 只允许特定的值。例如,在性别字段中只允许M或F。

索引

触发器

是什么:触发器是特殊的存储过程,它在特定的数据库活动发生时自动执行。

一般来说,约束的处理比触发器快,因此在可能的时候,应该尽量使用约束。

数据库安全

  • 对数据库管理功能(创建表、更改或删除已存在的表等)的访问;

  • 对特定数据库或表的访问;

  • 访问的类型(只读、对特定列的访问等);

  • 仅通过视图或存储过程对表进行访问;

  • 创建多层次的安全措施,从而允许多种基于登录的访问和控制;

  • 限制管理用户账号的能力。

关键字

关键字 作用 附加说明
SELECT 要返回的列或表达式
FROM 从中检索数据的表
WHERE 指定搜索条件进行过滤(行级过滤) 范围值检查:BETWEEN xx AND xx
指定条件范围:IN(xx, xx)
否定其后条件:NOT
GROUP BY 分组 组级过滤:HAVING
ORDER BY 输出排序顺序 降序:DESC (DESCENDING)
升序(默认):ASC(ASCENDING)
DISTINCT distinct
IS NULL 非空检查
AND 、OR 逻辑操作符
LIKE
  1. distinct

    它指示数据库只返回不同的值。

    eg:SELECT DISTINCT vend_id FROM Products;

    警告:不能部分使用 DISTINCT
    DISTINCT关键字作用于所有的列,不仅仅是跟在其后的那一列。例如,你指定SELECT DISTINCT vend_id, prod_price,除非指定的两列完
    全相同,否则所有的行都会被检索出来。

redis配置文件

发表于 2019-07-18 | 更新于 2021-03-06

配置文件

源于redis版本 3.2.1,可能和最新版本略有差异。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
######################### 引用 #########################

# 不同redis server可以使用同一个模版配置作为主配置,并引用其它配置文件用于本server的个性# 化设置
# include并不会被CONFIG REWRITE命令覆盖。但是主配置文件的选项会被覆盖。
# 想故意覆盖主配置的话就把include放文件前面,否则最好放末尾
# include /path/to/local.conf
# include /path/to/other.conf

######################### 网络 #########################

# 不指定bind的话redis将会监听所有网络接口。这个配置是肯定需要指定的。
# Examples:
# bind 192.168.1.100 10.0.0.1
# bind 127.0.0.1 ::1
# 下面这个配置是只允许本地客户端访问。
bind 127.0.0.1

# 是否开启保护模式。默认开启,如果没有设置bind项的ip和redis密码的话,服务将只允许本地访 问。
protected-mode yes

# 端口设置,默认为 6379
# 如果port设置为0 redis将不会监听tcp socket
port 6379

# 在高并发环境下需要一个高backlog值来避免慢客户端连接问题。注意Linux内核默默将这个值减小到/proc/sys/net/core/somaxconn的值,所以需要确认增大somaxconn和tcp_max_syn_backlog 两个值来达到需要的效果。
tcp-backlog 511

# 指定用来监听Unix套套接字的路径。没有默认值,没有指定的情况下Redis不会监听Unix socket
# unixsocket /tmp/redis.sock
# unixsocketperm 700

# 客户端空闲多少秒后关闭连接(0为不关闭)timeout 0# tcp-keepalive设置。如果非零,则设置SO_KEEPALIVE选项来向空闲连接的客户端发送ACK,用途如下:
# 1)能够检测无响应的对端
# 2)让该连接中间的网络设备知道这个连接还存活
# 在Linux上,这个指定的值(单位秒)就是发送ACK的时间间隔。
# 注意:要关闭这个连接需要两倍的这个时间值。
# 在其他内核上这个时间间隔由内核配置决定# 从redis3.2.1开始默认值为300秒
tcp-keepalive 300

######################### 通用 #########################

# 是否将Redis作为守护进程运行。如果需要的话配置成'yes'
# 注意配置成守护进程后Redis会将进程号写入文件/var/run/redis.pid
daemonize no

# 是否通过upstart或systemd管理守护进程。默认no没有服务监控,其它选项有upstart, systemd, auto
supervised no

# pid文件在redis启动时创建,退出时删除。最佳实践为配置该项。
pidfile /var/run/redis_6379.pid

# 配置日志级别。选项有debug, verbose, notice, warning
loglevel notice

# 日志名称。空字符串表示标准输出。注意如果redis配置为后台进程,标准输出中信息会发送到/dev/null
logfile ""

# 是否启动系统日志记录。
# syslog-enabled no

# 指定系统日志身份。
# syslog-ident redis

# 指定syslog设备。必须是user或LOCAL0 ~ LOCAL7之一。
# syslog-facility local0

# 设置数据库个数。默认数据库是 DB 0
# 可以通过SELECT where dbid is a number between 0 and 'databases'-1为每个连接使用不同的数据库。
databases 16

######################### 备份  #########################
# 持久化设置:
# 下面的例子将会进行把数据写入磁盘的操作:
#  900秒(15分钟)之后,且至少1次变更
#  300秒(5分钟)之后,且至少10次变更
#  60秒之后,且至少10000次变更
# 不写磁盘的话就把所有 "save" 设置注释掉就行了。
# 通过添加一条带空字符串参数的save指令也能移除之前所有配置的save指令,如: save ""
save 900 1
save 300 10
save 60 10000

# 默认情况下如果上面配置的RDB模式开启且最后一次的保存失败,redis 将停止接受写操作,让用户知道问题的发生。
# 如果后台保存进程重新启动工作了,redis 也将自动的允许写操作。如果有其它监控方式也可关闭。
stop-writes-on-bgsave-error yes

# 是否在备份.rdb文件时是否用LZF压缩字符串,默认设置为yes。如果想节约cpu资源可以把它设置为no。
rdbcompression yes

# 因为版本5的RDB有一个CRC64算法的校验和放在了文件的末尾。这将使文件格式更加可靠,
# 但在生产和加载RDB文件时,这有一个性能消耗(大约10%),可以关掉它来获取最好的性能。
# 生成的关闭校验的RDB文件有一个0的校验和,它将告诉加载代码跳过检查rdbchecksum yes
# rdb文件名称
dbfilename dump.rdb

# 备份文件目录,文件名就是上面的 "dbfilename" 的值。累加文件也放这里。
# 注意你这里指定的必须是目录,不是文件名。
dir /Users/wuji/redis_data/

######################### 主从同步 #########################

# 主从同步配置。
# 1) redis主从同步是异步的,但是可以配置在没有指定slave连接的情况下使master停止写入数据。
# 2) 连接中断一定时间内,slave可以执行部分数据重新同步。
# 3) 同步是自动的,slave可以自动重连且同步数据。
# slaveof <masterip> <masterport>

# master连接密码
# masterauth <master-password>

# 当一个slave失去和master的连接,或者同步正在进行中,slave的行为有两种可能:
# 1) 如果 slave-serve-stale-data 设置为 "yes" (默认值),slave会继续响应客户端请求,可能是正常数据,也可能是还没获得值的空数据。
# 2) 如果 slave-serve-stale-data 设置为 "no",slave会回复"正在从master同步(SYNC with master in progress)"来处理各种请求,除了 INFO 和 SLAVEOF 命令。
slave-serve-stale-data yes

# 你可以配置salve实例是否接受写操作。可写的slave实例可能对存储临时数据比较有用(因为写入salve# 的数据在同master同步之后将很容被删除),但是如果客户端由于配置错误在写入时也可能产生一些问题。
# 从Redis2.6默认所有的slave为只读
# 注意:只读的slave不是为了暴露给互联网上不可信的客户端而设计的。它只是一个防止实例误用的保护层。
# 一个只读的slave支持所有的管理命令比如config,debug等。为了限制你可以用'rename-command'来隐藏所有的管理和危险命令来增强只读slave的安全性。
slave-read-only yes

# 同步策略: 磁盘或socket,默认磁盘方式
repl-diskless-sync no

# 如果非磁盘同步方式开启,可以配置同步延迟时间,以等待master产生子进程通过socket传输RDB数据给slave。
# 默认值为5秒,设置为0秒则每次传输无延迟。
repl-diskless-sync-delay 5

# slave根据指定的时间间隔向master发送ping请求。默认10秒。
# repl-ping-slave-period 10

# 同步的超时时间
# 1)slave在与master SYNC期间有大量数据传输,造成超时
# 2)在slave角度,master超时,包括数据、ping等
# 3)在master角度,slave超时,当master发送REPLCONF ACK pings# 确保这个值大于指定的repl-ping-slave-period,否则在主从间流量不高时每次都会检测到超时
# repl-timeout 60

# 是否在slave套接字发送SYNC之后禁用 TCP_NODELAY
# 如果选择yes,Redis将使用更少的TCP包和带宽来向slaves发送数据。但是这将使数据传输到slave上有延迟,Linux内核的默认配置会达到40毫秒。
# 如果选择no,数据传输到salve的延迟将会减少但要使用更多的带宽。
# 默认我们会为低延迟做优化,但高流量情况或主从之间的跳数过多时,可以设置为“yes”。
repl-disable-tcp-nodelay no

# 设置数据备份的backlog大小。backlog是一个slave在一段时间内断开连接时记录salve数据的缓冲,所以一个slave在重新连接时,不必要全量的同步,而是一个增量同步就足够了,将在断开连接的这段# 时间内把slave丢失的部分数据传送给它。
# 同步的backlog越大,slave能够进行增量同步并且允许断开连接的时间就越长。
# backlog只分配一次并且至少需要一个slave连接。
# repl-backlog-size 1mb

# 当master在一段时间内不再与任何slave连接,backlog将会释放。以下选项配置了从最后一个
# slave断开开始计时多少秒后,backlog缓冲将会释放。
# 0表示永不释放backlog
# repl-backlog-ttl 3600

# slave的优先级是一个整数展示在Redis的Info输出中。如果master不再正常工作了,sentinel将用它来选择一个slave提升为master。
# 优先级数字小的salve会优先考虑提升为master,所以例如有三个slave优先级分别为10,100,25,sentinel将挑选优先级最小数字为10的slave。
# 0作为一个特殊的优先级,标识这个slave不能作为master,所以一个优先级为0的slave永远不会被# sentinel挑选提升为master。
# 默认优先级为100
slave-priority 100

# 如果master少于N个延时小于等于M秒的已连接slave,就可以停止接收写操作。
# N个slave需要是“oneline”状态。
# 延时是以秒为单位,并且必须小于等于指定值,是从最后一个从slave接收到的ping(通常每秒发送)开始计数。
# 该选项不保证N个slave正确同步写操作,但是限制数据丢失的窗口期。
# 例如至少需要3个延时小于等于10秒的slave用下面的指令:
# min-slaves-to-write 3
# min-slaves-max-lag 10

# 两者之一设置为0将禁用这个功能。
# 默认 min-slaves-to-write 值是0(该功能禁用)并且 min-slaves-max-lag 值是10。

######################### 安全 #########################

# 要求客户端在处理任何命令时都要验证身份和密码。
# requirepass foobared

# 命令重命名
# 在共享环境下,可以为危险命令改变名字。比如,你可以为 CONFIG 改个其他不太容易猜到的名字,这样内部的工具仍然可以使用。
# 例如:
# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52
# 也可以通过改名为空字符串来完全禁用一个命令
# rename-command CONFIG ""
# 请注意:改变命令名字被记录到AOF文件或被传送到从服务器可能产生问题。

######################### 限制 #########################

# 设置最多同时连接的客户端数量。默认这个限制是10000个客户端,然而如果Redis服务器不能配置
# 处理文件的限制数来满足指定的值,那么最大的客户端连接数就被设置成当前文件限制数减32(因为Redis服务器保留了一些文件描述符作为内部使用)
# 一旦达到这个限制,Redis会关闭所有新连接并发送错误'max number of clients reached'
# maxclients 10000

# 不要使用比设置的上限更多的内存。一旦内存使用达到上限,Redis会根据选定的回收策略(参见:maxmemmory-policy)删除key。
# 如果因为删除策略Redis无法删除key,或者策略设置为 "noeviction",Redis会回复需要更多内存的错误信息给命令。例如,SET,LPUSH等等,但是会继续响应像Get这样的只读命令。
# 在使用Redis作为LRU缓存,或者为实例设置了硬性内存限制的时候(使用 "noeviction" 策略)
#的时候,这个选项通常事很有用的。
# 警告:当有多个slave连上达到内存上限时,master为同步slave的输出缓冲区所需内存不计算在使用内存中。这样当移除key时,就不会因网络问题 / 重新同步事件触发移除key的循环,反过来slaves的输出缓冲区充满了key被移除的DEL命令,这将触发删除更多的key,直到这个数据库完全被清空为止。
# 总之,如果你需要附加多个slave,建议你设置一个稍小maxmemory限制,这样系统就会有空闲的内存作为slave的输出缓存区(但是如果最大内存策略设置为"noeviction"的话就没必要了)
# maxmemory <bytes>

# 最大内存策略:如果达到内存限制了,Redis如何选择删除key。
# volatile-lru -> 根据LRU算法删除设置过期时间的key
# allkeys-lru -> 根据LRU算法删除任何key
# volatile-random -> 随机移除设置过过期时间的key
# allkeys-random -> 随机移除任何key
# volatile-ttl -> 移除即将过期的key(minor TTL)
# noeviction -> 不移除任何key,只返回一个写错误
# 注意:对所有策略来说,如果Redis找不到合适的可以删除的key都会在写操作时返回一个错误。# 目前为止涉及的命令:set setnx setex append incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby getset mset msetnx exec sort
# 默认策略:
# maxmemory-policy noeviction

# LRU和最小TTL算法的实现都不是很精确,但是很接近(为了省内存),所以你可以用样本量做检测。 例如:默认Redis会检查3个key然后取最旧的那个,你可以通过下面的配置指令来设置样本的个数。
# 默认值为5,数字越大结果越精确但是会消耗更多CPU。
# maxmemory-samples 5

######################### APPEND ONLY MODE #########################

# 默认情况下,Redis是异步的把数据导出到磁盘上。这种模式在很多应用里已经足够好,但Redis进程出问题或断电时可能造成一段时间的写操作丢失(这取决于配置的save指令)。
# AOF是一种提供了更可靠的替代持久化模式,例如使用默认的数据写入文件策略(参见后面的配置)。
# 在遇到像服务器断电或单写情况下Redis自身进程出问题但操作系统仍正常运行等突发事件时,Redis能只丢失1秒的写操作。
# AOF和RDB持久化能同时启动并且不会有问题。
# 如果AOF开启,那么在启动时Redis将加载AOF文件,它更能保证数据的可靠性。
appendonly no

# AOF文件名(默认:"appendonly.aof")
appendfilename "appendonly.aof"

# fsync() 系统调用告诉操作系统把数据写到磁盘上,而不是等更多的数据进入输出缓冲区。
# 有些操作系统会真的把数据马上刷到磁盘上;有些则会尽快去尝试这么做。
# Redis支持三种不同的模式:
# no:不要立刻刷,只有在操作系统需要刷的时候再刷。比较快。
# always:每次写操作都立刻写入到aof文件。慢,但是最安全。
# everysec:每秒写一次。折中方案。
# 默认的 "everysec" 通常来说能在速度和数据安全性之间取得比较好的平衡。
# appendfsync always
appendfsync everysec
# appendfsync no

# 如果AOF的同步策略设置成 "always" 或者 "everysec",并且后台的存储进程(后台存储或写入AOF 日志)会产生很多磁盘I/O开销。某些Linux的配置下会使Redis因为 fsync()系统调用而阻塞很久。
# 注意,目前对这个情况还没有完美修正,甚至不同线程的 fsync() 会阻塞我们同步的write(2)调用。
# 为了缓解这个问题,可以用下面这个选项。它可以在 BGSAVE 或 BGREWRITEAOF 处理时阻止fsync()。
# 这就意味着如果有子进程在进行保存操作,那么Redis就处于"不可同步"的状态。
# 这实际上是说,在最差的情况下可能会丢掉30秒钟的日志数据。(默认Linux设定)
# 如果把这个设置成"yes"带来了延迟问题,就保持"no",这是保存持久数据的最安全的方式。
no-appendfsync-on-rewrite no

# 自动重写AOF文件。如果AOF日志文件增大到指定百分比,Redis能够通过 BGREWRITEAOF 自动重写AOF日志文件。# 工作原理:Redis记住上次重写时AOF文件的大小(如果重启后还没有写操作,就直接用启动时的AOF大小)
# 这个基准大小和当前大小做比较。如果当前大小超过指定比例,就会触发重写操作。你还需要指定被重写日志的最小尺寸,这样避免了达到指定百分比但尺寸仍然很小的情况还要重写。
# 指定百分比为0会禁用AOF自动重写特性。
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# 如果设置为yes,如果一个因异常被截断的AOF文件被redis启动时加载进内存,redis将会发送日志通知用户。如果设置为no,erdis将会拒绝启动。此时需要用"redis-check-aof"工具修复文件。
aof-load-truncated yes

######################### 集群 #########################

# 只有开启了以下选项,redis才能成为集群服务的一部分
# cluster-enabled yes

# 配置redis自动生成的集群配置文件名。确保同一系统中运行的各redis实例该配置文件不要重名。
# cluster-config-file nodes-6379.conf

# 集群节点超时毫秒数。超时的节点将被视为不可用状态。
# cluster-node-timeout 15000

# 如果数据太旧,集群中的不可用master的slave节点会避免成为备用master。如果slave和master失联时间超过:
 (node-timeout * slave-validity-factor) + repl-ping-slave-period
则不会被提升为master。
# 如node-timeout为30秒,slave-validity-factor为10, 默认default repl-ping-slave-period为10秒,失联时间超过310秒slave就不会成为master。
# 较大的slave-validity-factor值可能允许包含过旧数据的slave成为master,同时较小的值可能会阻止集群选举出新master。
#为了达到最大限度的高可用性,可以设置为0,即slave不管和master失联多久都可以提升为master
# cluster-slave-validity-factor 10

# 只有在之前master有其它指定数量的工作状态下的slave节点时,slave节点才能提升为master。默认为1(即该集群至少有3个节点,1 master+2 slaves,master宕机,仍有另外1个slave的情况下其中1个slave可以提升)
# 测试环境可设置为0,生成环境中至少设置为1
# cluster-migration-barrier 1

# 默认情况下如果redis集群如果检测到至少有1个hash slot不可用,集群将停止查询数据。
# 如果所有slot恢复则集群自动恢复。
# 如果需要集群部分可用情况下仍可提供查询服务,设置为no。
# cluster-require-full-coverage yes

######################### 慢查询日志 #########################

# 慢查询日志,记录超过多少微秒的查询命令。查询的执行时间不包括客户端的IO执行和网络通信时间,只是查询命令执行时间。
# 1000000等于1秒,设置为0则记录所有命令
slowlog-log-slower-than 10000

# 记录大小,可通过SLOWLOG RESET命令重置
slowlog-max-len 128

RedisBloom 布隆过滤器

发表于 2019-07-18 | 更新于 2021-03-06

RedisBloom 安装

参考:https://oss.redislabs.com/redisbloom/

1
2
3
4
5
6
# branch参数指定克隆的tag。
git clone --branch v2.0.2 https://github.com/RedisBloom/RedisBloom.git
cd RedisBloom
make
# loadmodule 加载自定义module,也可以在redis.conf中
src/redis-server --loadmodule .RedisBloom/redisbloom.so

RedisBloom命令

1
2
3
4
5
6
7
8
# 设置
BF.RESERVE {key} {error_rate} {capacity}
# 添加
BF.ADD {key} {item}
BF.MADD {key} {item} [item...]
# 检验是否存在
BF.EXISTS {key} {item}
BF.MEXISTS {key} {item} [item...]

redis

发表于 2019-07-10 | 更新于 2021-03-06

安装

1
2
3
4
5
6
7
8
9
# 安装依赖
sudo apt install make gcc
# 下载安装
wget http://download.redis.io/releases/redis-5.0.5.tar.gz
tar xzf redis-5.0.5.tar.gz
cd redis-5.0.5
make MALLOC=libc
# 修改配置文件redis.conf,启动
src/redis-server redis.conf

redis-cli 命令

1
2
3
4
auth Cnitsec%4321
#取从位置0开始到位置2结束的3个元素。
lrange mykey 0 2
llen mykey

Redis 启动时出现警告的解决办法

1
2
3
4
7283:M 12 Mar 12:13:33.749 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
7283:M 12 Mar 12:13:33.749 # Server started, Redis version 3.0.7
7283:M 12 Mar 12:13:33.749 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
7283:M 12 Mar 12:13:33.749 * The server is now ready to accept connections on port 6379

第1个警告(WARNING: The TCP backlog setting of 511 ……)解决办法

方法1: 临时设置生效:

sysctl -w net.core.somaxconn = 1024

方法2: 永久生效:

1
2
3
4
# 修改/etc/sysctl.conf文件,增加一行
net.core.somaxconn= 1024
# 然后执行命令
sysctl -p

补充:
net.core.somaxconn是linux中的一个kernel参数,表示socket监听(listen)的backlog上限。
backlog是socket的监听队列,当一个请求(request)尚未被处理或建立时,他会进入backlog。
而socket server可以一次性处理backlog中的所有请求,处理后的请求不再位于监听队列中。
当server处理请求较慢,以至于监听队列被填满后,新来的请求会被拒绝。
所以说net.core.somaxconn限制了接收新 TCP 连接侦听队列的大小。
对于一个经常处理新连接的高负载 web服务环境来说,默认的 128 太小了。大多数环境这个值建议增加到 1024 或者更多。

第2个警告(WARNING overcommit_memory is set to 0! ……)同样也有两个解决办法

方法1: 临时设置生效:

sysctl -w vm.overcommit_memory = 1

1
2
3
4
# 方法2: 永久生效: 修改/etc/sysctl.conf文件,增加一行
vm.overcommit_memory = 1
# 然后执行命令
sysctl -p

补充:

overcommit_memory参数说明:
设置内存分配策略(可选,根据服务器的实际情况进行设置)
/proc/sys/vm/overcommit_memory
可选值:0、1、2。
0, 表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。
1, 表示内核允许分配所有的物理内存,而不管当前的内存状态如何。
2, 表示内核允许分配超过所有物理内存和交换空间总和的内存
注意:redis在dump数据的时候,会fork出一个子进程,理论上child进程所占用的内存和parent是一样的,比如parent占用的内存为8G,这个时候也要同样分配8G的内存给child,如果内存无法负担,往往会造成redis服务器的down机或者IO负载过高,效率下降。所以这里比较优化的内存分配策略应该设置为 1(表示内核允许分配所有的物理内存,而不管当前的内存状态如何)。

windows zip包安装

发表于 2019-07-10 | 更新于 2021-03-06

windows zip包安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.\mysqld.exe --initialize-insecure --user=mysql
.\mysqld.exe install
net start mysql
mysql -ruoo -p
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'lkg123456' WITH GRANT OPTION;
flush privileges;

show variables like '%character%';

--defaults-file="C:\Software\mysql-5.7.23-winx64\my-default.ini"


# window 删除
4》运行“regedit”文件,打开注册表。
删除HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Eventlog\Application\MySQL文件夹
删除HKEY_LOCAL_MACHINE\SYSTEM\ControlSet002\Services\Eventlog\Application\MySQL文件夹。
删除HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application\MySQL的文件夹。
如果没有相应的文件夹,就不用删除了。

my-default.ini样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[mysqld]
port=3306
#这一句解决有IPV6协议的计算机上默认采用IPV6协议导致无法从程序连接数据库的问题
bind-address=127.0.0.1
# 允许最大连接数
max_connections = 200
# 服务端使用的字符集默认为8比特编码的latin1字符集
character-set-server = utf8mb4
# 创建新表时将使用的默认存储引擎
default-storage-engine = INNODB

[client]
# 设置mysql客户端默认字符集
default-character-set = utf8mb4

BeautifulSoup

发表于 2019-05-31 | 更新于 2021-03-06

对象的种类

Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种: Tag , NavigableString , BeautifulSoup , Comment .

java位运算符

发表于 2019-05-30 | 更新于 2021-03-06 | 分类于 java基础

关于java中位运算符的使用和理解

&(按位与)

‘ & ’ 符号的作用是对运算符的两侧以二进制表达的操作符按位进行‘与’运算。
规则:
只有两个操作数对应位同为1时,结果为1,其余全为0. (或者是只要有一个操作数为0,结果就为0)。

个人理解:在编程中,我们可以认为‘1’代表‘true’,‘0’代表‘false’。那么就可以理解为只有都为‘true’的时候才为‘true’,否则就是‘false’。

举例:
5 & 10 = ?

10 的二进制为:1010

5 的二进制为:0101

则 5 & 10 的二进制为 0000,完整的运算为 5 & 10 = 0

int i = 12; i &= 7; i = ?
‘ &= ’ 的逻辑跟 ‘ += ’ 的处理逻辑是一样的
i &= 7 可以看成 i = i & 7
所以i = 4

|(按位或)

‘ | ’ 符号的作用是对运算符两侧以二进制表达的操作符按位分别进行’或’运算。
规则:
只有两个操作数对应位同为1时,结果为1,其余全为0. (或者是只要有一个操作数为1,结果就为1)。

个人理解:在编程中,我们可以认为‘1’代表‘true’,‘0’代表‘false’。那么就可以理解为只要有一个为‘true’的时候就为‘true’,否则就是‘false’。

举例:
5 | 10 = ?

10 的二进制为:1010

5 的二进制为:0101

则 5 | 10 的二进制为 1111,完整的运算为 5 | 10 = 15

int i = 12; i |= 7; i = ?
‘ |= ’ 的逻辑跟 ‘ += ’ 的处理逻辑是一样的
i |= 7 可以看成 i = i | 7
所以i = 15

^(按位异或)

‘ ^ ’ 符号的作用是对运算符两侧以二进制表达的操作数按位分别进行’异或’运算。
规则:
仅当两个操作数不同一时候。对应的输出结果才为1,否则为0。

个人理解:在编程中,我们可以认为‘1’代表‘true’,‘0’代表‘false’。那么就可以理解为值不相等的时候为‘true’,值相等的时候为‘false’。

举例:
5 ^ 10 = ?

10 的二进制为:1010

5 的二进制为:0101

则 5 ^ 10 的二进制为 1111,完整的运算为 5 ^ 10 = 15

int i = 12; i ^= 7; i = ?
‘ ^= ’ 的逻辑跟 ‘ += ’ 的处理逻辑是一样的
i ^= 7 可以看成 i = i ^ 7
所以i = 11

~(按位非)

‘ ~ ’ 符号的作用是将各位数组取反。
规则:
全部的0变为1,1变为0。

个人理解:在编程中,我们可以认为‘1’代表‘true’,‘0’代表‘false’。那么就可以理解为将‘true’变成‘false’,而‘false’变为‘true’。

举例:
~ 10 = ?

10 的二进制为:1010

取反后为:1111 1111 1111 0101

则 1111 1111 1111 0101 的十进制为 -11,完整的运算为 ~ 10 = -11

很多人对负数的二进制的转换很迷惑,在这里为大家讲解下:
因为电脑的世界中只有 ‘ 1 ’ 和 ‘ 0 ’ ,所以在表示正负数的时候是从最高位看的,最高位如果为 ‘ 1 ’ 则为负数,如果是 ‘ 0 ’ 则是正数。
但是如果负数单纯是把最高位变为1的话,在运算中会出现不是我们想要的值。所以引入了:‘原码’,‘反码’,‘补码’。
正数的‘原码’,‘反码’,‘补码’都一样。
负数的‘反码’是对除了符号位(最高位)的‘原码’取反,而‘补码’是对‘反码’ + 1,而计算机所采用的就是‘补码’的方式。
示例:
-11的‘原码’是 : 1000 0000 0000 1011
求出对应的反码 : 1111 1111 1111 0100
求出对应的补码 : 1111 1111 1111 0101
所以在计算机中 ‘ -11 ’ 对应的二进制为 ‘ 1111 1111 1111 0101 ’

<<(左位移运算符)

‘ << ’ 符号的作用是将一个运算对象的各二进制位全部左移若干位。
规则:
左边的二进制位丢弃,右边补0。

个人理解:左移可以看成是乘以2的多少次方。3 << 3就代表3乘以2的3次方。

举例:
10 << 3 = ?

10 的二进制为:0000 0000 0000 1010

移位后为:0000 0000 0101 0000 (80)

则 10 << 3 = 80

int i = 5; i <<= 4; i = ?
‘ <<= ’ 的逻辑跟 ‘ += ’ 的处理逻辑是一样的
i <<= 4 可以看成 i = i << 4
所以i = 80

>>(右位移运算符)

‘ >> ’ 符号的作用是将一个运算对象的各二进制位全部右移若干位。
规则:
正数左补0,负数左补1,右边丢弃。

个人理解:正数右移可以看成是跟2的多少次方取模,10 >> 3就代表10跟8取模得1。而负数则需要对应的转换,因为负数进行了补码的操作,所以跟正数的逻辑不同

举例:
10 >> 3 = ?

10 的二进制为:0000 0000 0000 1010

移位后为:0000 0000 0000 0001

则 10 >> 3 = 1

int i = 5; i >>= 4; i = ?
‘ >>= ’ 的逻辑跟 ‘ += ’ 的处理逻辑是一样的
i >>= 4 可以看成 i = i >> 4
所以i = 0

>>>(无符号右位移运算符)

‘ >>> ’ 符号的作用是将一个运算对象的各二进制位全部右移若干位。
规则:
右移后左边空出的位用零来填充。移出右边的位被丢弃。无符号的意思是将符号位当作数字位看待。

个人理解:正数的无符号右移可以看成是跟2的多少次方取模,10 >>> 3就代表10跟8取模得1。而负数的无符号右移是不同的,就不需要再进行转换的操作,-1 >>> 1 = 2147483647

举例:
10 >>> 3 = ?

10 的二进制为:0000 0000 0000 1010

移位后为:0000 0000 0000 0001

则 10 >>> 3 = 1

int i = 5; i >>>= 4; i = ?
‘ >>>= ’ 的逻辑跟 ‘ += ’ 的处理逻辑是一样的
i >>>= 4 可以看成 i = i >>> 4
所以i = 0

unit

发表于 2019-05-29 | 更新于 2021-03-06

unit配置文件的区块

[Unit]区块通常是配置文件的第一个区块,用来定义 Unit 的元数据,以及配置与其他 Unit 的关系。它的主要字段如下。

  • Description:简短描述
  • Documentation:文档地址
  • Requires:当前 Unit 依赖的其他 Unit,如果它们没有运行,当前 Unit 会启动失败
  • Wants:与当前 Unit 配合的其他 Unit,如果它们没有运行,当前 Unit 不会启动失败
  • BindsTo:与Requires类似,它指定的 Unit 如果退出,会导致当前 Unit 停止运行
  • Before:如果该字段指定的 Unit 也要启动,那么必须在当前 Unit 之后启动
  • After:如果该字段指定的 Unit 也要启动,那么必须在当前 Unit 之前启动
  • Conflicts:这里指定的 Unit 不能与当前 Unit 同时运行
  • Condition...:当前 Unit 运行必须满足的条件,否则不会运行
  • Assert...:当前 Unit 运行必须满足的条件,否则会报启动失败

[Install]通常是配置文件的最后一个区块,用来定义如何启动,以及是否开机启动。它的主要字段如下。

  • WantedBy:它的值是一个或多个 Target,当前 Unit 激活时(enable)符号链接会放入/etc/systemd/system目录下面以 Target 名 + .wants后缀构成的子目录中
  • RequiredBy:它的值是一个或多个 Target,当前 Unit 激活时,符号链接会放入/etc/systemd/system目录下面以 Target 名 + .required后缀构成的子目录中
  • Alias:当前 Unit 可用于启动的别名
  • Also:当前 Unit 激活(enable)时,会被同时激活的其他 Unit

[Service]区块用来 Service 的配置,只有 Service 类型的 Unit 才有这个区块。它的主要字段如下。

  • Type:定义启动时的进程行为。它有以下几种值。
  • Type=simple:默认值,执行ExecStart指定的命令,启动主进程
  • Type=forking:以 fork 方式从父进程创建子进程,创建后父进程会立即退出
  • Type=oneshot:一次性进程,Systemd 会等当前服务退出,再继续往下执行
  • Type=dbus:当前服务通过D-Bus启动
  • Type=notify:当前服务启动完毕,会通知Systemd,再继续往下执行
  • Type=idle:若有其他任务执行完毕,当前服务才会运行
  • ExecStart:启动当前服务的命令
  • ExecStartPre:启动当前服务之前执行的命令
  • ExecStartPost:启动当前服务之后执行的命令
  • ExecReload:重启当前服务时执行的命令
  • ExecStop:停止当前服务时执行的命令
  • ExecStopPost:停止当其服务之后执行的命令
  • RestartSec:自动重启当前服务间隔的秒数
  • Restart:定义何种情况 Systemd 会自动重启当前服务,可能的值包括always(总是重启)、on-success、on-failure、on-abnormal、on-abort、on-watchdog
  • TimeoutSec:定义 Systemd 停止当前服务之前等待的秒数
  • Environment:指定环境变量
12<i class="fa fa-angle-right" aria-label="下一页"></i>

lkg

14 日志
2 分类
9 标签
GitHub CSDN 博客园 E-Mail
© 2021 lkg