安装

http://www.openfst.org/twiki/bin/view/GRM/ThraxQuickTour

http://cslu.ogi.edu/~sproatr/Courses/TextNorm/tutorial.html

http://www.openfst.org/twiki/pub/GRM/ThraxDownload/thrax-1.2.7.tar.gz

thrax-1.2.5以上要求openfst-1.6.6以上

thrax-1.2.4要求openfst-1.6.0以上

 
 

MAKE SURE YOU CONFIGURE OpenFst WITH THE --enable-far, --enable-pdt AND --enable-mpdt FLAGS.

cd openfst

make clean

./configure -enable-far --enable-pdt --enable-mpdt

make -j24

sudo make install

 
 

使用--enable-pdt选项make时

pdtreplace.cc:(.text+0x245): undefined reference to `fst::script::FstClass::Read(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'

pdtreplace.cc:(.text+0x3f1): undefined reference to `fst::script::FstClass::Read(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'

pdtreplace.cc:(.text+0x4ac): undefined reference to `fst::script::VectorFstClass::VectorFstClass(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'

./.libs/libfstpdtscript.so: undefined reference to `fst::FstHeader::Write(std::ostream&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const'

./.libs/libfstpdtscript.so: undefined reference to `fst::ConvertToLegalCSymbol(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*)'

./.libs/libfstpdtscript.so: undefined reference to `fst::AddAuxiliarySymbols(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, long, fst::SymbolTable*)'

需要make clean

 
 

cd thrax

./configure --enable-static=no

make -j 8 -Wall -Wno-sign-compare

 
 

make错误

./../include/thrax/evaluator.h:257:15: error: request for member 'InputSymbols' in 'far_reader->fst::FarReader<A>::GetFst<fst::ArcTpl<fst::TropicalWeightTpl<float> > >()', which is of pointer type 'const fst::Fst<fst::ArcTpl<fst::TropicalWeightTpl<float> > >*' (maybe you meant to use '->' ?)

*far_reader->GetFst().InputSymbols())) {

^

./../include/thrax/evaluator.h:277:56: error: no matching function for call to 'fst::VectorFst<fst::ArcTpl<fst::TropicalWeightTpl<float> > >::VectorFst(const fst::Fst<fst::ArcTpl<fst::TropicalWeightTpl<float> > >*)'

MutableTransducer tmpfst(far_reader->GetFst());

^

Makefile:582: recipe for target 'main/compiler-stdarc.lo' failed

make[3]: *** [main/compiler-stdarc.lo] Error 1

make[3]: Leaving directory '/media/jarvan/ST2000DM001/kaldi.git.new/tools/thrax-1.2.1/src/lib'

Makefile:344: recipe for target 'all-recursive' failed

make[2]: *** [all-recursive] Error 1

make[2]: Leaving directory '/media/jarvan/ST2000DM001/kaldi.git.new/tools/thrax-1.2.1/src'

Makefile:400: recipe for target 'all-recursive' failed

make[1]: *** [all-recursive] Error 1

make[1]: Leaving directory '/media/jarvan/ST2000DM001/kaldi.git.new/tools/thrax-1.2.1'

Makefile:323: recipe for target 'all' failed

make: *** [all] Error 2

 
 

使用thrax-1.2.4替换thrax-1.2.1:

wget http://www.openfst.org/twiki/pub/GRM/ThraxDownload/thrax-1.2.4.tar.gz

即可解决编译错误

 
 

QuickTour

http://www.openfst.org/twiki/bin/view/GRM/ThraxQuickTour

 
 

如果安装了GNU readline,则可以在configure时加上(--enable-readline)选项以启用readline功能。

这样,使用thraxrewrite-tester时,支持内联的输入编辑以及保存历史。可以使用--history_file选项指定历史文件(默认为.rewrite-tester-history)。

 
 

工具集

 
 

thraxmakedep

thrax的语法依赖关系生成工具

该工具以top-level-grammar作为主语法文件(相当于main.c);

根据语法文件的调用关系,以thraxcompiler为编译器,生成makefile;

Usage: src/bin/thraxmakedep [-s/--save_symbols] [-a/--arc_type (default: standard)] top-level-grammar [makefile-target=Makefile]

 
 

--save_symbols和--arc_type选项将被传递给thraxcompiler

 
 

[-s/--save_symbols]

表示是否保留输入和输出的原始符号;

若保留,则FSTs中使用原始符号作为弧之上的权重;

否则,FSTs使用标识符代替原始符号;

如果设定了--save_symbols,编译时,符号表将得以保留。

符号的选择基于用于编译FSTs的每条字符串的解析模式。

符号表可以是一个byte符号表、utf8符号表

用户自定义符号表。

当需要从fst档案文件中提取FSTs并使用fstprint或fstdraw显示时,可以指定此参数。但是可能会出现一些bugs。

[-a/--arc_type (default: standard)]

--arc_type选项支持与OpenFST相同的弧类型:standard (tropical), log 和 log64。

通常,我们需要弧的类型为热带半环,因此一般情况下不需要设定此参数。

注意,thraxrewrite-tester只支持--arc_type standard,否则,将不能进行测试。

 
 

 
 

thraxcompiler

用于将语法文件编译为FST

PROGRAM FLAGS:

--arc_type: type = string, default = "standard"

编译FSTs的弧类型

--emit_ast_only: type = bool, default = false

解析输入,将语法文件的AST打印到标准输出,不生成FST档案

--input_grammar: type = string, default = ""

输入的语法文件

--output_far: type = string, default = ""

输出的FST档案目标位置

thraxrewrite-tester

thrax改写/重写测试工具

该工具根据规则文件在标准输入上向用户请求一个或多个输入;

然后将用户的输入以某种规则输入到FSTs中;

获取FSTs的输出,并输出到标准输出。

Flags from: rewrite-tester-utils.cc

--far: type = string, default = ""

far, fsts archive, fst档案文件

要测试的fst档案文件,后缀名一般为".far"

--history_file: type = string, default = ".rewrite-tester-history"

历史文件的位置

--input_mode: type = string, default = "byte"

输入的编码,可以是"byte"、"utf8"或是一个符号表。

--noutput: type = int64, default = 1

对于每个输入,最多输出的字符串的个数

--output_mode: type = string, default = "byte"

输出的编码,可以是"byte"、"utf8"或是一个符号表。

--rules: type = string, default = ""

重写规则文件名

 
 

规则文件的内容为
以逗号为分隔符的规则列表

这些规则将与标准输入(或随机生成器)一起构成FSTs的输入

这类似于Bash的字符串替换:echo "Hello $you_name, my name is $my_name."

 
 

--show_details: type = bool, default = false

当指定了多个规则文件时(比如:--rules=FST1,FST2,FST3)

将显示每个transducer的输出结果,可用于调试。

thraxrandom-generator

thrax随机生成器

该工具根据规则文件随机生成最多noutput个输入;

然后将生成的输入以某种规则输入到FSTs中;

获取FSTs的输出,并输出到标准输出。

 
 

注:使用后进先出转换器(pushdown transducer)规则时,该工具将会生成无意义的结果。

 
 

PROGRAM FLAGS:

--far: type = string, default = ""

要测试的fst档案文件,后缀名一般为".far"

--input_mode: type = string, default = "byte"

输入的编码,可以是"byte"、"utf8"或是一个符号表。

--noutput: type = int64, default = 1

要生成的最大输出映射(output mappings)数

--output_mode: type = string, default = "byte"

输出的编码,可以是"byte"、"utf8"或是一个符号表。

--rule: type = string, default = ""

重写规则文件名

 
 

 
 

Thrax使用示例

 
 

使用thraxmakedep工具分析主语法文件的依赖关系,生成Makefile;

$ thraxmakedep example.grm

使用Automake中的make对Makefile解决依赖并生成fst档案(.far);

$ make

使用thraxwrite-tester,根据"--rules"指定的规则文件,对fst档案进行输入输出的测试;

$ thraxrewrite-tester --far=example.far --rules=TOKENIZER

Input string: Well, I can't eat muffins in an agitated manner.

Output string: Well , I ca n't eat muffins in an agitated manner .

Input string: Mr. Ernest Worthing, B. 4, The Albany.

Output string: Mr. Ernest Worthing , B. four , The Albany .

Input string: Lieutenant 1840,

Output string: Lieutenant eighteen forty ,

Input string: Uncle Jack!

Output string: Uncle Ernest !

 
 

从far中抽取fst

farextract numbers.far

目录中将生成NUMBERS

fstinfo ./NUMBERS

fstprint ./NUMBERS

 
 

 
 

http://openfst.org/twiki/bin/view/Forum/GrmThraxForum

 
 

LoadFst: load fst from a file or extracting from a FAR.

 
 

LoadFst['/path/to/fst']

LoadFstFromFar['/path/to/far', 'fst_name']

 
 

http://blog.csdn.net/visionfans/article/details/50408846

 
 

 
 

Thrax语法规则

 
 

 
 

 
 

 
 

Imports

导入语句由import声明列表组成,导入声明如下:

import 'path/to/file.grm' as alias;

编译器将先搜索提供的文件并加载其中的所有函数以及所有导出的符号。

从编译目标FST档案(file.far)中加载的符号(FSTs)必须与导入的源文件在同一目录下。

导入后,主文件中就可以使用别名来引用函数和符号。

因此,如果file.grm提供了一个名为foo的函数,那么可以使用语法alias.foo[...]来调用这一函数。

注意,要导入的文件本身也可能导入的其他文件。要访问这些文件和FSTs,可以使用以下别名语法:

 
 

alias.utils.common.kUpperCaseLetters.

 
 

import语法示例:

import 'path/to/file.grm' as alias;

这相当于C语言中的'#include "path/to/file.grm"'和'typedef file.grm alias',grm是源文件。但是,在"file.h"同一目录下需要提供file.far,一个Fst ARchive文件,该文件是编译好的FST文件,相当于C语言中的lib库。当import该源文件后,调用file.grm中定义的函数。比如:alias.foo[…]。当file.grm中也调用了其他源文件,比如"import utils.common.kUpperCaseLetters",要在当前源文件中加入"alias.utils.common.kUpperCaseLetters."即可调用。

 
 

 
 

Functions

 
 

使用func关键字来定义函数,紧接一个函数描述符(函数名)以及一个由方括号包裹的、由逗号分隔的参列表,紧接是有花括号包裹的函数体。函数中,可以使用return语句返回一个对象(通常是一个FST)。

示例:

func UnionWithTriple[fst] {

fst3 = fst fst fst;

result = fst | fst3;

return result;

}

要调用此函数,可以使用函数名与参数列表以调用:

export a_or_a3 = UnionWithTriple["a"];

 
 

注意,函数不会引用局部环境的变量,以下语句是不合法的:

 
 

abc = "abc";

 
 

func AddAbc[fst] {

return fst abc;

}

 
 

可以引用在其他模块中定义的变量。这一,如果模块"foo"定义了"abc",则可以:

func AddAbc[fst] {

return fst foo.abc;

}

 
 

示例:

func UnionWithTriple[fst] {

fst3 = fst fst fst;

result = fst | fst3;

return result;

}

函数用func关键字定义,后接函数名,参数表用方括号包裹,主函数体用花括号包裹,每一个指令以分号结尾。

 
 

调用该函数:

export a_or_a3 = UnionWithTriple["a"];

 
 

 
 

Grm源文件中主体部分(主函数)中生成FST的语句

 
 

主体中其他元素都是用于生成FSTs的语句,这些输出的FSTs将被导入到FST档案中作为输出。每一个语句由一个以分号结尾的赋值操作构成:

foo = "abc";

export bar = foo | "xyz";

声明语句可以用export关键词来修饰;该语法会把变量的内容写入到最终输出档案中。无export关键词修饰的变量声明将不会被输出。

 
 

标注库函数、运算和常量

StringFile:从文件中加载字符串列表或者字符串二元组的列表,将其编译成一个表示这些字符串的并集的FST。相当于 ("string1 | string2 | string3 | ...")

如果该文件每一行只有一个字符串,则编译的FST是accpetor;如果每一行为由制表符隔开的字符串二元组,则编译的FST是transducer。解析模式由StringFile函数的第二个参数指定:

StringFile['strings_file', 'byte', my_symbols]

 
 

example.grm

# CDRewrite:给定一个转换器和两个上下文接受器(以及字母机),该指令将返回一个新的FST,用于在给定的上下文中执行字符串替换(rewrite,重写)。

第二个(左上下文)和第三个(右上下文)参数是未加权的接受器

第四个参数(sigma_star)是用于执行"最小化"的机器。

第五个参数指定重写的方向。我们可以"left-to-right,ltr"或"right-to-left,rtl"或"simultaneously,sim"重写。

第六个参数选择重写是否可选。它可以是强制性的(obligatory,obl)也可以是可选的(optional,opt)。

指定的符号[BOS]和[EOS]可以用来分别指定表示左右上下文的正则表达式中字符串的开始和结束。

请注意,[BOS]和[EOS]只能在CDRewrite函数中使用,而且,一般只想在左上下文中使用[BOS],同样,只在正确的上下文中使用[EOS]。

# 语法

CDRewrite [tau,lambda,rho,sigma_star,'ltr'|'rtl'|'sim','obl'|'opt']

 
 

# 强制性规则在字符串末尾的"d"前改"s"为"z"

CDRewrite ["s":"z","","d [EOS]"]

 
 

# 这一规则介绍字符串分隔符标签"[EOS]"的使用。由于英文缩写和小数中都有英文句号,而我们只想对每段话末尾的英文句号(后面可能有一个空格,紧接着其他的标点符号)进行分割。那么以下的规则的作用是:当某个英文句号后面是以一串空格或标点结尾时,我们在这个英文句号处插入一个空格。对于左上下文(left context),可以将字符串的起始表示为"[BOS]",即"Beginning Of the String"。

separate_final_period = CDRewrite["" : " ",

"",

"."

(bytelib.kPunct | bytelib.kSpace)* "[EOS]",

sigma_star]

 
 

 
 

# 下面的规则对两个transducer进行组合,然后对组合的结果进行优化。优化过程是在transducer上执行的,包含:去除空"epsilon"弧、对弧的权重加和、确定化(determinizing)和最小化(minimizing)。生成的transducers将变

得更小巧且有效。特别是当语法较大时,对一些中间部分的transducer进行优化通常是一个不错的做法,这样可以明显地提高编译的速度。

first_phase = Optimize[separate_punct @ separate_final_period];

 
 

我们将"word"定义为"anyword"或者是一个数字(如上所述),由number.grm中的数字语法或(愚蠢的)ernest规则处理。 下面这条规则说明了如何使用权重。 如果该规则与输入相匹配,那就要把"123"映射为"one hundred twenty three",而不是"123"。 我们可以通过使用权重来实现,不赞成使用"anyword"分析。 对于任何非空格字符串序列,分析器将允许这两个分析,但"anyword"分析将永远不受欢迎。 所以当TOKENIZER规则(如下)由一个字符串组成时,最好的(最短路径)分析将是带有数字分析的分析(如果有的话)。 权重根据热带(+,min)半球来解释(参见http://www.openfst.org下的"FST权重"),所以如下<1.0>的权重将不合意的"anyword",其具有隐含的 权重为0,也可以使用负权重,所以可以这样写:

 
 

FST字符串输入

 
 

以双引号包裹的字符串可用于定义基本的字符串FSTs。

 
 

这些字符串可以通过以下几种方式之一来解析:

  1. "abc".utf8
  2. "abc".byte
  3. arctic_symbol_table = SymbolTable['/path/to/bears.symtab'];

    "abc".arctic_symbol_table;

     
     

    双引号字符串中,允许以反斜线修饰的特殊字符:

    \n, newline

    \r, line feed

    \t, tab

     
     

     
     

关键词和符号

 
 

保留关键字和符号列表如下:

= 用于将右侧的对象赋值给左侧的对象;

exprt 用于指定要输出到FST档案中的FST符号(规则);

() 用于修饰需要进行预计算的表达式,优先级较高;

; 表示一个语句的结尾

# 注释

. 用于指定字符串FST的解析模式(默认为byte)

<> 用于指定FST的权重。放置在FST之后,将不带方括号的权重防止在该方括号中;

foo = "aaa" <1>;

goo = "aaa" : "bbb" <-1>;

import 用于导入其他grm文件中的函数和导出的FSTs

as 用于设定其他grm文件的别名

func 声明和定义函数;

[,,] 指定函数参数

return 将对象返回给调用者,文件主体中不可用。

 
 

标准库函数、运算以及常数

 
 

以下是带有特殊语法的内建函数,用于对FSTs进行运算。函数以优先度降序排列。

除非特别说明,所有的运算符都是左结合的,所有函数都将参数展开为VectorFst。

 
 

Closure

重复参数FST任意多次:

fst* 接收fst 0到多次

fst+ 接收fst 1到多次

fst{x,y} 接收fst最少x次,最多y次

Concatenation

将第二个FST拼接到第一个FST的末尾。该运算符是右结合的。

该函数还有一个不展开参数的延迟版。

foo bar

Concat[foo, bar]

ConcatDelayed[foo, bar]

Composition

将左侧的FST输出作为右侧FST的输入,两个FST合二为一。

使用显式的函数名则能指定排序方式。

foo @ bar

对右侧的FST的输入弧进行排序,相当于Compose[foo, bar, 'right']

Compose[foo, bar]

不进行弧的排序

Compose[foo, bar, 'left'|'right'|'both']

left:对左侧FST的输出排序

right:对右侧FST的输入排序

both:同时对左侧FST的输出和右侧FST的输入排序

Union

接收两者任意之一的FST。延迟版不展开参数

foo | bar

Union[foo, bar]

UnionDelayed[foo, bar]

 
 

Rewrite

将与第一个FST相匹配的字符串重写到第二个FST中(又称:向量积)

foo : bar

Rewrite[foo, bar]

 
 

Weight

在指定FST中附加权重

fst <weight>

ArcSort

对一个FST的所有状态的所有弧根据弧的输入或输出进行排序

ArcSort[fst, 'input'|'output']

Connect

使得FST变得全连接图,移除不可达的状态和路径

CDRewrite

个上下文接收器(以及字母表机),会生成一个在给定上下文中任意位置进行重写的新FST。

第二个(左上文)、第三个(右下文)和第四个(sigma star)函数是不带权接收器

第五个参数选择重写的方向。我们既可以左到右重写(ltr)也可以右到左重写(rtl),或者同时重写。

 
 

 
 

CDRewrite[tau, lambda, rho, sigma_star, 'ltr'|'rtl'|'sim', 'obl'|'opt']

## ltr obligatory rule changing "s" into "z" before a "d" at the end of a string

CDRewrite["s" : "z", "", "d[EOS]", sigma_star]

 
 

Determinize

使得一个FST变得确定化

Determinize[fst]

RmEpsilon

将给定FST中的所有epsilon(label 0)移除

RmEpsilon[fst]

 
 

Expand

显式地将提供的FST展开为VectorFst

Expand[fst]

Invert

将给定的FST倒置

Invert[fst]

Minimize

FST最小化

Minimize[fst]

Optimize

FST优化

Optimize[fst]

Project

将FST投影到输入维数或输出维数

Project[fst, 'input'|'output']

Reverse

反转FST

Reverse[fst]

 
 

RmWeight

移除FST的所有权重

RmWeight[myfst]

LoadFst

从文件中或FAR中加载FSTs

LoadFst['path/to/fst']

LoadFstFromFar['path/to/far', 'fst_name']

StringFile

加载由字符串列表或字符串二元组组成的文件,并将其编译(以byte模式)编译为表示这些字符串的联合的FST。这相当于"string1 | string2 | string3 | ...",但这样更高效。

StringFile['strings_file']

 
 

rws@catarina:~/tmp$ cat foo.sym

<eps> 0

얼룩말 1

개 2

딩고 3

코끼리 4

rws@catarina:~/tmp$ cat foo.grm

foo_syms = SymbolTable['foo.sym'];

export foo = StringFile['foo.txt', 'byte', foo_syms];

rws@catarina:~/tmp$ cat foo.txt

dingo 딩고

dog 개

zebra 얼룩말

elephant 코끼리

 
 

 
 

高级功能

 
 

先进后出转换器(Pushdown Transducer,PDT)

 
 

多栈先进后出转换器(Multi-Pushdown Transducer,MPDT)

 
 

功能与范式

 
 

功能

 
 

范式

 
 

替换转换器

 
 

小贴士

 
 

 
 

来自 <http://www.opengrm.org/twiki/bin/view/GRM/ThraxQuickTour>

 
 

Thrax-构建基于语法的语言模型工具的更多相关文章

  1. 使用 XMPP 构建一个基于 web 的通知工具——转

    Inserting of file(使用 XMPP 构建一个基于 web 的通知工具.docx) failed. Please try again. http://www.ibm.com/develo ...

  2. 自己动手用maven构建基于SSI的java EE应用

    上篇跟大家聊了聊maven的简单使用,之前也写了一篇搭建基于SSI(struts2,spring,ibatis)的javaEE开发环境的文章,但是那篇只是给初学者搭建一个简单的SSI应用的框架,其实我 ...

  3. Top11 构建和测试API的工具

    立刻像专业人士一样构建API 组织正在改变他们已经在软件应用项目中成功的微服务架构模型,这就是大多数微服务项目使用API(应用程序接口)的原因. 我们要为微服务喝彩,因为它相对于其他的模型有各种先进的 ...

  4. 基于MBT的自动化测试工具——GraphWalker介绍和实际使用

    GraphWalker是一个开源的基于模型的自动化测试工具,它可以用来通过图形测试模型来自动生成测试用例. 本文主要描述了使用yed画出FSM, EFSM模型图(常见的流程图),然后使用GraphWa ...

  5. maven-bundle-plugin插件, 用maven构建基于osgi的web应用

    maven-bundle-plugin 2.4.0以下版本导出META-INF中的内容到MANIFEST.MF中 今天终于把maven-bundle-plugin不能导出META-INF中的内容到Ex ...

  6. 正则表达式引擎的构建——基于编译原理DFA(龙书第三章)——3 计算4个函数

    整个引擎代码在github上,地址为:https://github.com/sun2043430/RegularExpression_Engine.git nullable, firstpos, la ...

  7. Net 项目构建基于Jenkins + Github + Mono 的持续集成环境

    Net 项目构建基于Jenkins + Github + Mono 的持续集成环境 阅读目录 1 安装 2 配置 3 测试 在Redhat enterprise 6.5 的服务器上,为在gutub 上 ...

  8. 使用PowerApps快速构建基于主题的轻业务应用 —— 入门篇

    作者:陈希章 发表于 2017年12月12日 前言 在上一篇文章 基于Office 365的随需应变业务应用平台 中我提到,随着随需应变的业务需要,以及技术的发展,业务应用的开发的模式也有了深刻的变化 ...

  9. SSM框架整合环境构建——基于Spring4和Mybatis3

    目录 环境 配置说明 所需jar包 配置db.properties 配置log4j.properties 配置spring.xml 配置mybatis-spring.xml 配置springmvc.x ...

随机推荐

  1. monkey常用命令实例

    一.常用命令的使用 1.monkey进行压力测试的命令是什么呢? adb shell monkey -p <packagename> <count> eg: adb shell ...

  2. centos 网卡状态

    由于ifconfig命令没法看到网卡的一些状态, 以下有5种方法查看网卡状态,是否连通网线 1)# dmesg | grep eth.....e1000: eth0 NIC Link is Up 10 ...

  3. JWT是什么鬼

    什么是JWT Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点 ...

  4. MySQL之执行流程

    最近开始在学习mysql相关知识,自己根据学到的知识点,根据自己的理解整理分享出来,本篇文章会分析下一个sql语句在mysql中的执行流程,包括sql的查询在mysql内部会怎么流转,sql语句的更新 ...

  5. Linux如何管理目录和文件属性

    概述:在Linux文件系统的安全模型中,为系统中的文件(或目录)赋予了两个属性:访问权限和文件所有者,简称为“权限”和“归属”.其中,访问权限包括读取.写入.可执行三种基本类型,归属包括属主(拥有该文 ...

  6. 【zabbix教程系列】五、邮件报警设置(脚本方式)

    本方式是使用外部邮箱账号发送报警邮件到指定邮箱. 好处是:此邮箱账号既能发送邮件,也能接收邮件,而且避免被当做垃圾邮件. 一.zabbix-server端安装mailx服务 [root@ltt01 ~ ...

  7. Java 多线程加锁的方式总结及对比(转载)

    转自https://blog.csdn.net/u010842515/article/details/67634813 参考博文:http://www.cnblogs.com/handsomeye/p ...

  8. 快速搭建一个vue开发环境

    常规的搭建就是从npm到vue到webpack这样一个一个的来,这样一套下来说不上复杂但是也不简单.之前公司的vue后台项目 我还是写的轻车熟路的,因为前端同事已经把架子搭好了,环境配置的丝般顺滑,你 ...

  9. YApi二次开发环境部署

    YApi 是去哪儿网大前端技术中心开源的一个可视化的接口管理平台.下面是在CentOS7下搭建二次开发环境步骤. 1 安装MongoDB 具体安装参考CentOS7安装MongoDB 2 安装Node ...

  10. Go语言中的make和new

    相同点: make和new都是用来创建分配类型内存的. 不同点: 先看下面的代码 package main import "fmt" func main(){ var i *int ...