目录

Logstash Grok 概览

背景

Grok 插件让 Logstash 在处理一定格式的日志文件的时候有了一定程度“正则表达”的功能。
特别适用于解析一些非结构化的数据,并从中提取真正相关的信息至一些结构化 field 中。

主要的使用场景在 syslog、apache 与其他的 webserver 具有这样特点的日志:这些日志都具有易人读但不易机读的特点。

Logstash 默认有很多 patterns,你可以在 https://github.com/logstash-plugins/logstash-patterns-core/tree/master/patterns 找到。当然你也可以添加你自己的 pattern,这点我们稍后就会讲到。

测试你的 Grok pattern

Debug 是人类进步的阶梯,想起来当时被正则表达式支配的恐惧了么?那时我们有一些工具来测试我们的正则表达式是否足够“强壮”,grok 的作者也提供了两个网站,允许你通过这个来测试你的 grok 表达式,就跟你在测试正表达式的时候一样。分别是 http://grokdebug.herokuapp.com http://grokconstructor.appspot.com/

Grok 的一些基本设定

语法

Grok 使用如下的语法进行匹配操作。

1
%{SYNTAX:SEMANTIC}

其中 SYNTAX是你想匹配的表达式的名称,SEMANTIC 则是存储匹配后的文本的变量名,比如:

1
2
3
4
5
6
7
8
# 待匹配的文本为
192.168.1.1 2016-04-26T19:55:15Z
# 一个完整的匹配式
%{IPV4:ip} %{TIMESTAMP_ISO8601:time}
# pattern 为
IPV4 (?

TIMESTAMP_ISO8601 %{YEAR}-%{MONTHNUM}-%{MONTHDAY}[T ]%{HOUR}:?%{MINUTE}(?::?%{SECOND})?%{ISO8601_TIMEZONE}?

那么 IPV4TIMESTAMP_ISO8601就是 SYNTAXiptime 就是 SEMANTIC。

一个实际的例子

一个 logstash 的配置文件,内容如下:

1
2
3
4
5
6
7
8
9
10
input {
file {
path => "/var/log/http.log"
}
}
filter {
grok {
match => { "message" => "%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}" }
}
}

运行后,这条 message 将会在 grok 过滤之后上报一条 event,内容如下:

1
2
3
4
5
client: 55.3.244.1
method: GET
request: /index.html
bytes: 15824
duration: 0.043

正则表达式库

Grok 使用了 oniguruma 的正则表达式,所以所有在该文档中出现的匹配语法都可以使用。

自定义 pattern

Grok 自带了一些常用的匹配规则,比如:IPV4、IPV6、YEAR等,但是当我们想要写一些自己的规则的时候,grok 也提供了支持,这里主要有两种方式:

第一种方式添加自定义 pattern

直接使用下面的 pattern 结构:

1
(?the pattern here)

其中 field_name 可以理解为上文的 SEMANTIC,后面则跟的是实际的匹配表达式,比如这样:

1
(?[0-9A-F]{10,11})

第二种方式添加自定义 pattern

第二种方式就如同我们一开始使用的一样,在指定的 pattern 文件夹,添加即可比如:

1
2
# 在 ./pattern/postfix 添加
POSTFIX_QUEUEID [0-9A-F]{10,11}

在实际匹配的时候写入

1
%{POSTFIX_QUEUEID:queue_id}

使用的效果与第一种方式完全一致。

Logstash 的配置文件中可以指定 自定义 pattern 的位置,比如:

1
2
3
4
5
6
filter {
grok {
patterns_dir => ["./patterns"]
match => { "message" => "%{SYSLOGBASE} %{POSTFIX_QUEUEID:queue_id}: %{GREEDYDATA:syslog_message}" }
}
}

就是读取当前目录下的 patterns 文件。

Grok 插件的一些配置项

如果需要定制化 Grok 插件的一些匹配配置

配置项名称 匹配项类型 是否必须
break_on_match boolean no
keep_empty_capture boolean no
match hash no
named_captures_only boolean no
overwrite array no
pattern_definitions hash no
patterns_dir array no
patterns_files_glob string no
tag_on_failure array no
tag_on_timeout string no
timeout_millis number no

named_captures_only

默认值: true
意义:当该值为 true 时,只会从数据中捕获有 SEMANTIC 的信息,其他的匹配项不存储。

overwrite

默认值:[]
意义:这个属性允许你在输出匹配结果之前,重写该匹配结果中的一项或多项,比如:

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
# 原始数据
734742416494845952,Android,"In trade, military and EVERYTHING else, it will be AMERICA FIRST! This will quickly lead to our ultimate goal: MAKE AMERICA GREAT AGAIN!",2016-05-23T13:46:57Z
# 配置文件
filter {
grok {
patterns_dir => ["/root/custom-patterns.txt"]
match => { "message" => "%{ID:id},%{DEVICE:device},%{MESSAGE_BODY:message},%{TIMESTAMP_ISO8601:timestamp}" }
}
}
# 结果1 没有overwrite选项
"message": [
"734742416494845952,Android,"In trade, military and EVERYTHING else, it will be AMERICA FIRST! This will quickly lead to our ultimate goal: MAKE AMERICA GREAT AGAIN!",2016-05-23T13:46:57Z"
,
""In trade, military and EVERYTHING else, it will be AMERICA FIRST! This will quickly lead to our ultimate goal: MAKE AMERICA GREAT AGAIN!""
],
"host": "localhost",
"@timestamp": "2018-10-21T01:09:04.089Z",
"device": "Android",
"id": "734742416494845952",
"timestamp": "2016-05-23T13:46:57Z",
"path": "/root/trump-test.csv",
"@version": "1"

# 结果2 设置overwrite选项 overwrite => ["message"]
"message": "In trade, military and EVERYTHING else, it will be AMERICA FIRST! This will quickly lead to our ultimate goal: MAKE AMERICA GREAT AGAIN!",
"host": "localhost",
"@timestamp": "2018-10-21T01:09:04.089Z",
"device": "Android",
"id": "734742416494845952",
"timestamp": "2016-05-23T13:46:57Z",
"path": "/root/trump-test.csv",
"@version": "1"

可以看到,原来的 message 属性存储的是原始的输入信息,增加了 overwrite 选项后,则由匹配到的 message 信息将其替换。

pattern_definitions

默认值:空
意义:可以再该项中,以键值对的方式输入 grok 表达式,也就是把patterns_dir 文件内的 pattern 写在这个属性里,比如:

1
2
3
4
5
pattern_definitions => {
"ID" => "\d+(?=,)"
"DEVICE" => "[a-zA-Z]+(?=,)"
"MESSAGE_BODY" => ".+(?=,2)"
}

timeout_millis

默认值:30000
意义:在执行了所定义的时间后,终止正则匹配,设置为0则没有超时时间。

add_tag

默认值:[]
意义:在匹配成功后,增加一个或多个 tag 字段

add_field

默认值:{}
意义:在匹配成功后,增加一个或多个 field、value对,例如:

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
# 输入
依然是上文中使用的例子

# Logstash 配置文件如下
filter {
grok {
pattern_definitions => {
"ID" => "\d+(?=,)"
"DEVICE" => "[a-zA-Z]+(?=,)"
"MESSAGE_BODY" => ".+(?=,2)"
}
#patterns_dir => ["/root/custom-patterns.txt"]
match => { "message" => "%{ID:id},%{DEVICE:device},%{MESSAGE_BODY:message},%{TIMESTAMP_ISO8601:timestamp}" }
overwrite => ["message"]
add_tag => [ "test_%{id}"]
add_field => {
"test_%{timestamp}" => "test"
}
remove_field => ["device"]
}
}

# 结果如下
"host": "localhost",
"timestamp": "2016-05-23T13:46:57Z",
"id": "734742416494845952",
"tags": [
"test_734742416494845952"
],
"@version": "1",
"@timestamp": "2018-10-21T01:47:31.552Z",
"message": "In trade, military and EVERYTHING else, it will be AMERICA FIRST! This will quickly lead to our ultimate goal: MAKE AMERICA GREAT AGAIN!",
"path": "/root/trump-test.csv",
"test_2016-05-23T13:46:57Z": "test"

参考

grok manual


版权声明:本文由littleji.com创作并发表,转载请注明作者及出处,欢迎关注公众号:littleji_com
本文遵守CC BY0SA 4.0
if you have any questions, please leave a message behind or give an issue

本文链接为:https://blog.littleji.com/2018/10/25/20181025LogstashGrokOverview/

目录

概率图模型之一

概率图概述

概率图模型使用图的方法来表示概率分布,在该模型中,结点表示变量,节点之间的边表示变量之间的概略关系。

根据图模型中的边是否有向,将概率图的代表模型如下:

image

无向图模型和有向图模型的区别

这里要说明的是,采用有向图的贝叶斯网络的”有向”表示的是依存关系,具有因果推断,即A->B->C,反之则不可.
而无向图的代表马尔科夫网络,采用的无向图

各个图模型的演变关系如下:

image

其中横向,由点到线(序列结构),最终到面。
纵向则是在一定的条件下生成式模型转换为判别式模型。
下面假设有观测序列x,状态序列y,并依次来说明生成式与判别式模型的区别。

生成式模型

生成式模型的定义是:“状态(输出)序列y按照一定的规律生成观测(输入)序列x”。生成式模型的本质是对于联合概率分布p(x,y)进行建模,并根据生成概率最大的生成序列来获取y。

这类模型中,一般有严格的独立性假设,模型变量之间的关系清楚,处理单类问题时较为灵活。

弱点是模型的推导与学习较为复杂。

主要的模型有:n-gram,HMM、朴素贝叶斯、概率上下文无关文法。

判别式模型

判别式模型的定义是:“状态(输出)序列y是由观测序列(输入)所决定的。”判别式模型的本质是对后验概率p(y|x)进行建模,优点是处理多累问题或分辨某一类与其他类差异时更为灵活,模型构造简单。

缺点是模型的描述能力有限,变量之间的关系不清楚。大多数模型都是有监督学习,不能很好地扩展为无监督学习。

主要模型有:最大熵模型、最大熵马尔科夫模型、支持向量机、条件随机场、感知机。

贝叶斯网络

贝叶斯网络也称为belief networks,是一种基于概率推理的数学模型,理论基础为贝叶斯公式。

贝叶斯网络形式上是一个有向无环图(DAG directed acyclic graph),结点表示随机变量,结点之间的边表示条件依存关系,箭头出发的节点为父节点,箭头到达的节点为子节点,子节点依存于父节点。

如果两个节点没有连接关系,表示两个随机变量能够在某些特定情况下条件独立。

构造贝叶斯网络

构造贝叶斯网络是一个复杂的任务,其主要有三个方面的问题:表示、推断、学习

表示

在简单某一随机变量的组合上
image
即便是随机变量只有两个取值,那么联合概率分布P需要对 2^n 种不同取值下的概率情况进行说明,然而这件事的计算代价非常高。

推断

由于贝叶斯网络是变量以及关系的完整模型,那么在观测到某些变量变化的时候就需要使用一些推断方法,来得知另一些变量子集的变化。
概率推理:在已知某些证据的情况下,计算变量的后验分布的过程。
常用的精确推理方法有两种

  • 变量消除法 variable elimination
  • 团树法 clique tree

常用的近似推理

  • 重要性抽样 importance sampling
  • 随机马尔科夫链蒙特卡洛模拟法 Markov chain Monte Carlo,MCMC
  • 循环信念传播法 loopy belief propagation
  • 泛化信念传播法 generalized belief propagation

学习

参数学习的目的就是得知各个变量结点之间相互依存的强度。
比如给定某个节点X,需要计算 P(X|父节点1,父节点2…),这些概率分布可以是任意形式,通常是离散分布与高斯分布。

常用的参数学习方法包括:

  • 最大似然估计 MLE
  • 最大后验概率 MAP
  • 期望最大 EM
  • 贝叶斯估计方法,贝叶斯图模型中,使用较多的是该种方法

除了参数学习,还需要结构学习来学习各个变量之间的图关系,简单的贝叶斯可以由有经验的专家来构造,但一般情况下人工构造一个贝叶斯网络的结构几乎不可能,所以自动结构学习是一项颇具挑战的任务。

MLE MAP 贝叶斯估计之间的关系

其中,最大似然估计(MLE)是频率派的代表,贝叶斯估计(Bayes)是贝叶斯派的代表,最大后验估计是频率派和贝叶斯派的合成,是一种规则化后的最大似然估计。

一般来说,在我们对于先验概率一无所知时,只能假设每种猜测的先验概率是均等的(其实这也是人类经验的结果),这个时候就只有用最大似然了,但不能忘记一个重要的前提是所有的采样都是独立同分布。

如果我们有足够的自信,训练集中的样本分布的确很接近真实的情况,这时就应该用贝叶斯方法。贝叶斯学派强调的是“靠谱的先验概率”。所以说贝叶斯学派的适用范围更广,关键要先验概率靠谱,而频率学派有效的前提也是他们的先验概率同样是经验统计的结果。但也说明了贝叶斯计算要更为复杂,因为需要选择一个常用分布,并确定一个初始参数集作为先验分布。

再者,MAP与MLE最大区别是MAP中加入了模型参数本身的概率分布,即是否考虑了先验知识。或者说。MLE中认为模型参数本身的概率的是均匀的,即该概率为一个固定值。

参考

统计自然语言处理(第2版)
1
2
3
4
5


版权声明:本文由littleji.com创作并发表,转载请注明作者及出处,欢迎关注公众号:littleji_com
本文遵守CC BY0SA 4.0
if you have any questions, please leave a message behind or give an issue

本文链接为:https://blog.littleji.com/2018/10/22/20181022ProbabilisticGraphicalModels1/

目录

形式语法概述

背景

形式语言作为精确描述语言的工具,广泛的应用在机器翻译等自然语言处理的领域

描述语言的常用三个方法:

  1. 穷举法,对于句子数目有限的语言可以使用这种方法将所有的句子进行枚举,从而定义。
  2. 文法,可以理解为我们在英文、中文中学习的语法,通过严格定义规则,来生成合法的句子,重点在于生成句子。
  3. 自动机,不同于文法,自动机更偏向与对于输入句子的合法性检测,从而区分哪些是语言中的句子,哪些不是。

文法与自动机二者皆有所长,一定条件下可以相互转换。

符号与符号串

字母表,符号集

字母或者符号的又穷非空集合。
例:汉语字母表为汉字、数字、标点符号。

符号串

字母表中的符号组成的任何有穷序列。
例:有符号集
image
符号串为:0,1,01,10,11,00

空字符串

image表示,长度为0

符号串的头、尾、固有头、固有尾

例:如果z=abc,则
z的头为:image,a,ab,abc
z的尾为:image,c,bc,cba
z的固有头:image,a,ab
z的固有尾:image,c,bc

符号串连接

有符号串x,y,连接xy指y符号串写在x符号串之后
例:x=ab,y=cd,xy=abcd

符号串的方幂

有符号串x,z=xxxx….,称z为x的方幂,记为image

image

符号串的相乘

有符号串image
例:有A={a,b} B={c,d},则AB={ac,ad,bc,bd}

闭包

字母表image上所有又穷长的字符串的集合用image
来表示,其中正闭包image不包括空集

文法和语言的形式定义

规则

也称为产生式:
image
其中,image

文法

定义:G定义为四元组image
image

句型

image
句子一定是句型,句型不一定是句子

语言

image记为L(G)

文法类型

image

上下文无关文法

image
重点是在规则的左部只有一个非终结字符

正规文法

image

语法树

语法树表明了推倒过程中使用了什么样的产生式和用到了哪些非终结字符,并不表明顺序。
例:有下图
image
构造aabbaa的语法树,步骤如下
image

文法的二义性

image

句型分析

识别一个符号串是否为某文法的句型是整个推导的构建过程

自上而下分析法

由非终结字符串推导至终结字符串,并查看该终结字符串是否匹配

自下而上分析法

有终结字符串进行规约,最终生成的非终结字符串,是否符合规则

回溯法

image
这时候使用回溯法进行计算

简化文法

主要是去除规则中的两种类型的规则,有害规则和多与规则

有害规则

例如:
U->U这种产生式,会引起文法的二义性。
多余规则:指文法中任何句子的推倒都不会用到的规则,主要有两种:

  1. 非终结字符不在任何规则的右部出现。
  2. 非终结字符无法推出终结符号串

参考

宗成庆. 统计自然语言处理[M]. 清华大学出版社, 2008.
北京大学编译原理课程


版权声明:本文由littleji.com创作并发表,转载请注明作者及出处,欢迎关注公众号:littleji_com
本文遵守CC BY0SA 4.0
if you have any questions, please leave a message behind or give an issue

本文链接为:https://blog.littleji.com/2018/10/16/20181016FormalLanguageGenerality/

目录

在alpine上,从零开始安装DVWA

背景

alpine系统

目前 alpine 系统已经作为 docker 容器的默认安装系统,其最大的特点是安装的体积非常小,镜像的大小最少只有 5M ,这对于在 docker 集群中大规模使用容器的情况下,极大的降低了磁盘占用,并且其还有:

  1. 因体积较小,从而提升了启动速度
    2.因体积小,组件少,从而暴露面降低,最终提升系统的安全

当我们能够熟练的配置该系统之后,可以大大加快 devops 的整体流程,迅速搭建原型系统,提高资源的利用率。

DVWA

DVWA:Damn Vulnerable Web Application

老牌的安全测试靶场,后端使用的是 PHP + MySQL 的组合,可以方便快捷的让安全从业者,对常见的安全漏洞的原理进行学习,并在实践中巩固自己的学习成果。

DVWA的官网在这里

安装alpine系统

首先从 alpine 的官网,根据需要下载指定的alpine安装包,这里选择了 3.8.1 的Extend版本。

之后,可以将下载的iso文件制作成U盘启动器进行安装,这里由于演示使用 VMware Fusion 进行安装演示。

虚拟机的配置为默认配置如下:

image

启动后直接使用 root 账号登录,并输入 setup-alpine ,进入配置界面,这里的操作的目的是将目前运行在内存中的系统,配置完整后安装至实际的硬盘上,如下图所示:

image

图中可根据自己的需要配置,如键盘的布局、主机名、网卡信息、时间服务器组件、root密码、时区等,本文选择时区为Asia/Shanghai,重点是选择安装的实际物理磁盘( sda )以及安装的用途( sys )

image

安装完成后 reboot

安装系统必备组件

安装Bash、Vim

1
apk add bash vim

开启远程root登录的权限以及扩展的包镜像源

方便直接通过远程终端进行操作,打开vim /etc/ssh/sshd_config,在配置文件的末尾添加:

1
PermitRootLogin yes

重启 ssh 服务,service sshd restart

开启community testing edge包仓库

1
vim /etc/apk/repositories

将其中所有对应的库链接注释打开

安装配置 MySQL/MariaDB

安装MariaDB

1
apk add mariadb mariadb-client

配置MariaDB

MariaDB安装后还不能直接使用,需要创建用户等配置工作

设定环境变量,稍后使用

1
2
3
4
export DB_DATA_PATH=/var/lib/mysql
export DB_ROOT_PASS=root_password
export DB_USER=dvwa
export DB_PASS=dvwa_password

启动配置MariaDB

1
2
mysql_install_db --user=mysql --datadir=${DB_DATA_PATH} &&\
chown -R mysql:mysql ${DB_DATA_PATH}

启动 MariaDB 并添加默认启动

1
2
rc-service mariadb start
rc-update add mariadb default

改 root 密码

1
mysqladmin -u root password "${DB_ROOT_PASS}"

创建一个dvwa用户,以及dvwa数据库

建议添加该用户,不建议使用 MariaDB 的 root 账户登录MariaDB

1
2
3
4
5
6
7
8
echo "CREATE DATABASE dvwa;" >> /tmp/sql
echo "GRANT ALL ON *.* TO ${DB_USER}@'127.0.0.1' IDENTIFIED BY '${DB_PASS}' WITH GRANT OPTION;" > /tmp/sql
echo "GRANT ALL ON *.* TO ${DB_USER}@'localhost' IDENTIFIED BY '${DB_PASS}' WITH GRANT OPTION;" >> /tmp/sql
echo "GRANT ALL ON *.* TO ${DB_USER}@'::1' IDENTIFIED BY '${DB_PASS}' WITH GRANT OPTION;" >> /tmp/sql
echo "DELETE FROM mysql.user WHERE User='';" >> /tmp/sql
echo "DROP DATABASE test;" >> /tmp/sql
echo "FLUSH PRIVILEGES;" >> /tmp/sql
cat /tmp/sql | mysql -u root --password="${DB_ROOT_PASS}"

重启主机,验证是否安装完成

1
2
reboot
ps -ef | grep mysql

安装PHP 以及所需要的库组件

1
apk add lighttpd php5-common php5-iconv php5-json php5-gd php5-curl php5-xml php5-pgsql php5-mysql php5-imap php5-cgi fcgi php5-pdo php5-pdo_pgsql  php5-pdo_mysql  php5-soap php5-xmlrpc php5-posix php5-mcrypt php5-gettext php5-ldap php5-ctype php5-dom

安装配置 lighttp

1
vim /etc/lighttpd/lighttpd.conf

取消掉注释include "mod_fastcgi.conf"

1
vim /etc/lighttpd/mod_fastcgi.conf

替换/usr/bin/php-cgi/usr/bin/php-cgi5

打开对应的选项,便于漏洞学习

1
vim /etc/php5/php.ini

找到allow_url_openallow_url_include 均设置为 On

启动Lighttpd

1
rc-service lighttpd start && rc-update add lighttpd default

安装配置 DVWA

创建项目文件夹

1
mkdir -p /usr/share/webapps/

下载DVWA

1
2
cd /usr/share/webapps/
wget https://github.com/RandomStorm/DVWA/archive/v1.9.zip

将DVWA放到指定的web项目目录中

1
2
3
4
unzip v1.9.zip
rm v1.9.zip
chmod -R 777 /usr/share/webapps/
ln -s /usr/share/webapps/DVWA-1.9/ /var/www/localhost/htdocs/dvwa

配置DVWA

1
vim /usr/share/webapps/DVWA-1.9/config/config.inc.php

设置用户名 密码 以及端口号

image

验证安装情况

打开http://IP/dvwa/setup.php
查看 Setup Check 各项应均为绿色

image

点击Create/Reset Database,创建对应的数据库,安装完成

参考

https://wiki.alpinelinux.org/wiki/DamnVulnerable_Web_Application(DVWA))
https://wiki.alpinelinux.org/wiki/MariaDB


版权声明:本文由littleji.com创作并发表,转载请注明作者及出处,欢迎关注公众号:littleji_com
本文遵守CC BY0SA 4.0
if you have any questions, please leave a message behind or give an issue

本文链接为:https://blog.littleji.com/2018/09/25/20180925InstallDVWAOnAlpineFromScratch/

目录

在Linux上使用 i3 作为窗口管理器的入门教程

注:本文首发于linux中国
本篇文章会介绍如何在Fedora系统中,安装、配置、使用i3桌面管理器。

在我的文章i3 桌面让Linux更好的5个理由,我分享了选择 i3 桌面管理器 作为一种Linux桌面替代方案的最主要五个理由。
在本篇文章中,我将向大家展示,如何在 Fedora 28 上安装与配置 i3。

1. 安装

首先进入 Fedora 系统中,打开一个终端。使用 dnf 来安装需要的软件包,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[ricardo@f28i3 ~]$ sudo dnf install -y i3 i3-ipc i3status i3lock dmenu terminator --exclude=rxvt-unicode
Last metadata expiration check: 1:36:15 ago on Wed 08 Aug 2018 12:04:31 PM EDT.
Dependencies resolved.
================================================================================================
Package Arch Version Repository Size
================================================================================================
Installing:
dmenu x86_64 4.8-1.fc28 fedora 33 k
i3 x86_64 4.15-1.fc28 fedora 323 k
i3-ipc noarch 0.1.4-12.fc28 fedora 14 k
i3lock x86_64 2.9.1-2.fc28 fedora 33 k
i3status x86_64 2.12-1.fc28 updates 62 k
terminator noarch 1.91-4.fc28 fedora 570 k
Installing dependencies:
dzen2 x86_64 0.8.5-21.20100104svn.fc28 fedora 60 k

... Skipping dependencies/install messages

Complete!
[ricardo@f28i3 ~]$

注意:在这个命令中,我排除了 rxvt-unicode 这个包,因为我更喜欢 terminator 作为我的终端模拟器。

据用户目前的系统状态,在命令执行过程中可能会安装很多依赖。等待所有的依赖安装完成,之后重启你的电脑。

2. 登录与初始化

在你的机器重启之后,你便可以第一次体验 i3 了。在 GNOME Display Manager (GDM),选择你的用户名,之后先别着急输密码,点击下方的密码输入框下方的小齿轮,之后选择 i3 ,像下方这样:

输入你的密码,并点击 Sign In。在你第一次登入之后,会先看到 i3 的配置界面:

点击 ENTER 就会在 $HOME/.config/i3 生成一个配置文件,之后你可以通过这个配置文件来定制化 i3’s 的一些行为。

在下一屏,你需要选择你的 Mod 键。这一步很关键,因为 Mod 键通常都会作为 i3’s 命令快捷键的发起键。按 ENTER 会选择 Win 键作为默认的 Mod 键。如果你的键盘没有 Win 键,用 Alt 键做替代,用方向键键选择后按 ENTER 确认。

现在你就登录到了 i3 的系统中。由于 i3 是一个最小化的窗口管理器,你会看到一个黑屏窗口,以及屏幕底端显式的状态栏:

接下来,让我们看看 i3 的如何实际使用。

3. 基本的快捷键

现在你已经登录到了 i3 的会话中,你需要几个基本的快捷键来应对基本的操作。

大多数的 i3 快捷键都会用到之前配置的 Mod 键。在下面的例子中,当我提到 Mod 键,请根据情况使用你定义的做替换。通常使用 Win 键或者 Alt 键。

首先,打开一个终端,使用 Mod+ENTER。重复打开几个终端,观察 i3 是如何自动将它们在桌面中排列。默认情况下, i3 会在水平的方向分割屏幕;使用 Mod + v 来垂直分割,再按 Mod + h 会恢复水平分割模式。

当需要启动其他的应用,按 Mod + d 来打开 dmenu,一个简单的文字应用菜单。默认情况下,dmenu 会呈现出所有在你 $PATH 中设置的应用。使用方向键来选择你想启动的应用,同时你可以键入应用的名称,来缩小选择的范围,之后按 ENTER 来启动选择的应用。

如果你的应用没有提供退出的方法,你可以使用 i3 来关闭对应的窗口,通过按 Mod + Shift +q。注意,你可能会丢失未保存的工作内容。

最后,当你想关闭会话并退出 i3,按 Mod + Shift +e。之后会在窗口的上方提示你是否退出。点击 Yes, exit i3 退出,或选择 X 来取消。

这些就是 i3 中最基本的快捷键,如果想了解更多,请查阅官方文档 documentation

4. 替换GDM

使用 i3 window manager 会降低你操作系统的内存占用;然而,Fedora 依然会使用 GDM 作为登录的窗口。GDM 会载入几个与 GNOME 相关的库从而占用内存。

如果你想进一步的降低你的内存占用,你可以使用一些更轻量级的窗口管理器来替换 GDM,比如 lightdm

1
2
3
4
5
6
[ricardo@f28i3 ~]$ sudo dnf install -y lightdm
[ricardo@f28i3 ~]$ sudo systemctl disable gdm
Removed /etc/systemd/system/display-manager.service.
[ricardo@f28i3 ~]$ sudo systemctl enable lightdm
Created symlink /etc/systemd/system/display-manager.service -> /usr/lib/systemd/system/lightdm.service.
[ricardo@f28i3 ~]$

之后重启你的机器来使用 Lightdm 的登录界面。

现在你可以继续登录并使用 i3了。


via: https://opensource.com/article/18/8/getting-started-i3-window-manager

作者:Ricardo Gerardi
选题:lujun9972
译者:littleji
校对:校对者ID

本文由 LCTT 原创编译,Linux中国 荣誉推出


版权声明:本文由littleji.com创作并发表,转载请注明作者及出处,欢迎关注公众号:littleji_com
本文遵守CC BY0SA 4.0
if you have any questions, please leave a message behind or give an issue

本文链接为:https://blog.littleji.com/2018/09/07/20180907GettingStartedWithI3WindowManager/

目录

Go语言程序设计(1)

概述

有一点是要说明的,Java无意间成了更好的C++(开发角度来说),Go的目标则是充当更好的C,虽然垠神喷了又喷go的这与那,但作为一门工程师气息很重的语言,社区也越发强大的语言,为了更好的工程实践,需要深刻学习,并尝试替换后端难以维护的C写的后端.
最后,选择一门语言不是选择一门语言本身,更多的是选择社区.称为开发人员的社会性?

第一章 举例

Go的HelloWorld.go

1
2
3
4
5
6
7
8
package main
import (
"fmt"
)
func main() {
who := "World!"
fmt.Println("Hello", who)
}

第二章 布尔与数值类型

2.1 基础

2.1.1 注释风格

  • 采用了C的方式,行注释为//,块注释为/**/
1
2
3
4
5
6
7
8
//行注释
//fmt.Println("Hello!")

/*块注释*/
/*
fmt.Println("Hello!")
fmt.Println("World!")
*/
  • 同样的块注释也不可以嵌套比如下面的代码会报错
1
2
3
4
5
6
7
/*块注释
/*
fmt.Println("Hello!")
fmt.Println("World!")
*/
*/
syntax error: unexpected /, expecting expression

2.1.2 标识符

标识符需要使用字母为开头的,使用Unicode编码分类中的任何字符组成.
标识符不可以同关键字的名称相同.
标识符区分大小写,下面几个各不相同

1
2
3
hello
Hello //其中该以大写字母开头的标识符是公开的,其他的为私有的.
hEllo

其中下划线’_’在go中为占位符,当在调用一个赋值操作的时候,使用占位符,则忽略该值,被赋值的值保持原来的值, 如下所示

1
2
count, err = fmt.Println(x) //获取打印的字节数和error值
count, _ = fmt.Println(x) //忽略error值

2.1.3 常量和变量

  • 变量声明与赋值

由于go是强类型的语言,变量使用前必须要进行声明和赋值,如果用户不进行赋值,则默认置为0(整形等)或””(字符串)或nil(指针),不用担心C语言中的垃圾值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//正确做法1
var i int
i = 10 //变量

//正确做法2
var i int = 10

//正确做法3, 由于赋值的时候可以通过赋值符号右边的值进行类型推倒
var i = 10

//正确做法4, 最简单的方法, :=表明声明为变量并进行类型推倒,最终赋值,于是可以省略var
i := 10

//错误示范1,在声明的时候没有指定类型
var i
i = 10

//错误示范2,不声明直接赋值
i = 10
  • 常量声明和赋值
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
//正确做法1
const x = 0
const y = 1
const z = 2

//正确做法2, 可以使用小括号的方式来声明一组变量
const (
x = 0
y = 1
z = 2
)

//正确做法3,将括号内声明的变量初始化为一个值,下面的x y z 均初始化为0
const {
x = 0
y
z
}

//正确做法4, 使用iota标识符进行初始化,
//iota是一个无类型整数常量,每次const关键字出现的时候,其值自增1
const {
x = iota
y
z
}
//即
const {
x = iota // 0
y = iota // 1
z = iota // 2
}


//错误1, :=符号无法用在const初始化中
const x := 1

//错误2, 未初始化完成就使用, 必须声明初始化一起完成
const x
x = 1

2.2 布尔值和布尔表达式

  • 布尔值:true和false
  • 布尔表达式:
1
2
3
4
5
!b
a||b
a&&b
x
x>y

需要注意的是==和!=可以比较任何两个类型,只要被比较的双方兼容这两个操作符
< <= >= >只能比较数字和字符串

2.3 数值类型

不同的类型之间不允许进行二进制运算和比较操作,在操作之前必须转为相同的类型

1
2
3
4
5
6
7
8
9
//错误1, 两个不同类型之间, 不可以进行运算
x := 1 //自动推断为int类型
y := int16(2)
z := x + y

//正确
x := 1
y := int16(2)
z := x + int(y)

其他的算术运算符

1
2
3
x++ //没有++x
x--
x /= y //x/y的结果返回给x,如果分母为0,发出异常,如果两个值为整数,丢弃余数

2.3.1整型

  • 有符号的类型
1
2
int int8 int32 int64
int//默认是int32或者是int64 依赖平台
  • 无符号的类型
1
2
3
4
uint uint8 uint32 uint64
byte//等于uint8
rune //等于uint32
uintptr//(32位下uint32 64位下uint64)

需要注意的是 默认使用int就足够,并且其速度是可以保证的
将小的整数转换为大整数总是安全的,但是如果向下转换会产生截断或者得到一个不可预期的值,如果想使用一个完美的精度,可以使用big.Rat或者big.Int类型,该类型只受限于机器的内存大小

参考

Go语言程序设计


版权声明:本文由littleji.com创作并发表,转载请注明作者及出处,欢迎关注公众号:littleji_com
本文遵守CC BY0SA 4.0
if you have any questions, please leave a message behind or give an issue

本文链接为:https://blog.littleji.com/2018/02/04/20180204ProgrammingInGo1/

目录

比特币白皮书

比特币白皮书

0x00摘要

一个真正意义上的点对点的在线电子交易系统,应该满足交易的双方在不需第三方金融机构介入的情况下进行。虽说数字签名技术,部分解决了这个问题,但是又需要面临,在离线交易过程中可能出现的“重复支付”(double-spending )问题。我们在这里给出了一种解决的办法,这种方法将网络时间戳通过hash转换,加入到一种基于hash的、持续伸展的“工作证明链”(以下简称工作链)中。攻击者除非能够将之前所做的工作再做一遍,否则无法更改这个工作证明链中已有的工作证明记录。也就是说,最长的工作链一方面证明了其见证了最多的交易记录,另一方面也说明了其所掌握的CPU计算能力(译注:HASH的计算能力)。只要大多数的CPU计算能力掌握在各个交易的个体手中,那么攻击者无法对该交易网络进行攻击。当然,这个交易系统也需要最基本的结构,个个节点也会最大范围的通知自己所记录的交易行为。由于最长的工作链存有所有的交易记录,所以每个节点可以在任意的时间脱离或者回到这个交易系统,而不会丢失其未曾见证的交易记录。

0x01说明

目前,互联网上的电子商务几乎完全依赖作为可信第三方的金融机构来处理电子支付。在大多数情况下,该交易模式可以应对,但它仍然受到基于信任模型的固有弱点的影响。比如,不可避免的调解纠纷,而调解成本又增加了交易成本,限制了最小的实际交易规模,并且切断了小型临时交易的可能性。尤其是,当需要运作而又无法正常的运作一笔“不可逆的交易”时,交易成本会大大的增加。由于该系统的提供信息有可能存在掺了假的或者过时的信息,所以交易的双方都需要花更多的成本在获取双方的信任上,进一步增加了交易的成本。这种交易机制在没有任何可信任的第三方见证的情况下,交易无法进行下去。
事实上,目前所需要的是一种基于密码证明而不是信任的电子支付系统,这个系统允许任何两个愿意相互交易的双方,在不需要可信任的第三方的情况下进行交易。一方面,由于在实施欺骗需要付出巨大的计算代价,从而保护了卖家免受欺诈;另一方面,使容易被采用的常规托管机制,来保护买家。在本文中,我们提出了一个解决重复支付问题的解决方案,这个方案使用分布式时间戳服务器来顺序生成基于交易时间的工作证明。并且只要该系统中的所有坏人节点的计算能力不超过系统内的其他节点,那么就能保证这个系统是安全的。(译注:51%攻击)

0x02交易

这里定义一种电子货币保存一系列的数字签名。在交易的过程中,交易中的付款方首先将之前的交易与付款方的公钥一同进行hash,最终添加到付款方所持有的电子货币中,并传给收款方,收款方使用付款方的公钥对该电子货币进行验证是否为收款方的身份。
问题在于,收款方无法确认付款方是否多花了钱。一般的解决方法是引入一个可信的第三方,或者说造币厂,对每一笔交易进行审查。具体过程是,每一笔交易发生时,付款方将所持有的货币传回给造币厂,造币厂则将这个货币摧毁,产生一个新的货币给收款方。这样以来,整个交易的过程安全性完全依赖于造币厂。
而我们需要一种让收款者知道付款方没有进行二次交易。为了这个目的,我们可以在交易的过程中认为,只有最早的那笔交易是算数的,这样避免了二次交易情况的发生。收款方通过遍历所有的交易来验证付款方发出交易请求而收款方没有收到这一情况。要想脱离造币厂的模型,交易必须被广而告之,并且需要一个系统来帮助所有的参与者决策交易的到达顺序,收款方在判断一个交易的到达时间时需要这个系统内的其他节点进行投票决定,少数服从多数。

0x03时间戳服务器

时间戳服务器是一切的开始,时间戳服务器工作原理是对一个block进行hash,并对其结果进行广播。建立时间戳服务器的意义主要是为了证明某一个数据在一个时间点一定存在。在组成一个链的时候,每一个时间戳的生成都会考虑到之前时间戳的信息。

参考

比特币白皮书


版权声明:本文由littleji.com创作并发表,转载请注明作者及出处,欢迎关注公众号:littleji_com
本文遵守CC BY0SA 4.0
if you have any questions, please leave a message behind or give an issue

本文链接为:https://blog.littleji.com/2018/01/18/20180117BitCoin/

目录

舍得

0x00 写在前面

2017,眨眼便逝.

今年文章产出为1,无法回避这个问题,为什么呢?懒亦有了些自知之明.

  1. 懒是自制力的问题,这也是我自身亟待解决的问题,事实上在自身的方法论体系中对于自我的改造,自制力是要排在第一位的,没有自制力之后的所有学习方法都无法展开,或者说将事倍功半,可以说是内功中的”易筋经”,俗话说:脱胎换骨,内壮神勇.
  2. 由于在网上或书上看了不少的文章,发现均是良莠不齐,而这人一旦有了坏名声,再想改变人们的坏印象那可难喽.于是我心中也忐忑起来,不敢再有所造次.怕是污了各位看官的火眼.但又觉得污不污的也是真我,到了这把年纪再不折腾,怕是没时间了.

那在这个年初,便总结下有得有失的这一年:得是侥幸,失则是得的对立.

下面列举这一年几个对我影响较深思考:

  1. 舍得,有舍方有得.
  2. 选择、方法、努力缺一不可.
  3. 极小点.
  4. 人本身是工作问题的思考前提.
  5. 参差多态乃是幸福本源.
  6. 复盘,真正地找到自身的不足.
  7. 决定你的不是你,而是你的周遭.

上面几项,并非完全独立的关系,比如复盘于我自身的知识体系中在方法-实践方法-学习方法中.

下面简单地讲讲我对舍得的理解,其他几个留到之后一一细谈.

0x01 舍得也是公平

舍得舍得,有舍有得.其实跟此相似的概念还有等价交换.

舍得讲的是公平问题,这也是基本的商品交换规律,只有付出什么才能等到什么.

马云也说过:“员工离职就是两点:1.钱没给够 2.干的不爽”,事实上合起来也是公平二字,只不过一方面说的是钱,另一方面说的是心境。

供求双方在平等的条件下进行对彼此均有益的交易,符合囚徒理论中”双赢”的概念,双方在均获得一定利润的情况下,继续在合作巩固社会发展.

但理论归理论,实际上孰不想独拿那份最大的蛋糕?

举个生活中的例子:老板付工资,员工ABC干活.其中ABC干的是同一种活.
其中老板付出总共15000的情况下,公司的总利润是1500,其中,A正常工作、B偷懒工作、C勤奋工作.

0x0101 A与老板的地位平等

1
2
3
老板付出5000的工资,得到了员工A产出的5500的收益.老板很高兴.
员工A正常工作,付出4500的精力,得到了老板给出的5000的工资.员工A很开心.
二者携手共创美好的明天.

0x0102 B、C与老板之前地位不平等

还是上面的例子

1
2
3
员工B偷懒,员工C勤奋.
员工B由于频繁偷懒,拿着5000的工资,付出4500精力,产出了5000的收益.员工地位被抬高,老板觉得自己的利益受到侵害,很生气将其开除.
员工C由于非常勤奋,拿着5000的工资,付出了5500精力,产出了6000的收益.老板地位被抬高,员工觉得干了那么多活,依然拿着一样的工资,心生委屈愤而离职.

由此发现,由于两个员工离职,老板的利润只有每个月500,事实上比之前ABC三个员工均在时的收益1500降低了2/3.双方不平等的的结果只有双输:老板收益降低,员工没了工作。

0x0103 该怎么做?

无他,对于交易的双方来说,都应该关注好交易的彼此,莫让对方受了委屈,才是持续推动双方进步的不二法门。切莫为了蝇头甜点,预支了未来的大块蛋糕。

参考

等价交换


版权声明:本文由littleji.com创作并发表,转载请注明作者及出处,欢迎关注公众号:littleji_com
本文遵守CC BY0SA 4.0
if you have any questions, please leave a message behind or give an issue

本文链接为:https://blog.littleji.com/2018/01/14/20180114ThereAndBackAgain/

目录

我的程序员书单(My Programmer Book List)

算法

程序员实用算法 原书
算法导论->大餐 9.4
Algorithms Unlocked->开胃
算法引论——一种创造性方法(建议先看第5章,真是爽爆了)
The Science of Programming
求解数学题《怎样解题》
计算机程序设计艺术 9.3
基础数学 9.5
怎样解题 9.1
An Introduction to Probability Theory and Its Applications, Vol. 1, 3rd Edition 9.6
如何求解问题 8.5
数理逻辑 8.9
集合论基础 9.1
概率论及其应用 9.1
图论导引 8.8
来自圣经的证明 9.4

计算机原理

计算机程序的构造与解释 9.5
领域特定语言 9.1
编译原理 9.1

Java

Effective Akka
Java 8 in action
java puzz
java 并发编程实战 9.0
effective java 9.1

Python

Learning Python
Python Programming

C/C++

Effective C++/STL

数据库

高性能MySQL 第三版

安全

白帽子讲web安全 8.2
黑客攻防技术宝典:web实战篇(第2版) 8.6
加密与解密(第3版) 8.4
Web之困 - 现代Web应用安全指南
Web前端黑客技术揭秘
码的奥秘 9.2
Web安全深度剖析 7.9
SQL注入攻击与防御(第2版) 7.8
精通脚本黑客 8.0
0day安全 (第2版) 8.4
社会工程 8.0

软件工程

教科书:构建之法构建之法中提到的书单
参考书:代码大全 Rapid Development 快速软件开发 项目管理艺术 人件
敏捷软件开发 原则,模式与实践
硝烟中的Scrum和XP : 我们如何实施Scrum 8.6
认知与设计 8.6
门后的秘密 8.2
点石成金 8.5
启示录 8.5
项目百态 8.3
精益开发实战 8.3
敏捷武士 7.7
敏捷软件开发 9.1
持续交付 8.6
精益企业 8.8
精益思想 8.6
看板方法 7.8
系统的思考 8.0
管理3.0 8.0
第五项修炼

UI设计

简约至上 8.4

营销

增长黑客 7.9

标准

HTTP 权威指南 8.7
TCP/IP详解 9.2

软件设计

设计模式 : 可复用面向对象软件的基础 9.4
企业应用架构模式 9.0
软件框架设计的艺术
发布!软件的设计与部署 7.7
实现领域驱动设计 8.8

运维

网站运维 8.3

测试

Google软件测试之道 8.1

程序员实践

卓有成效的程序员
高效程序员的修炼
程序员的思维训练 8.3
程序员的职业素养 8.6
高效程序员的45个习惯——敏捷开发修炼之道
程序员修炼之道——从小工到专家
重构 9.0(《重构与模式》一样,充其量只是一本案例集,无法达到《重构》的高度)
编写可读代码的艺术 8.6
编程珠玑 9.2
编码 9.2

程序员泛读

哥德尔、艾舍尔、巴赫 9.4
暗时间 8.4
把时间当朋友
影响力 8.6
黑客 8.3
编程人生 8.4


版权声明:本文由littleji.com创作并发表,转载请注明作者及出处,欢迎关注公众号:littleji_com
本文遵守CC BY0SA 4.0
if you have any questions, please leave a message behind or give an issue

本文链接为:https://blog.littleji.com/2017/05/10/20170510MyBookList/

目录

使用navicat 修改MySQL数据库的某个表后,无法再读取该表(MySQL-#1146-#1017)

概述(abstract)

问题的产生原因是由于在Windows下使用Navicat客户端,操作位于CentOS上MySQL 5.6时,具体的执行一个重命名字段的操作时,Navicat停止了运行,然后将该Navicat强制的关闭后,再运行Navicat打开刚才重命名字段所在的表,再次卡死,反复操作几次,结果并没有改变.

解决1(figure it 1)

首先,去MySQL数据库所在的服务器,对MySQL服务进行重启

1
service mysqld restart

再去用Navicat操作MySQL ,报 ERROR 1146 table ‘’ doesn’t exist 的错误

解决2(figure it 2)

之后,通过查阅stackoverflow,可能是数据库文件权限的问题,然后照葫芦画瓢,使用下面的命令对其进行修改:

1
chown mysql:mysql /var/lib/mysql/ci/*

直接报,没有该文件

解决3(figure it 3)

需要通过下面的命令查询mysql data文件具体在什么位置

1
vim /etc/my.cnf

找到下面这行

1
datadir = /opt/mysql/db/data

再通过语句修改对应数据表所在数据库的权限,比如出现错误的表所在数据库的名字是’tmp_db’

1
chown mysql:mysql /opt/mysql/db/data/tmp_db/*

重新启动数据库

1
service mysqld restart

参考

stackoverflow#1


版权声明:本文由littleji.com创作并发表,转载请注明作者及出处,欢迎关注公众号:littleji_com
本文遵守CC BY0SA 4.0
if you have any questions, please leave a message behind or give an issue

本文链接为:https://blog.littleji.com/2016/12/19/20161219MySQL-#1146-#1017/