关于unix:MobPush-Android-For-Unity

集成筹备注册账号应用MobSDK之前,须要先在MobTech官网注册开发者账号,并获取MobTech提供的AppKey和AppSecret,详情能够点击查看注册流程 下载MobPush对应的.unitypackage包关上 Github 下载 MobPush-For-Unity 我的项目,下载实现后间接双击或者在Unity外面抉择关上 MobPush.unitypackage,导入相干资源和脚本到您的 Unity我的项目即可应用。 集成注:MobPush For Unity我的项目对应的Android插件局部,应用的是gradle编译形式,因为gradle编译形式在Unity2017及以上版本能力很好地反对并且兼容,强烈建议宽广开发者应用Unity2017及以上的版本进行开发,Unity2017以下版本集成略微麻烦一丢丢;所以集成外围局部分成:(1)新版Unity集成形式(Unity2017及以上的版本)(2)旧版Unity集成形式注意事项(应用Unity2017版本以下开发的必看) Unity集成形式(倡议)要害文件:mainTemplate.gradle和proguard-user.txt1、Unity2017及以上版本,在Build Settings > Player Settings上面,有两个开关,新建我的项目的话关上这两个开关就能够在Plugins>Android生成对应的两个文件;因为这两个文件MobPush都有间接提供,只需导入.unitypackage就好,Unity检测到曾经存在这两个文件,主动会更新为勾选状态;2、Build的时候有一个Build System选项,此选项默认抉择的Internal,切记要改成抉择外面的gradle选项(重要)3、图中所示的mainTemplate.gradle文件,即为集成的外围文件,应用编辑器关上此文件,要点内容如下:此处为辨别Unity5.6和Unity2017 gradle插件版本的中央,开发时用到哪个版本就应用哪个,若应用到其余Unity版本,请随便抉择一个,而后build,编译的时候会报错的,Console控制台信息报错时会提醒插件版本是多少,依据提醒批改成须要的版本就好(只批改前面的数字,比方:2.3.0或者2.1.0) buildscript { repositories { // 配置Mob Maven库 maven { url "https://mvn.mob.com/android" } // 配置HMS Core SDK的Maven仓地址。(集成华为厂商须要增加) maven { url 'https://developer.huawei.com/repo/'} } ... } dependencies { classpath 'com.android.tools.build:gradle:2.3.0'//Unity2017 //classpath 'com.android.tools.build:gradle:2.1.0'//Unity5.6 // 注册MobSDK classpath "com.mob.sdk:MobSDK:2018.0319.1724" }}此处为集成MobPush须要配置的信息 // 增加插件apply plugin: 'com.mob.sdk'// 在MobSDK的扩大中注册MobPush的相干信息MobSDK {appKey "替换为MobTech官网申请的appkey"appSecret "替换为MobTech官网申请的appkey对应的appSecret"MobPush { //集成其余推送通道(可选) devInfo { //华为推送配置信息 HUAWEI{ appId "华为的appid" } //魅族推送配置信息 MEIZU{ appId "魅族的appid" appKey "魅族的appkey" } //小米推送配置信息 XIAOMI{ appId "小米的appid" appKey "小米的appkey" } //FCM推送通道配置 FCM{ //设置默认推送告诉显示图标 iconRes "@mipmap/ic_launcher" } }}此处为配置签名文件和签名文件的别名和明码(正式公布apk须要的签名文件),能够写绝对路径,也能够写相对路径,相对路径应用”..\”跳出一层目录,跳出多层则间断拼接 ...

October 10, 2022 · 2 min · jiezi

关于unix:SIGTTINSIGTTOU-信号

SIGTTIN: 当一个后盾过程组试图读取其管制终端时,终端驱动程序产生此信号。在下列例外情况不产生次信号: a、读过程疏忽或者梗塞此信号 b、读过程所属的过程组是孤儿过程组,此时读操作返回出错,errno设置未EIO。 SIGTTOU: 当一个后盾过程组试图写其管制终端时,终端驱动程序产生此信号。与SIGTTIN信号不同,一个过程能够算着容许后盾过程写管制终端。 如果不容许写管制终端,则与SIGTTIN类似,也有两种非凡状况: a、写过程疏忽或者梗塞此信号 b:写过程所属的过程组是孤儿过程组,此时读操作返回出错,errno设置未EIO。 SIGTTIN 和 SIGTTOU 信号的默认动作是暂停过程。 下图代码,过程启动,fork 出子过程,子过程设置过程组,调用tcsetpgrp 将本人设置为前端过程组,父过程就变成了后端过程组。在read的时候,暂停。 #include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <signal.h>#include <sys/wait.h>//打印过程信息void pr_process(char * name){ printf("%s pid:%d,ppid:%d,pgid:%d,sid:%d,grrp:%d\n",name,getpid(),getppid(),getpgid(getpid()),getsid(getpid()),tcgetpgrp(STDIN_FILENO));}void handler(int sig){ printf("receive %d sig\n",sig);}int main(int argc,char *argv[]){ pid_t pid ; pid_t fpgid = tcgetpgrp(STDIN_FILENO); if((pid = fork()) < 0){ perror("fork error"); exit(1); } if(pid == 0){ signal(SIGTTOU,SIG_IGN); setpgid(getpid(),getpid()); pr_process("child before set:"); if(tcsetpgrp(STDIN_FILENO,getpid()) == -1){ printf("set error\n"); exit(2); } pr_process("child after set"); exit(1); } pr_process("parent1"); waitpid(pid,NULL,0); pr_process("parent2"); char buf[100];// signal(SIGTTIN,handler); if(read(STDIN_FILENO,buf,100) < 0){ perror("read error"); printf("error\n"); exit(127); } printf("sucess\n"); return 0;}

August 18, 2022 · 1 min · jiezi

关于unix:UnixLike终端命令强化之路

这篇文章针对的是Unix-Like平台,也就是Linux和Mac 常见命令优化ll命令形容除了Ubuntu,其余的都没有这个命令。ll命令是通过 ls -al实现的,然而这个命令有毛病:高亮不够难看、信息能够更具体exa命令能够优化 装置形式先装置rust,而后通过cargo装置 配置批改shell的配置文件,增加如下内容: alias ll="exa -lahiSgH"cat命令形容自带的cat命令只是简略的显示文件内容,没有针对代码的高亮显示 装置形式通过pip装置 pip3 install Pygments配置alias cat="pygmentize -P style=perldoc -P tabsize=4 -f terminal256 -g "注:不要遗记最初的空格能够应用fruity配色 成果展现windows 彩色背景成果 参考文章https://help.farbox.com/pygme... 常见软件优化vim形容mac下的vim默认没有开启高亮,这给文本的浏览制作的艰难 配置编辑.vimrc文件 vim ~/.vimrc增加 syntax on

May 22, 2021 · 1 min · jiezi

Linux常用指令以及入门介绍

Linux - 稳定、安全、多并发section1:**内容介绍 ***基础: - 入门、vm和Linux安装、目录结构; - Linux Shortcut keys: -- CTRL+A/E行首行尾; -- ctrl+U/k:擦除光标到行首/行尾; -- CTRL+Y:回退擦除的文本;***实际操作: - 远程登录(xshell xftp)|vi和vim编辑器|开机、重启、用户登录注销|用户管理 - 实用指令|定时任务调度|磁盘分区、挂载|网络配置|进程管理|RPM和YUM***python定制 - python专业开发平台Ubuntu、python开发环境、APT软件管理和远程登录**学习方向 ***Linux运维工程师***Linux嵌入式工程师-驱动开发***Linux下开发项目:Java、python、bigdata、PHP、c/c++**应用领域 ***个人桌面领域***服务器领域***嵌入式领域**进阶之路 ***基本操作命令:文件操作(rm,mkdir,chmod,chown)、vi/vim使用、Linux用户管理***linux各种配置:环境变量、网络配置、服务配置;***搭建相关语言的开发环境(java、python);***shell脚本编写,Linux服务器维护;[必会]***安全设置,防止攻击,保障运行,系统调优;√***深入了解Linux系统[对内核有研究],熟练大型网站应用架构组成,熟悉各环节的部署和维护;√**学习方法 ***高效愉快学习;***先整体框架,再细节;***指令;***"know how,know why"***"做中学"***适当囫囵吞枣***重点实际操作section2:Linux基础** Linux介绍 ***操作系统,免费,开源,安全,高效,稳定,处理高并发强悍,企业级项目部署到Linux/Unix服务器运行;***创始人:Linus Torvalds - Linux kernel;吉祥物:企鹅 - Tux;***主要发行版:内核基础上包装定制,Centos、Redhat[Redhat公司]|Ubuntu|Suse、openSuse[欧洲]|红旗Linux***主要操作系统:Windows、Android、iOS、macOS、车载系统、Linux等***Linux和Unix: - Ken Tompson|Dennis Richres 贝尔实验室 > B语言|C语言|Unix > Minix > Linux[GNU计划的一部分] - Richard Stallman:GNU计划 --- 人机互动 > application > GNU shell > OS[linux kernel] > hardware - Linux:GNU/Linux < Minix**VM和Linux(CentOS)的安装 ...

September 11, 2019 · 5 min · jiezi

gcc编译参数

编译 gcc -c main.c ==== 编译不链接,生成.o目标文件 gcc -E main.c ==== 预处理 gcc -S main.c ==== 只编译不汇编 gcc -g main.c -o main_d ==== 可进行gdb调试 gcc -Dname='xinzhu' === 定义宏 define name 'xinzhu' gcc main.c -o main -I../path gcc main.c -o main -I../path -L../path gcc -I [大写字母i]寻找头文件目录 /usr/local/include gcc -L [大写字母l]寻找库文件 /usr/local/lib gcc -l word [小写字母l], 寻找动态链接库文件libword.so静态库 .a结尾 # 创建.o目标文件 gcc -c test.c -o libtest.o #创建libtest.a静态库 ar rcs libtest.a libtest.o #链接静态库 gcc -o test main.c -ltest动态库 .so结尾 # 使用位置无关代码创建目标文件 gcc -c -fPIC test.c -o test.o # 创建共享库libtest.so gcc -shared -o libtest.so test.o # 链接静态库 gcc -o test main.c -ltest

September 8, 2019 · 1 min · jiezi

makefile

执行流程1.读入主Makefile (主Makefile中可以引用其他Makefile)2.读入被include的其他Makefile2.初始化文件中的变量4.推导隐晦规则, 并分析所有规则5.为所有的目标文件创建依赖关系链6.根据依赖关系, 决定哪些目标要重新生成7.执行生成命令内置环境变量MAKECMDGOALS 变量记录了命令行参数指定的终极目标列表例: make hello world $(MAKECMDGOALS) = hello world= ?= :=var1 = value1 最基本的赋值, 不立即展示变量var2 := $(value2 )立即展开变量, := 只能使用前面定义好的变量, = 可以使用后面定义的变量var3 ?= value3 只有在该变量为空时才设置值var4 += value4 将值追加到变量的尾端错误抑制符 @ -不用前缀, 输出执行的命令以及命令执行的结果, 出错的话停止执行前缀 @, 只输出命令执行的结果, 出错的话停止执行前缀 -, 命令执行有错的话, 忽略错误, 继续执行 例: @echo $(name)$@ $^ $< $?$@ 表示目標文件$^ 表示所有依赖文件$+ 表示所有依赖(文件包含重复)$< 表示第一个依赖文件$? 表示比目标还要新的依赖文件列表wildcard pattern placeholder src := a.c b.c $(wildcard *.c) 匹配所有后缀.c文件 $(src: .c=.c) 替换文件后缀.c为.o 模式佔位符匹配规则: 目标和依赖文件名必须一样, 即a.c, a.c %.o : %.c $(CC) -c $< -o $@.PHONY 伪目标 .PHONY: clean clean: rm -rf *findstring$(findstring <find>,<in>) #函数功能: 在字符串<in>中查找<find>字符串#返回:如果找到,那么返回<find>,否则返回空字符串。filter$(filter pattern…,text)#函数功能: 过滤掉字串"TEXT"中所有不符合模式“PATTERN”的单词, 保留所有符合此模式的单词. 可以使用多个模式, 模式中一般需要包含模式字符"%"#返回值: "TEXT"字串中所有符合模式"PATTERN"的字串words$(words <text>)#函數功能: 统计中字符串中的单词个数#返回值: 返回中的单词数strip$(strip <string>)功能:去掉<string>字串中开头和结尾的空字符。返回:返回被去掉空格的字符串值

September 7, 2019 · 1 min · jiezi

charles-快速设置本地代理抓包http请求-for-mac

Mac平台下调试手机APP的应用调用接口,使用charles进行代理,拦截请求的url,查看请求和响应。或者进行请求注入。 一、打开charles工具 二、设置mac系统代理 三、快速设置完成后,即可监测到本地http请求;

July 14, 2019 · 1 min · jiezi

Unix-常用命令-SED

文件编辑SEDSED 命令一般用于替换文件中的文本。匹配内容支持正则表达式。 基本用法 // 替换a.txt文件中的hello为hi,默认替换掉每一行的第一个hello$ sed 's/hello/hi/' a.txtflag $ sed 's/hello/hi/<flag>' a.txt几个不同的flag <n>: 如1, 2, 3等整数,替换掉每行的第n个匹配g: 替换掉全部匹配<n>+g: 如2g, 则表示替换掉每行的第2个到所有剩余的匹配p: 将包含匹配项的行在输出中打印两遍d: 删除匹配项所在的行特定行 $sed '3 s/hello/hi/' a.txt //只替换第3行$sed '1,3 s/hello/hi/' a.txt //替换第1到3行$sed '3,$ s/hello/hi/' a.txt //替换第3到末行$sed '1,3d' a.txt //删除第1到3行

July 14, 2019 · 1 min · jiezi

进程切换与线程切换的区别

注意这个题目问的是进程切换与线程切换的区别,不是进程与线程的区别。当然这里的线程指的是同一个进程中的线程。 这个问题能很好的考察面试者对进程和线程的理解深度,有比较高的区分度。 要想正确回答这个问题,面试者需要理解虚拟内存。 虚拟内存解放生产力对于程序员来说,我们在编程时实际上是不怎么操心内存问题的,对于使用Java、Python、JavaScript等动态类型语言的程序员来说更是如此,自动内存回收机制的引入使得使用这类语言的程序员几乎完全不用关心内存问题;即使对于编译型语言C/C++来说,程序员需要关心的也仅仅是内存的申请和释放。 总的来说,作为程序员(无论使用什么类型的语言)我们根本就不关心数据以及程序被放在了物理内存的哪个位置上(设计实现操作系统的程序员除外),我们可以简单的认为我们的程序独占内存,比如在32位系统下我们的进程占用的内存空间为4G;并且我们可以申请超过物理内存大小的空间,比如在只有256MB的系统上程序员可以申请1G大小的内存空间,这种假设极大的解放了程序员的生产力。 而这种假设实现的背后功臣就是虚拟内存。 什么是虚拟内存虚拟内存是操作系统为每个进程提供的一种抽象,每个进程都有属于自己的、私有的、地址连续的虚拟内存,当然我们知道最终进程的数据及代码必然要放到物理内存上,那么必须有某种机制能记住虚拟地址空间中的某个数据被放到了哪个物理内存地址上,这就是所谓的地址空间映射,也就是虚拟内存地址与物理内存地址的映射关系,那么操作系统是如何记住这种映射关系的呢,答案就是页表,页表中记录了虚拟内存地址到物理内存地址的映射关系。有了页表就可以将虚拟地址转换为物理内存地址了,这种机制就是虚拟内存。 每个进程都有自己的虚拟地址空间,进程内的所有线程共享进程的虚拟地址空间。 现在我们就可以来回答这个面试题了。 进程切换与线程切换的区别进程切换与线程切换的一个最主要区别就在于进程切换涉及到虚拟地址空间的切换而线程切换则不会。因为每个进程都有自己的虚拟地址空间,而线程是共享所在进程的虚拟地址空间的,因此同一个进程中的线程进行线程切换时不涉及虚拟地址空间的转换。 举一个不太恰当的例子,线程切换就好比你从主卧走到次卧,反正主卧和次卧都在同一个房子中(虚拟地址空间),因此你无需换鞋子、换衣服等等。但是进程切换就不一样了,进程切换就好比从你家到别人家,这是两个不同的房子(不同的虚拟地址空间),出发时要换好衣服、鞋子等等,到别人家后还要再换鞋子等等。 因此我们可以形象的认为线程是处在同一个屋檐下的,这里的屋檐就是虚拟地址空间,因此线程间切换无需虚拟地址空间的切换;而进程则不同,两个不同进程位于不同的屋檐下,即进程位于不同的虚拟地址空间,因此进程切换涉及到虚拟地址空间的切换,这也是为什么进程切换要比线程切换慢的原因。 有的同学可能还是不太明白,为什么虚拟地址空间切换会比较耗时呢? 为什么虚拟地址切换很慢现在我们已经知道了进程都有自己的虚拟地址空间,把虚拟地址转换为物理地址需要查找页表,页表查找是一个很慢的过程,因此通常使用Cache来缓存常用的地址映射,这样可以加速页表查找,这个cache就是TLB,Translation Lookaside Buffer,我们不需要关心这个名字只需要知道TLB本质上就是一个cache,是用来加速页表查找的。由于每个进程都有自己的虚拟地址空间,那么显然每个进程都有自己的页表,那么当进程切换后页表也要进行切换,页表切换后TLB就失效了,cache失效导致命中率降低,那么虚拟地址转换为物理地址就会变慢,表现出来的就是程序运行会变慢,而线程切换则不会导致TLB失效,因为线程线程无需切换地址空间,因此我们通常说线程切换要比较进程切换块,原因就在这里。 总结虚拟内存是现代操作系统极其重要的一部分,当然在这里限于篇幅我们只能简单介绍,关于虚拟内存的详细讲解见后续操作系统教程,敬请期待 :) 更多计算机内功文章,欢迎关注微信公共账号:码农的荒岛求生。 计算机内功决定程序员职业生涯高度

July 13, 2019 · 1 min · jiezi

2019-年-最简单最通俗的-vagrant-安装使用说明附带示例Vagrantfile

2019 年 最简单最通俗的 vagrant 安装使用说明,附带示例vagrantfileVagrant是一个基于Ruby的工具,用于创建和部署虚拟化开发环境。它 使用Oracle的开源VirtualBox虚拟化系统,使用 Chef创建自动化虚拟环境。 老套路,更新留坑vagrant 安装官网链接vagrant windows 下载64 位下载:https://releases.hashicorp.co...32 位下载:https://releases.hashicorp.co...百度云64位下载: 链接:https://pan.baidu.com/s/1oiztOlj0S_h6AfQ6WdUb_w 提取码:aoph vagrant mac 下载64 位下载: https://releases.hashicorp.co...vagrant box 下载官网下载:https://app.vagrantup.com/box...百度云下载: 提取码:aophvagrant box 添加到本地镜像下载好的镜像添加vagrant box add {镜像名称} {镜像地址}例如: vagrant box add C:/box/centos7.box --name centos/7.5 使用远程镜像vagrant box add https://mirrors.tuna.tsinghua.edu.cn/ubuntu-cloud-images/bionic/current/bionic-server-cloudimg-amd64-vagrant.box --name ubuntu/bionicvagrant 命令说明vagrant up 启动/创建虚拟机G:\project vagrant up ci1.cn && vagrant ssh ci1.cnBringing machine 'ci1.cn' up with 'virtualbox' provider...==> ci1.cn: Clearing any previously set forwarded ports...==> ci1.cn: Vagrant has detected a configuration issue which exposes a.....Last login: Mon Jun 24 06:40:46 2019 from 10.0.2.2[vagrant@ci1 ~]$ lsnode-v12.3.1 node-v12.3.1.tar.gz project[vagrant@ci1 ~]$vagrant ssh 进行虚拟机交互命令行G:\project vagrant ssh ci1.cnLast login: Mon Jun 24 06:40:46 2019 from 10.0.2.2[vagrant@ci1 ~]$vagrant reload 重新启动虚拟机vagrant reload ci1.cnvagrant up/reload --provision 重新创建或重新执行脚本vagrant up --provisionvagrant reload --provisionvagrant status 查看当前目录下的虚拟机状态vagrant status例如: ...

June 25, 2019 · 3 min · jiezi

2019年最新最快最简洁最详细的docker-和-dockercompose-安装使用说明

2019年最新最快最简洁最详细的docker 和 docker-compose 安装使用屁话不多说,直接开始重要内容 本区域留用与后续更新docker 安装windows 专业版安装 docker系统要求Docker for Windows 支持 64 位版本的 Windows 10 Pro,且必须开启 Hyper-V。 百度盘下载链接:https://pan.baidu.com/s/1Lkcaz7rMyepsWDIxXTb1zw 提取码:xfwu 复制这段内容后打开百度网盘手机App,操作更方便哦直接下载链接点我安装下载好之后双击 Docker for Windows Installer.exe 开始安装。 mac版本下载点我安装下载好之后双击 Docker.dmg 开始安装。 linux 安装推荐安装方式:阿里云 # install docker curl -fsSL https://get.docker.com | sudo bash -s docker --mirror Aliyun rm -rf get-docker.sh # start docker service sudo systemctl enable docker sudo systemctl restart docker # 配置镜像加速器 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://dt77flbr.mirror.aliyuncs.com"] } EOF sudo systemctl daemon-reload sudo systemctl restart dockerdocker 使用命令查看运行中的容器docker ps -a创建容器docker run ....举例: ...

June 24, 2019 · 1 min · jiezi

socket和accept返回的套接字fd有什么区别

记录unix网络编程的复习之路简单回顾下socket连接过程socket() --得到fd! 功能:指定了协议族(IPv4、IPv6或unix)和套接口类型(字节流、数据报或原始套接口)。但并没有指定本地协议地址或远程协议地址。 定义:int socket(int family, int type, int protocol); 返回:出错:-1 成功:套接口描述字 (socket file descriptor)(套接字)sockfdbind() --我在哪个端口? 功能:给套接口分配一个本地协议地址。 定义:int bind(int sockfd, const struct sockaddr *my_addr, int addrlen);connect() --Hello! 功能:建立与TCP服务器的连接 定义:int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);listen() --有人给我打电话吗? 功能:将未连接主动套接口的转换为被动套接口,指示内核接受对该套接口的连接请求。 定义:int listen(int sockfd, int backlog); 参数: - sockfd调用socket函数返回的文件描述符(套接字). - 未完成连接队列和已完成连接队列的上限. - 未完成连接队列 : 服务端还未完成三次握手全部过程的一个队列. - 已完成连接队列 : 服务端已经完成三次握手全部过程的一个队列, 等待accept函数从这个队列中返回下一个(返回其实是取出, 该套接字不在已完成队列中了)套接字.accept() --"Thank you for calling port 3490." ...

June 13, 2019 · 1 min · jiezi

PowerVM

wiki相关文章索引:https://en.wikipedia.org/wiki...基础入门:http://www.redbooks.ibm.com/a... PowerVMPowerVM,以前被称为APV,是在基于IBM POWER处理器的硬件平台上,提供的具有行业领先水平的虚拟化技术家族。 逻辑分区(LPAR):微分区:可以将一组处理器分配到共享处理器池(SPP), 然后使用LPAR可以使用这些处理器,此时服务器上只有一个SPP,但多个LPAR可以共享这些资源。虚拟I/O服务器(VIOS): 是一个分区,提供I/O资源共享(网卡和存储)虚拟LAN: 连接多个LPAR,HMC可以定义虚拟LAN设备,从而使LPAR通过内存而非以太网连接,一个LPAR可支持256个虚拟LAN。共享以太网适配器: SEA在客户机中的虚拟以太网适配器和主机服务器中的实际适配器之间路由数据。存在于虚拟I/O服务器上 HMC提供了三种接口: classic(-8.7.0), enhanced(+8.2.0, template), enhanced+,

June 1, 2019 · 1 min · jiezi

Manjaro安装配置美化字体模糊发虚解决记录

Manjaro安装记录前言: 记录自己Manjaro18安装的一些坑,避免下次满互联网找解决方法。在此之前试过Manjaro、Ubuntu、Fedora、linux Mint系统的pac、yum、apt都用过了,所以果断选择Manjaro的包管理方式。Xfce4、Gnome、Cinnamon 和Mate桌面环境都试过了,KDE没试过,因为KDE 被抛弃了。其中呢我觉得xfce4最好,比较轻,资源占用低,但是我还是选择了Gnome,因为这个比较符合我的审美,而且现在(2019.3.31)gnome3.32已经没那么多问题了,资源占用也没那么夸张,cpu一般不会超过5%,还是在用了很多插件情况下,有两个插件一用就会超过7%:如果是新手,安装完之后建议不要急着还原u盘,因为后面重装的路还长,不知道一个不注意就卸载了不该卸的,然后…..安装: rufus以dd模式写入U盘,bios关闭安全启动,U 盘启动,选择driver选择non-free,比开源驱动好的了,双显卡也能很好的解决。然后都是图形界面了,不多说。只有开始点击开始安装按钮如果安装程序闪退,多半是没联网,连上网就好了,卡在93%进度多半又是因为电脑还联网,关了网络就好了。配置:排列国内源:sudo pacman-mirrors -i -c China -m rank 清华源(tuna)最快,但是我这有一个依赖后面升级时候,清华的源没有这个文件,换成其他源更新好才改回来Archlinux改清华源:sudo gedit /etc/pacman.conf[archlinuxcn]SigLevel = Optional TrustedOnlyServer = https://mirrors.tuna.tsinghua.edu.cn/archlinuxcn/$arch更新一下:pacman -Syyu更新签名:sudo pacman -Syy && sudo pacman -S archlinuxcn-keyringAur源改国内:待填坑。。。安装yay:sudo pacman -S yay因为yaourt停更了,只有这一个我用着还不错,以后安装东西直接yay+包名输入法安装:sudo pacman -S fcitx-sogoupinyinsudo pacman -S fcitx-im sudo pacman -S fcitx-configtool或者google拼音:第一行改成sudo pacman -S fcitx-googlepinyin,谷歌拼音的话,如果全部安装了依赖,可以在包管理卸载qt5那几个无用的软件。然后 sudo gedit ~/.profile底部加入下面几行来指定输入法。export LC_CTYPE=zh_CN.UTF-8export GTK_IM_MODULE=fcitxexport QT_IM_MODULE=fcitxexport XMODIFIERS="@im=fcitx"然后就是调缩放问题,要不然那么小的字会看瞎。Arch wiki上给出的解决办法那个自定义缩放比例,默认只有200%缩放比例,在我这没用,更辣眼睛,所以调字体放大倍数。 优化–>字体–>缩放字体–>1.5字体我用的是思源黑体(adobe家开源的),文泉驿和google家的noto系列也不错。noto系列cjk指的是中国韩国和日本,中国大陆好像是S开头的字体,因为太大了就没有安装。chrome等其他浏览器可以在浏览器设置里改一下字体风格,然后在/etc/fonts/新建一个local.conf文件写入:<?xml version=“1.0”?><!DOCTYPE fontconfig SYSTEM “fonts.dtd”><fontconfig> <match target=“font”> <edit name=“autohint” mode=“assign”> <bool>false</bool> </edit> <edit name=“hinting” mode=“assign”> <bool>false</bool> </edit> <edit name=“hintstyle” mode=“assign”> <const>none</const> </edit> </match></fontconfig>这样软件默认就不会用自己的文字处理方式了,和win下字体基本无太大差别,字体模糊问题解决,如图:然后就是卸载没用的软件了,基本上依赖不多的都可以卸载,gnome自带的磁盘分析和笔记本便签字符映射闹钟天气日历qt5那些都被我卸载了我有强迫症,不用的东西一个都不留,自带的那一套主题和字体也被我卸了。。。zshzsh默认已经有了,shell cat / etc / shells查看有没有。安装oh-my-zsh:sh -c“$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)”更换zsh:chsh -s / bin / zsh然后可以配置了:分别是自动跳转、语法建议、语法高亮插件。sudo pacman -S autojumpgit clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-/.oh-my-zsh/custom}/plugins/zsh-autosuggestionsgit clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting然后配之~/.zshrc文件:#主题ZSH_THEME=“steeef”# 纠错ENABLE_CORRECTION=“true”# 提示COMPLETION_WAITING_DOTS=“true”# 插件plugins=( git zsh-autosuggestions web-search autojump zsh-syntax-highlighting)source ~/.oh-my-zsh/plugins/incr/incr*.zshexport UPDATE_ZSH_DAYS=7双显卡切换问题: bumblebee系统默认安装好了:安装依赖:sudo pacman -S virtualgl lib32-virtualgl lib32-primus primus开启服务:sudo systemctl enable bumblebeed添加用户组:sudo gpasswd -a $USER bumblebee重启后optirun+应用程序名 即可用独显打开应用程序。测试性能:集显性能:glxgears -info独显性能:optirun glxgears -info如果独显依旧是60fps的话那就是依赖没安装,安装依赖:sudo pacman -S virtualgl lib32-virtualgl lib32-primus primus美化: manjaro18 gnome版已经美化的相当可以了,但是我不喜欢。。。图标:sudo pacman -S numix-icon-theme主题:yay -S arc-gtk-theme然后把自带的删了……扩展: 自带的基本够了,列出我的参考一下:Applications menu(类win应用程序选择查找)Clipboard indicator(剪贴板)因为googlepinyin自带的也不错,放弃这个了Dash to dock(dock栏自定义)Dash to panel(状态栏自定义)Desktop icons(桌面图标)Places status indicator(快速访问)Simple net speed(网速栏)Tray icons(顶栏显示后台运行窗口)Removable driver men(挂载状态栏)软件:<u>下面就是我用到的软件了,包管理里都有,可以命令行安装也可以在包管理里搜索安装:</u>推荐在包管理列表搜索安装,详情里可以让自己更好的选择。下面是一些有坑的安装:安装QQ:yay -S deepin.com.qq.im wine下的qq、和tim,还是有点小问题的自己体验一下安装Tim:yay -S deepin.com.qq.office安装微信:yay -S wewechat 第三方的微信,英文&&开源。软件包里的pycharm和idea社区版在1.5倍字体放大后真的很辣眼睛,改字体大小还能接受,但是复选框和状态栏图标等依然很大。最好的办法是:官网下载toolbox,这个jetbrains家的软件管理是Appimage打包的,在哪种linux环境下都可以运行,然后下载社区版idea2019和pycharm2018.3.5,显示就很完美了:[图片上传失败…(image-1ccfdb-1554217428204)]笔记只有wiznote在linux下还行。SS-qt5文明上网,生成pac规则。。。具体不解释。网盘同步只有Dropbox在linux下比较完美,启动时要手动设置代理127.0.0.1,port:1080。kolourpaint:简单图片编辑peek:录制gifvim:网上搜一下配置SimpleScreenRecorder:录屏JDKyay jdk 选择合适的版本,输入数字回车。建议不要选jdk8以下的和openJDK。archlinux-java status 查看jdk状态。sudo archlinux-java set jdk-12 设置jdk版本。java -version 查看是否成功设置,成功了就可以卸载自带的openJDK8了大家用不到系列,记录一下:medis、mysql wprkbench、Charles、filezilla、mitmproxy、anacondeanaconde需要在.zshrc里设置路径 export PATH="/opt/anaconda/bin:$PATH"如果没用zsh就是在.bashrc里设置。如果用的是zsh就算最后输入yes设置默认环境变量也没用,具体参考anaconda wiki。查看当前存在哪些虚拟环境:conda env list创建Python虚拟环境:conda create -n zeronet python=3.6激活虚拟环境:source activate zeronet对虚拟环境中安装额外的包:conda install -n zeronet [package]关闭虚拟环境:source deactivate zeronet删除虚拟环境:conda remove -n your_env_name –all<h6>aria2配置:/etc/aria2下新建aria2.conf、aria2.log、aria2.session</h6><p> 开启监听:sudo aria2c <span style=‘font-family:“PT Serif”, “Times New Roman”, Times, serif’>–</span>conf<span style=‘font-family:“PT Serif”, “Times New Roman”, Times, serif’>-</span>path=/etc/aria2/aria2.conf</p><p> 可以增加自启动脚本</p><pre>dir=/home/zz/Downloadsdisable-ipv6=true断点续传continue=trueinput-file=/etc/aria2/aria2.sessionsave-session=/etc/aria2/aria2.session启用磁盘缓存, 0为禁用缓存, 需1.16以上版本, 默认:16Mdisk-cache=32M文件预分配方式, 能有效降低磁盘碎片, 默认:prealloc预分配所需时间: none < falloc ? trunc < preallocfalloc和trunc则需要文件系统和内核支持, NTFS建议使用falloc, EXT3/4建议truncfile-allocation=trunc断点续传continue=true最大同时下载任务数, 运行时可修改, 默认:5max-concurrent-downloads=5同一服务器连接数, 添加时可指定, 默认:1max-connection-per-server=5最小文件分片大小, 添加时可指定, 取值范围1M -1024M, 默认:20M假定size=10M, 文件为20MiB 则使用两个来源下载; 文件为15MiB 则使用一个来源下载min-split-size=10M单个任务最大线程数, 添加时可指定, 默认:5split=64整体下载速度限制, 运行时可修改, 默认:0max-overall-download-limit=0单个任务下载速度限制, 默认:0max-download-limit=0整体上传速度限制, 运行时可修改, 默认:0max-overall-upload-limit=0单个任务上传速度限制, 默认:0max-upload-limit=0禁用IPv6, 默认:falsedisable-ipv6=true进度保存相关从会话文件中读取下载任务input-file=aria2.session在Aria2退出时保存错误/未完成的下载任务到会话文件save-session=aria2.session定时保存会话, 0为退出时才保存, 需1.16.1以上版本, 默认:0save-session-interval=60RPC相关设置enable-rpc=true允许所有来源, 默认:falserpc-allow-origin-all=true允许非外部访问, 默认:falserpc-listen-all=true事件轮询方式, 取值:[epoll, kqueue, port, poll, select], 不同系统默认值不同event-poll=selectRPC监听端口, 端口被占用时可以修改, 默认:6800rpc-listen-port=6800BT/PT下载相关当下载的是一个种子(以.torrent结尾)时, 自动开始BT任务, 默认:truefollow-torrent=trueBT监听端口, 当端口被屏蔽时使用, 默认:6881-6999listen-port=51413单个种子最大连接数, 默认:55bt-max-peers=55打开DHT功能, PT需要禁用, 默认:trueenable-dht=false打开IPv6 DHT功能, PT需要禁用enable-dht6=falseDHT网络监听端口, 默认:6881-6999dht-listen-port=6881-6999本地节点查找, PT需要禁用, 默认:falsebt-enable-lpd=false种子交换, PT需要禁用, 默认:trueenable-peer-exchange=false每个种子限速, 对少种的PT很有用, 默认:50Kbt-request-peer-speed-limit=50K客户端伪装, PT需要peer-id-prefix=-TR2770-user-agent=Transmission/2.77当种子的分享率达到这个数时, 自动停止做种, 0为一直做种, 默认:1.0seed-ratio=0强制保存会话, 话即使任务已经完成, 默认:false较新的版本开启后会在任务完成后依然保留.aria2文件force-save=falseBT校验相关, 默认:truebt-hash-check-seed=true继续之前的BT任务时, 无需再次校验, 默认:falsebt-seed-unverified=true保存磁力链接元数据为种子文件(.torrent文件), 默认:falsebt-save-metadata=true</pre><p> </p> ...

April 3, 2019 · 2 min · jiezi

对话 CTO〡和 PingCAP CTO 黄东旭聊开源数据库新蓝海

专栏介绍「对话 CTO」是极客公园的一档最新专栏,以技术人的视角聊聊研发管理者的发展和成长。本专栏由ONES 的创始人&CEO 王颖奇作为特邀访谈者。王颖奇曾参与金山软件 WPS、金山毒霸等大型软件的核心开发工作;2011 年创立了正点科技,旗下产品正点闹钟、正点日历在全球用户过亿;2014 年,王颖奇在知名美元基金晨兴资本任 EIR,并以个人身份参与十余家公司的管理咨询工作;2015 年,王颖奇创立 ONES,致力于提供企业级研发管理解决方案。摘要有像甲骨文这样的统治级巨头在,数据库市场还是个好的创业领域吗?在 PingCAP 联合创始人&CTO 黄东旭眼中,答案是肯定的,数据库行业的转折点已经到了。黄东旭曾在豌豆荚从事 infrastructure 相关工作,在分布式存储领域有着多年的积累和实战经验。在他看来,伴随着分布式数据库理念和技术的成熟,对传统数据库理念和技术的依赖正在走向瓦解。开源理念的普及也在加速数据库行业走向下一个阶段,「像数据库、操作系统、云技术,或者云内部的基础软件,未来只有开源一条路,如果不开源,或者说内核不开源的话,产品的生命力是很差的。」一切正在 PingCAP 中顺利落地。作为开源新型分布式数据库公司,PingCAP 研发了分布式关系型数据库 TiDB 项目,具备「分布式强一致性事务、在线弹性水平扩展、故障自恢复的高可用、跨数据中心多活」等核心特性。目前公司准生产测试用户 1400 余家,涉及互联网、游戏、银行、保险、证券、航空、制造业、电信、新零售、政府等多个行业。本期对话 CTO,我们请到了 PingCAP CTO 黄东旭来谈一谈他对于数据库行业的技术和行业演进的理解,以及商业公司究竟需要什么样的数据库。分布式数据库、开源数据库的蓝海机遇在哪?颖奇:PingCAP做的事情,我认为在中国工业领域上具有很大意义。因为几乎没有其他公司做过,你们是怎么想到做这件事的?黄东旭:中国过去也不是没有做数据库的公司,我们和他们不太一样在于,一是我们是类似于互联网公司,或者说创业公司的路径,是走融资发展的;二是技术上,我们公司是基于分布式数据库的理论成立的。过去三四十年,数据库市场都是依赖像 Oracle、IBM 所建立的理论基础运行。但在 21 世纪,Google 提出分布式系统技术后,随着硬件条件的成熟,像 SSD、万兆的网卡,带来的改变就是处理的数据量在持续地变大。数据库市场到了需要去做修订或者说要有个转折的地方了。数据库行业最根基的东西在发生变化,而这一块还没人做,所以说一定要找到正确的切入点。颖奇:你们找到的切入点是什么?黄东旭:就是分布式理论怎么跟传统关系数据库理论融合的点。最近这些硬件的革新,使得原来很多的假设都不成立了。比如过去大家可能觉得数据库的瓶颈是磁盘,想怎么设计一个更好的 B-Tree 能够让磁盘磁头转得少一点。但现在全是 SSD,甚至未来可能持久化内存的东西都出现了。过去分布式系统的网络这么慢,带宽这么小,所以尽可能都是在单机或者本地上去做。但现在基本上单机访问远程数据库和访问本地数据库在吞吐量上表现差不多了。还有就是选择「开源」。中国传统软件数据库的技术软件商业模式,跟传统的软件很像,就是做一个产品,招一堆销售挨家敲门。我们觉得这样效率太低。就现在而言,基础软件好不好关键是在于怎么在最短的时间找到最多人来去用这个产品,能够让它变得更好,变成一个正向循环。但传统软件招销售并不是一个特别好的选择,因为扩张速度取决于销售敲门的速度。颖奇:靠销售肯定来不及。黄东旭:所以我们喜欢「开源」。「开源」相当于用一些 to C 的方法论,在工程师的社区里通过病毒式传播让产品 adoption,别人用得不爽一定会 feedback 提 issue。用的人越多,它的质量就越好,质量越好,会变成一传十,十传百的这种效应,让产品正向循环下去。对于基础软件,我的观点是像数据库、操作系统、云技术,或者云内部的基础软件,未来只有开源一条路,如果不开源,或者说内核不开源的话,产品的生命力是很差的。不像其他的商业软件,基础软件就像在水管、水电煤这样的基础设施的层面上,你不开源的话别人也不敢用。颖奇:我们看到在中国实际上有两件事情之前没怎么做好。第一是特别基础的软件,第二是做一个特别好的开源公司,你们算是把两种结合起来的「鼻祖」。请问你们具体是怎么做的呢?黄东旭:我觉得有一点是因为 PingCAP 或者 TiDB 选的这个坑特别好。过去大家都知道 MySQL 数量大了以后只能 sharding,现在 TiDB 就是解决这个坑。大家都非常清楚这是个痛点,你不用去跟别人解释这就是一个非常厉害的内核代码。有需求有痛点,然后问题足够清晰,也足够大。颖奇:那你觉得开源这个事情会把PingCAP带到一个什么样的位置上?黄东旭:从数据库的角度上来看,大家会发现,最早的关系数据库 SQL、TSQL,在互联网或者移动互联网开始爆发的时候,数量开始膨胀,单机系统怎么样都搞不定的时候,互联网公司没有办法,只能去做了一套 NoSQL,但 NoSQL 又有点过了,就把原来的传统管理模型全都扔掉,但至少能把数据存下来。所以我觉得历史是螺旋式发展。其实这两年已经开始有这个趋势,就是新一代的数据库又开始回归 SQL 模型,可能未来持续十年会有一个关系型数据库的复兴吧。过去是因为分布式理论,以及硬件环境没有办法去跟这个模型很好地结合在一起。但至少以我们的经验来说,现在分布式基本上能满足很多需求。颖奇:所以传统数据库公司是在单机上解决这种数据的问题?黄东旭:对,我觉得未来数据一定是更大的状态,单机肯定是有问题的。硬件成本持续在下降,一定会到达一个临界点,就是数据本身的价值都比硬件成本要高,这样一来,我肯定是保护数据,怎么样把我的数据能无限存下来,并且能快速通过好用的接口来访问它。我觉得这个市场会很大,所以我从来都不跟别人说这个事情的天花板在哪里,因为我自己也不知道。颖奇:早期还是在数据价值比较大的行业里来应用会更好一些?黄东旭:我们早期策略上分两块,一块就是互联网公司,workload 数量很大,然后有很强的研发团队,开源社区的主力就是这帮人,随便用,而且我会很鼓励你们投人投精力去用它。还有一部分是一些高净值客户,比如银行,业务已经倒逼他们要去用一些互联网的技术去解决问题。比如说即使 Oracle 用得不好,迁到 TiDB 上其实也是很平滑的过程,同时可以保证多数据中心高可用、强一致等这些特性,用起来很省心。我觉得我们就是拿互联网最先进的技术给到传统公司,给他们赋能,而且让对方的迁移成本降得很低。「商业公司」如何管理「开源社区」颖奇:可以跟大家讲一下PingCAP对人才的要求和你们的管理方法吗?黄东旭:我一直信奉一句话,「Hire for attitude, train for skill」。首先你要打心底里认可这个事情,是一切往后谈的基础。这对我们来说不难,很多工程师他们还是有共同理想的。第二点就是研发人才的 skill set,我可能会更倾向于是在互联网,或者说在做这种大规模分布式系统。互联网人有个优势在于他们对新技术的接受度特别高,思想特别开放,没有一些条条框框的东西。第三点就是特别喜欢年轻人,我们会刻意地让团队里面有一些非常新鲜的血液。第四点的话我们并不强求,就是人的责任心和主人公意识,这其实跟我们的晋升体系有关。我们的晋升体系跟 Facebook 很像,团队在实际工作的时候,让员工的特点会慢慢浮现出来。比如说小明,每件事情交给他都特别靠谱。大家都公认觉得他是个靠谱的人,慢慢形成这样的效果。对于小公司来说,没办法把每个人每天的工作,每个任务都亲自去帮你规划好。所以我们的管理风格还算是比较粗放吧。颖奇:你们公司现在是有一些外籍工程师?黄东旭:对,我们也有一些外籍人士,大概七八个人吧。我们比较国际化。因为我们这个项目是开源的,用户用出问题了一般会去上面提一个 issue,很多国内用户直接用中文写 issue 上去,我们还有一个团队专门把中文 issue 翻译成英文,因为这个东西要同步嘛,在别人遇到同样问题去搜索的时候也能看到。颖奇:你们的TiDB或者TiKV里,我看到有几百个contributors,那里面有多少是外籍的?黄东旭:一半。包括我们的文档都是中英文一对一的比例。我觉得在哪做这个事情,这个问题已经不重要了。包括现在我们很多人才,在加入之前就已经是项目的粉丝,有些人甚至都不用面试,都不用看 GitHub,因为这个人天天就在 commit code。我们在国内的招聘方式也是挺特殊的,我们不太关心你到底在哪个城市工作。我们重度依赖像 Google Docs、Slack、GitHub、Jira、Confluence 这种生产力工具,基本上能够摆脱面对面的会议,这个是很重要的。我们不鼓励开长会,如果要开会,就开半个小时、15 分钟的短会。远程有个好处就是它会迫使工程师把所有想做的东西进行文档化,任何东西都可以被检索。我觉得这样更符合现代化的管理模式,有充足的时间,更加灵活地安排自己的生活,是一个更好的工作方式。颖奇:开源社区可能有一套管理模式,商业公司也有自己的管理模式,现在你们在这两边的管理模式是一样的还是说会有一些区别?黄东旭:我们是一样的。你可以认为我们自己的员工跟社区小伙伴的区别,就 TiDB 内核部分的开源来说,唯一区别就是我们给他们工资。颖奇:你觉得未来中国会有很多这样的工作出现吗?黄东旭:我觉得在技术软件行业会越来越多。颖奇:早期美国的很多开源软件没有太多资本介入,所以发展周期会很长。你觉得资本介入会使得开源软件发展周期变短吗?黄东旭:没有资本介入,或者说没有商业公司在后面支持的话,开源软件都不会有太强的生命力。开源我认为是分成两个阶段,一个是 1.0,一个是 2.0。1.0 是当年像 Glue、 GCC、Linux 内核这些项目;2.0 是就最近的这几年像 Eclipse、MongoDB、Databricks 这些开源软件公司,这些模式其实是更先进的,或者更加符合现在时代的做法。中国其实过去没有这样的东西,我们算是第一波。颖奇:早期的开源公司商业化诉求没那么快,所以贡献者相对平等,也没有经济回报。现在您这边的项目里有两种方式,可能一百个工程师是拿回报的,另外一百个可能是不拿回报的。那现在一个项目里混杂了两种组合方式,你们的解决方案是什么?黄东旭:我觉得其实这个问题的本质是:为什么要来(社区)。两种情况,一种就是我实际就在用这个东西,发现这个东西不好,某些地方有 bug 或者说某些地方的功能不是我想要的,我想要去改进它。大多数机构都是出于这种思路来贡献的。第二种人就是纯粹为了做出成就感。觉得这事情很不错,我能参与到这个项目来了,「I want to help」,我想去帮助别人,同时我能够得到证明,我是这个项目的 heavy contributor、committer,得到尊敬或者认同感。对每一个 contributor,哪怕提交一行代码或者修改一个文档,我们都会给他一个大礼包,包括贴纸、杯子等等周边产品。如果贡献比较多的话,我会亲手给你写一封明信片表达感谢,包括我们每年办的这些大会,只要是 contributor 都是免费的。颖奇:我觉得这个挺棒的。再问最后一个问题,你可以推荐几本书,给已经是CTO或准备想当CTO的人学习和借鉴。黄东旭:我有几本书是很喜欢的,《Unix 编程艺术》是到目前来说对我影响最大的跟编程和计算机相关的书。更技术一点的是《Unix 环境高级编程 (APUE) 》。很多人想学编程可能看这本书够了,其他什么书都不用买,就这个。还有《大教堂与集市》,这个介绍 open source 的原始出发点。然后我最近在读《毛选》,还有王小波的小说。颖奇:《Unix编程艺术》这本我也会推荐给年轻人看。这本书对我的影响非常大,读完使得我对整个计算机的软件体系结构有了非常深刻的认识。第一次读是在13年前了,至今对我的工作和创业都有很大的帮助。非常感谢东旭今天的分享。本文作者:王颖奇,联系方式:wangyingqi@gmail.com ...

February 21, 2019 · 1 min · jiezi

记录一次过程(1):Building Mosquitto from the git repository

MosquittoMosquittto是针对MQTT 3.1版本和3.1.1版本的一个开源实现的服务器。它包含C和C++的客户端库,以及用于publish/subscribe的实用程序:mosquitto_pub/mosquitto_sub。Mosquitto项目对于如何Building from source描述并不足够清晰,但其实步骤也还算简单。步骤1.cmake使用命令cmake -DWITH_TLS_PSK=OFF -DWITH_TLS=OFF得到– Configuring done– Generating done这两行中间有warning,由于我只是需要搭建一个简单的环境做简单地测试,就没有管warning。2.make使用命令make得到[100%] Linking C executable mosquitto[100%] Built target mosquitto3.sudo make install使用命令sudo make install报错。报错信息如下:Install the project…– Install configuration: “”– Up-to-date: /usr/local/etc/mosquitto/mosquitto.conf– Up-to-date: /usr/local/etc/mosquitto/aclfile.example– Up-to-date: /usr/local/etc/mosquitto/pskfile.example– Up-to-date: /usr/local/etc/mosquitto/pwfile.example– Up-to-date: /usr/local/lib/pkgconfig/libmosquitto.pc– Up-to-date: /usr/local/lib/pkgconfig/libmosquittopp.pc– Installing: /usr/local/lib/libmosquitto.1.5.5.dylib– Up-to-date: /usr/local/lib/libmosquitto.1.dylib– Up-to-date: /usr/local/lib/libmosquitto.dylib– Up-to-date: /usr/local/include/mosquitto.h– Installing: /usr/local/lib/libmosquittopp.1.5.5.dylib– Up-to-date: /usr/local/lib/libmosquittopp.1.dylib– Up-to-date: /usr/local/lib/libmosquittopp.dylib– Up-to-date: /usr/local/include/mosquittopp.h– Installing: /usr/local/bin/mosquitto_pub– Installing: /usr/local/bin/mosquitto_sub– Installing: /usr/local/sbin/mosquitto– Up-to-date: /usr/local/include/mosquitto_broker.h– Up-to-date: /usr/local/include/mosquitto_plugin.hCMake Error at man/cmake_install.cmake:36 (file): file INSTALL cannot find “/Users/xxxx/Desktop/iMac-mosquitto/mosquitto-master/man/mosquitto_passwd.1”.Call Stack (most recent call first): cmake_install.cmake:57 (include)make: * [install] Error 1报错之后首先检查报错信息,google之后仍然有解决方面的困难。这时我们注意到上面加粗的三行,切换到安装目录 /usr/local/include/ 后运行命令 mosquitto发现可以运行,但是在安装目录外就不可以运行。这时候我们的下一步就是配置环境变量,从而使mosquitto的运行不受当前目录的限制。4.添加环境变量环境变量的作用是:可以在操作系统的各个目录下,都能访问到需要的工具目录内的内容。我参考的是Mac OS X 系统的环境变量配置分别将/usr/local/bin/以及/usr/local/sbin/加入环境变量之后(我将路径加入了用户级的~/.bash_profile),就可以运行mosquitto了。但是还有一个烦人的小问题,就是Mac每次都要执行source /.bash_profile,配置的环境变量才生效。解决方法是:在/.zshrc文件最后,增加一行: source ~/.bash_profile5.运行测试先开一个terminal,输入命令mosquitto。打开第二个terminal,输入命令mosquitto_sub -h localhost -t test。打开第三个terminal,输入命令mosquitto_pub -h localhost -t test -m “hello world”。发现在第二个terminal上出现了hello world字符串,即成功。6.思考几个问题,后续解决。直接用cmake .是会由于OpenSSL的路径问题报错的,OpenSSL是干什么用的?我没有去解决OpenSSL的路径问题,而是忽略了它,关闭了TLS直接cmake的。TLS又是什么?起到了什么作用?程序运行起来经过了哪些步骤?一个大型项目是如何安装运行起来的?为什么安装mosquitto的步骤是cmake->make->sudo make install? ...

February 11, 2019 · 1 min · jiezi

2.进程

进程管理进程的基本概念进程与程序的区别进程控制进程同步进程通信线程进程的基本概念程序在并发环境中的执行过程资源分配和独立运行的基本单位程序的顺序执行一个有4条语句的程序段:S1:a:=x+2;S2: b:=y+4;S3: c:=a+b;S4: d:=c+b;程序顺序执行的特征顺序性封闭性可再现性顺序性处理机的操作严格按照程序所规定的顺序执行,即每一个操作必须在下一个操作之前结束。封闭性程序在封闭的环境下执行,结果不受外界因素的影响。可再现性只要环境和初始条件相同,程序重复执行时总得到相同结果。程序的并发执行一个有4条语句的程序段:S1:a:=x+2;S2: b:=y+4;S3: c:=a+b;S4: d:=c+b;S1和S2可以同时执行-》S3-》S4程序并发执行的特征间断性 共享、合作、制约导致,执行->暂停->执行失去封闭性 资源状态由多程序改变不可再现性 相同环境和初始条件, 重复执行,结果不同程序AL1: N:=N+1goto L1程序BL2: PRINT (N) N:=0goto L2设共享变量N初始值为5,则会产生3种执行结果:6,6,05,0,15,6,0进程的特征结构特征动态性并发性独立性异步性进程的结构功能描述进程控制块(PCB)动态特征的集中反映程序段描述要完成的功能数据段操作对象及工作区动态性进程最基本的特征是动态性进程的生命周期:进程由创建产生,由调度而执行,由撤销而消亡的过程。并发性多个进程同在内存中,且能在一段时间内同时运行。独立性进程是一个能独立运行、独立分配资源、独立接受调度的基本单位异步性进程按各自独立的、不可预知的速度向前推进进程的定义进程是进程实体的运行过程,是系统进行资源分配和调度的基本单位。进程和程序的关系(1)进程是一个动态概念,程序是一个静态概念(2)进程具有并行特征,程序没有(3)进程是竞争资源的基本单位(4)一个程序对应多个进程,一个进程为多个程序服务。进程的三种基本状态就绪状态运行状态阻塞状态就绪状态进程已经分配了除处理机以外的所有必要资源,只要再获得处理机就能执行的状态这样的进程可以有多个,通常排成一个队列,称就绪队列。执行状态已经获得CPU,正在运行在单处理机系统中,只有一个进程处于执行状态。多处理机系统则有多个处于执行状态。阻塞状态正在执行的进程由于发生了某事件而暂时无法继续执行时,放弃处理机而进入的状态,又称等待状态引起阻塞的事件:请求I/O,申请缓存。挂起状态引入原因(1)终端用户请求(2)父进程请求(3)负荷调节需要(一般在实时操作系统中使用)(4)操作系统的需要挂起引起的状态转换静止状态(挂起状态)活动状态(非挂起状态)引入挂起概念后,原先的进程的三种状态就变成了5种: (1)执行(2)活动就绪(3)静止就绪(4)活动阻塞(5)静止阻塞进程控制块Process Control BlockPCB是OS中最重要的记录型结构OS用PCB对并发进程进行管理和控制PCB是进程存在的唯一标志PCB常驻内存PCB专门开辟PCB区将所有的PCB组织成若干个链表或队列结构体(structure)for example:一个学生的自然信息(姓名,性别,年龄,生日……)PCB中的信息(1)进程标识符(2)处理机状态(3)进程调度信息(4)进程的控制信息进程标识符(1)内部标识符进程唯一的数字编号,给OS使用(2)外部标识符由字母、数字组成,给用户使用处理机状态处理机中的主要寄存器(1)通用寄存器8~32个,暂存信息用(2)指令计数器 要访问的下一条指令的地址(3)程序状态字PSW 条件码、执行方式、中断屏蔽标志(4)用户栈指针 用户进程拥有的系统栈,存放过程和系统调用参数及调用地址。进程调度信息进程状态进程优先级与调度算法有关信息事件 如:阻塞原因进程控制信息程序和数据地址进程同步和通信机制资源清单:除CPU之外的所需资源与已经分配资源清单链接指针:本进程PCB所在队列的下一个地址PCB的组织方式(1)链接方式把统一状态的PCB,用其中的链接字链接成一个队列。如,就绪队列、阻塞队列(根据不同阻塞原因)、空白队列。(2)索引方式建立就绪索引表、阻塞索引表等。把索引表在内存的首地址放在内存的专用单元中。链接方式索引方式

January 31, 2019 · 1 min · jiezi

如何通过Geth、Node.js和UNIX/PHP访问以太坊节点

本文旨在说明通过Geth、Node.js如何访问以太坊节点和UNIX下PHP如何访问以太坊节点。说明如何通过RPC使用此(A)以太坊节点对于以太坊主网络使用RPC url:http://85.214.51.53:8545对于Ropsten测试网络使用RPC url:http://85.214.51.53:8546通过本地系统上的“geth”访问节点:1.确保你的本地IP已在你的用户配置文件中注册。使用RPC服务时,不会阻止从此IP访问。2.在本地系统上安装geth二进制文件约30MB,geth二进制文件包。3.查找geth目录位置4.使用命令./geth attach rpc:http://85.214.51.53:8545连接并启动JavaScript环境,参考文档。5.控制台正在启动,你会看到>作为输入提示符。6.写eth.getBlock(10000)并获取块信息作为结果,参考文档。你的系统在几分钟内运行,无需安装已经500GB以上的以太坊区块链!故障排除:安装正确的geth二进制文件。验证geth在本地系统上是否可用。检查用户配置文件中的IP。确认没有个人防火墙阻止你的发送出去请求。尝试Ropsten测试网络:http://85.214.51.53:8545适用于主网络。http://85.214.51.53:8546适用于Ropsten测试网络。通过本地系统或服务器上的node.js访问节点1.这将返回一个webserver响应并输出一个html文件。2.在node.js系统中通过NPM或其他方式安装web3。3.将服务器文件指向app.js。这将为你带来一个帐户余额(钱包)的输出。文件:app.jsconst http = require(‘http’);const walletAddress = ‘0xDED5f23C157aCef931946D9A695cAc3eF1AaaA8D’;var Web3 = require(‘web3’);var web3 = new Web3();web3.setProvider(new web3.providers.HttpProvider(‘http://85.214.51.53:8545’));var balance = web3.eth.getBalance(‘0xDED5f23C157aCef931946D9A695cAc3eF1AaaA8D’);http.createServer(function(request, response) { response.writeHead(200, {‘Content-Type’: ’text/html’}); response.end("<!DOCTYPE html>\n" + “<html lang="en">\n” + “<head>\n” + " <meta charset="UTF-8">\n" + " <title>ethernode.biz</title>\n" + “</head>\n” + “<body>\n” + “<p>ethernode.biz</p>” + “<center>\n” + “</center>\n " + “<p> Ethereum balance : " + balance +"</p>\n” + “</body>\n” + “</html>\n”);}).listen(process.env.PORT);在Unix系统上通过PHP访问节点1.确保你的geth通过RPC正常工作。2.在geth_rpc_getblock.js下的Unix系统上保存以下shell脚本。确保你具有执行它的正确权限。3.在脚本中调整geth命令的路径。4.检查命令./geth_rpc_getblock.js是否会带来一些正确的输出。它应返回类似Data::QBIT=27867000000;WETH=0;ETH=0.002650772的内容。5.将下面保存在同一目录下的geth_access.phpPHP脚本。6.将$shellstring中的路径调整为脚本文件位置。7.php脚本应该回显脚本的输出。Data::QBIT=27867000000;WETH=0;ETH=0.002650772。你说对了!请记住,从长远来看,使用php shell_exec命令访问geth并不是很省事。文件:geth_rpc_getblock.js#!/bin/sh# ——————————————————————————# Qubitica.net# ——————————————————————————# Don’t define PARAM to use the standard IPC comms# Use below to connect to RPC portPARAM=“rpc:http://85.214.51.53:8545”/var/www/vhosts/ethernode.info/php/geth attach $PARAM << EOF | grep “Data:” | sed “s/Data: //“var erc20ABI = [{“constant”:true,“inputs”:[],“name”:“name”,“outputs”:[{“name”:””,“type”:“string”}],“payable”:false,“stateMutability”:“view”,“type”:“function”},{“constant”:false,“inputs”:[{“name”:"_spender”,“type”:“address”},{“name”:"_value",“type”:“uint256”}],“name”:“approve”,“outputs”:[{“name”:“success”,“type”:“bool”}],“payable”:false,“stateMutability”:“nonpayable”,“type”:“function”},{“constant”:true,“inputs”:[],“name”:“totalSupply”,“outputs”:[{“name”:"",“type”:“uint256”}],“payable”:false,“stateMutability”:“view”,“type”:“function”},{“constant”:false,“inputs”:[{“name”:"_from",“type”:“address”},{“name”:"_to",“type”:“address”},{“name”:"_value",“type”:“uint256”}],“name”:“transferFrom”,“outputs”:[{“name”:“success”,“type”:“bool”}],“payable”:false,“stateMutability”:“nonpayable”,“type”:“function”},{“constant”:true,“inputs”:[],“name”:“decimals”,“outputs”:[{“name”:"",“type”:“uint8”}],“payable”:false,“stateMutability”:“view”,“type”:“function”},{“constant”:false,“inputs”:[{“name”:"_value",“type”:“uint256”}],“name”:“burn”,“outputs”:[{“name”:“success”,“type”:“bool”}],“payable”:false,“stateMutability”:“nonpayable”,“type”:“function”},{“constant”:true,“inputs”:[{“name”:"",“type”:“address”}],“name”:“balanceOf”,“outputs”:[{“name”:"",“type”:“uint256”}],“payable”:false,“stateMutability”:“view”,“type”:“function”},{“constant”:false,“inputs”:[{“name”:"_from",“type”:“address”},{“name”:"_value",“type”:“uint256”}],“name”:“burnFrom”,“outputs”:[{“name”:“success”,“type”:“bool”}],“payable”:false,“stateMutability”:“nonpayable”,“type”:“function”},{“constant”:true,“inputs”:[],“name”:“symbol”,“outputs”:[{“name”:"",“type”:“string”}],“payable”:false,“stateMutability”:“view”,“type”:“function”},{“constant”:false,“inputs”:[{“name”:"_to",“type”:“address”},{“name”:"_value",“type”:“uint256”}],“name”:“transfer”,“outputs”:[],“payable”:false,“stateMutability”:“nonpayable”,“type”:“function”},{“constant”:false,“inputs”:[{“name”:"_spender",“type”:“address”},{“name”:"_value",“type”:“uint256”},{“name”:"_extraData",“type”:“bytes”}],“name”:“approveAndCall”,“outputs”:[{“name”:“success”,“type”:“bool”}],“payable”:false,“stateMutability”:“nonpayable”,“type”:“function”},{“constant”:true,“inputs”:[{“name”:"",“type”:“address”},{“name”:"",“type”:“address”}],“name”:“allowance”,“outputs”:[{“name”:"",“type”:“uint256”}],“payable”:false,“stateMutability”:“view”,“type”:“function”},{“inputs”:[],“payable”:false,“stateMutability”:“nonpayable”,“type”:“constructor”},{“anonymous”:false,“inputs”:[{“indexed”:true,“name”:“from”,“type”:“address”},{“indexed”:true,“name”:“to”,“type”:“address”},{“indexed”:false,“name”:“value”,“type”:“uint256”}],“name”:“Transfer”,“type”:“event”},{“anonymous”:false,“inputs”:[{“indexed”:true,“name”:“from”,“type”:“address”},{“indexed”:false,“name”:“value”,“type”:“uint256”}],“name”:“Burn”,“type”:“event”}];//var QBITWalletAddress = “$1”; You may pass a parameter from the php call into this $1.var QBITContractAddress1 = “0xCb5ea3c190d8f82DEADF7ce5Af855dDbf33e3962”;var QBITContractAddress2 = “0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2”;var QBITWalletAddress = “0x842286ea00502f8e5b1ea40d17ebc4b70becda08”;var QBITContract1= web3.eth.contract(erc20ABI).at(QBITContractAddress1);var QBITContract2= web3.eth.contract(erc20ABI).at(QBITContractAddress2);var acctBal = web3.fromWei(eth.getBalance(QBITWalletAddress), “ether”);totalBal += parseFloat(acctBal);var QBITbalanceOf = QBITContract1.balanceOf(QBITWalletAddress);var WETHbalanceOf = QBITContract2.balanceOf(QBITWalletAddress);console.log(“Data:"+":QBIT="+ QBITbalanceOf +";WETH="+ WETHbalanceOf +";ETH="+ acctBal);exit;<<<<< New FilePHP脚本:geth_access.php<?php$shellstring= “./geth_rpc_getblock.js”;$output=shell_exec($shellstring);echo “$output”;?>故障排除shell脚本对Windows换行符很敏感或返回\n\lf检查权限======================================================================分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。汇智网原创翻译,转载请标明出处。这里是原文如何通过Geth、Node.js和UNIX/PHP访问以太坊节点 ...

January 7, 2019 · 1 min · jiezi

从0开始学架构

理解架构历史背景设计背景复杂度来源一复杂度来源二复杂度来源三复杂度来源四

December 27, 2018 · 1 min · jiezi

vi简史

历史的道路不是涅瓦大街上的人行道,它完全是在田野中前进的,有时穿过尘埃,有时穿过泥泞,有时横渡沼泽,有时行经丛林。—- 车尔尼雪夫斯基当我们每天打开电脑,使用vi的时候,一切显得是那么顺理成章,觉得vi这个编辑器从古老的Unix走来,似乎理所应当地成为我们系统中的默认编辑器,却不知道它曾经经历了怎样的曲折甚至是九死一生。我们用它,我们恨它,最终我们又离不了它,这就是vi。混沌初开1964年,一个21岁的年轻人Butler Lampson从哈佛大学文学院毕业,来到加州大学伯克利分校读博,在这里,他遇到了另一个天才少年,18岁的Peter Deutsch在这里读本科,他们的任务是共同为一台SDS-940电脑编写一个分时操作系统:在当时,绝大部分计算机使用的都是批处理方式运行指令,一个用户的使用是独占式的,在他的程序运行期间不会被别的程序打断。而Butler Lampson他们编写的操作系统是第一款通用型的分时操作系统。因此他们需要编写一个内核和一个命令行界面,需要可以能够编辑文本,所以他们开发了一个小程序叫做QED,它的名称的来源是Quick Editor(快速编辑器)。除此之外,Butler Lampson的贡献还包括后来在施乐公司期间领导开发了Alto,这个操作系统就是日后激发乔布斯灵感并从施乐偷师学艺的那一款操作系统。并且Butler本人在1992年获得了计算机学界最高奖图灵奖。这时候,加州大学伯克利分校的另一个天才少年Ken Thompson(这个名字日后将如雷贯耳,因为是他发明了Unix),刚刚获得了电子工程学士学位,一年后,获得了计算机科学硕士学位,并拿到了贝尔实验室的Offer。在贝尔实验室,Ken的工作之一是把他母校的QED移植到另一个比较大型的分时操作系统CTSS上,只不过这个CTSS是另一个学校的产物——麻省理工学院。在移植的过程中,Ken加入了他当时正在研究的,也是他最喜欢的Regular Expression(正则表达式)。在此过程中,Ken对QED变得非常熟悉。Ken最终在1969年发明了Unix,而Unix系统中一个重要组件是ed,这个ed的很多功能直接来源于Ken的母校加州大学伯克利分校的QED。由ed而又衍生出来了一系列著名的Unix命令,例如grep和sed。grep这个名词的来源其实是g/re/p,第一个字母g代表global(全局检索),re代表regular express(正则表达式),而p表示print(显示)。sed里面则加入了很多ed里没有实现的script(脚本)功能。至此,ed已经成为Unix操作系统的标配。我们来看一下一个标准的ed的编辑界面(下文标黑的粗体字是屏幕显示的内容,其余是用户输入的命令):aed is the standard Unix text editor.This is line number two..2i.,led is the standard Unix text editor.$$This is line number two.$3s/two/three/,led is the standard Unix text editor.$$This is line number three.$w text65q是不是已经看到了一些vi的影子了呢?只是这时的ed还只是一个行编辑器,远远不是后来vi的样子。脱胎换骨在Ken发明Unix的6年之后,1975年,他回到母校伯克利分校,这一次,他的使命是在伯克利分校的电脑系统上安装他自己发明的Unix,而这一套Unix日后将成为Unix界极富盛名的BSD(Berkeley Software Distribution,伯克利软件套装)。也就是这一年的夏天,Ken在伯克利分校遇到了我们故事的主人公Bill Joy,那一年,Bill是21岁,正在伯克利分校读研。Bill后来回忆说:Ken Thompson来到伯克利并且带来了一台坏掉的Pascal系统,而我们准备在那个暑期修好它。当我们对它进行修理时,发现我们正在使用的名为ed的编辑器完全无法使用了。由于Unix系统的广为流行,远在伦敦玛丽王后大学担任讲师的George Coulouris也不得不使用ed,但他得出的结论是:ed的难用程度达到了神级,根本就不是给人用的。所以他开始着手改进ed,并把改进之后的软件版本起名为em(editor for mortal给人类使用的编辑器)。1976年夏天,George访问伯克利分校,他带着一卷磁带,里面包含了他的em代码,并演示给别人看。其他人对此不感兴趣,而Bill Joy对此很受启发,他要来了em的源码,并在此基础上不断做改进,起名为en,然后又在en的基础上不断改进,一直改进到了ex(中间是否还有eo, ep, eq, …已经不得而知)。1977年10月,Bill Joy在ex的基础上,增加了全屏幕显示的功能,并将此功能命名为ex的可视化模式(visual mode),别名——vi。因为Bill Joy在开发vi的时候用的是一台ADM-3A电脑:而这台电脑的键盘排布方式是这样的:这个键盘上并没有上下左右方向键,而上下左右键是印在了HJKL这四个字母上,通过按下Ctrl+HJKL来实现上下左右移动,所以vi里的上下左右是通过HJKL来实现的,和游戏玩家里热爱的WASD是如此不同,以至于很多人认为这是一种反人类的设计。但你们要知道,WASD是很多很多年之后才被大多数人接受的设置。在当时的各款主流电脑上,方向键要么没有,要么也是一字排开。例如苹果的Apple II系统:同时还应该注意到,ADM-3A电脑键盘上Esc键的位置有多么特殊,就在Q键的左侧,正好是我们目前Tab键的位置,简直是触手可及,所以vi用它来做模式切换键是非常自然,而不像现在的Esc键离我们的手那么远,要把小指伸出去很远才能够得到。还有一个细节是在ADM-3A键盘上,除了上下左右四个键外,还有一个Home键,它也可以通过按下Ctrl来实现回到行头的效果,而更关键的是这个键同时也是键,这也就是为什么Unix系统里会用来代表home目录的原因。黯淡时光vi的第一个正式版本是在1978年3月随着BSD 1.0同时发布的,这注定了它以后将走过一段不平凡的岁月。Bill Joy继续对vi进行升级,中间经过无数次叠代,在1979年6月发表了vi的2.7版本后,退出主要开发者行列,但仍持续贡献到1980年8月的3.5版本,从那以后彻底淡出。在谈到他为什么要退出vi开发者行列时,他说:我希望我们没有用尽键盘上的每一个键。我觉得vi一个最有趣的特点是它是一款基于模式的编辑器。作为一款基于模式的编辑器,vi做的非常棒。EMACS的优点之一是它是一款无模式的编辑器。但我从来没有想过要把vi做成EMACS那样。我也不擅长于优化vi的代码。我觉得编辑器的重绘功能非常棘手。vi完成它目前的工作非常不错,但你总是在学习的过程中编写程序……所以我不再继续这样做了。实际上,我当时正在试图给vi加上多窗口编辑的功能,那是1978年的12月。我的磁带机坏了,而我没有任何备份。我的代码都丢失了,而我连文件目录都没有。我必须重写关于多窗口编辑功能的所有代码,我放弃了。我退回到上一版本,给代码增加了一些说明文档,完成了用户手册,然后就退出了。如果不是那一次事故的话,也许vi就会有多窗口编辑功能了,但,谁知道呢?vi的最根本问题是它没有鼠标,所以才有了各式各样的命令。但你不能用现在的眼光去看当时的软件。我觉得如果能加上多级回退这个功能也很不错。但无论如何,vi的内核实际上还是ed,你不可能脱离这个事实。这就有点像用一层层纸包裹起来的糖果,它没有一个统一的概念。我觉得如果可以回到过去,我不会回去重新再来一遍。1982年2月24日,3个斯坦福大学毕业的学生Vinod Khosla,Andy Bechtolsheim和Scott McNealy创办了Sun公司,他们挖来了伯克利分校毕业的Bill Joy,从而导致伯克利分校Unix BSD的vi被锁死在3.7版本上。其他各家商业公司,包括IBM,Sun,HP,DEC都能在Bill Joy开发的vi的代码基础之上做改进,但其他人却不可以了。因为AT&T开始了那场臭名昭著的官司,控告BSD侵犯了他们的知识产权,而vi是基于BSD里面的ed做开发的,也属于被禁止使用之列。关于这场官司,详细情况可以看阮一峰的文章《Unix版权史》。阮一峰在文章中评论道:AT&T与BSD之间的诉讼,是当代版权制度最恶劣的应用之一。为什么这么说?首先,起诉者其实与Unix毫无关系。这是AT&T经理层的决定,而不是开发者的决定。事实上,包括Ken Thompson在内的技术人员一直希望,公司能够公开源码。他们完全有理由这么要求,因为Unix从来不是AT&T的业务重点,最初是个人项目,后来也没有占用公司太多资源。销售Unix的利润,在公司全部业务中,几乎可以忽略不计。为了一点点钱,去打击一个使许多人受益的产品,何必这样做呢。其次,AT&T根本不关心Unix的发展。它真正关心的是金钱和削弱对手。1994年,官司还没有结束,它就把Unix卖给了Novell公司,从此不再与Unix发生关系,官司也因此不了了之。既然你不想要这个产品,为什么要提起诉讼呢?真是不可理解。最后,所谓的侵权几乎是不存在的。因为Novell从AT&T买下Unix版权后,检查了BSD的源码,在18000个组成文件中删除了3个,并对其他文件做了一些小修改,然后BSD就重新获得了自由发布源码的许可。这意味着,至多只有千分之一的BSD代码有版权问题,但是就因为这千分之一的问题,导致百分之百的产品被迫中断,完全不符合比例原则。所以,这场版权官司就是一家利益至上的公司,以微不足道的理由,为了一个自己根本不在乎的产品,悍然发动一场损人不利己的战争。BSD在法律纠纷中艰难前行,并分裂出了3个版本分支:FreeBSD, NetBSD和OpenBSD。而在此之前,乔布斯黯然离开苹果,开始自己的第二次创业的时候,开发的NexT操作系统,也是从BSD上拉的分支,最后还吸取了很多FreeBSD的成果,最后成就了今天的Mac OSX,以及你手机里使用的iOS。凤凰涅磐在这场旷日持久的官司当中,vi不能用了,但是vi的热爱者并不愿意切换到emacs上,直到1990年,Steve Kirkendall才发布了一个vi的克隆版,起名叫Elvis。1992年,Elvis被纳入BSD,1994年,Keith Bostic在Elvis基础上开发了nvi,一直沿用至今。花开两朵,各表一枝。1991年,芬兰大学生Linus Torvalds,他想学习Unix,但是买不起工作站,就自己写了一个能在386上运行的操作系统内核,并以自己的名字命名为:Linux。Linus Torvalds后来说:如果我早知道BSD没有法律问题,并且可以被移植到386,我会加入BSD的开发,而不会自己动手写一个。Linus写的Linux并不是一个完整的操作系统,它只是一个内核,在内核之外,还应该有像vi这样的编辑器。于是在2000年6月,Gunnar Ritter基于Bill Joy的vi源代码,把vi发布到了Linux操作系统和FreeBSD操作系统上(这时候的BSD由于法律诉讼的原因已经被拆分成了FreeBSD, NetBSD和OpenBSD三个分支)。一开始,这又是一个违法的举动,因为Ritter根本就没有获得AT&T的授权,但是随着2002年1月,对相关授权限制的逐渐解除,这个版本才正式成为一个合法的版本,也就是我们今天使用的Linux上的vi。然而,令人唏嘘的是,虽然现在vi已经可以用在BSD的直系后裔FreeBSD上了,但是FreeBSD已经有了自己的替代品nvi,不愿再使用vi。反倒是那些一开始没有vi的Unix版本,例如HP-UX,AIX等等,可以继续堂而皇之地使用vi。虽然如此,但是由于Linux的普及,以及Mac OSX这个BSD的变种的流行,vi依然成为了各大操作系统中事实上的标配。vi这个编辑器的王者称号当之无愧,并将随着开源软件的发展一直永远流传。最后,让我们记住vi的作者Bill Joy。是他,给我们带来了vi。 ...

October 7, 2018 · 1 min · jiezi