Go 语言特性:
Go 语言在语言级别支持[[Coroutine|协程]],叫 [[Goroutine]]。Go 语言标准库提供的所有系统调用 (syscall) 操作,当然也包括所有同步 IO 操作,都会出让 CPU 给其他 goroutine
Go 语言推荐采用“Erlang 风格的并发模型”的编程范式来实现进程间通信。
要求 public 变量以大写字母开头,private 变量以小写字母开头。
花括号写法,还有错误处理,都有详细的规定。Go 语言也是至今为止学习的语言中,唯一一个将编码风格写入语言要求的。
对于 Go 的变量,推荐使用 ` 驼峰式 `
Go 语言标识命名规则:
包名要求小写。
Go 语言反对重载,反对继承,反对虚函数和虚函数重载,Go 提供了继承但是使用组合文法提供。
Go 语言是静态类型语言。
一些值得提前了解的语言特性
Go 语言引入 goroutine 概念,关键字 go, 可以让函数以 goroutine 协程方式执行。Go 语言使用 channel 来实现通信顺序进程(CSP,Communicating Sequential Process)模型,方便跨 goroutine 通信。
从 这里 下载,然后解压并添加环境变量
tar -C /usr/local -xzf go1.18.3.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin
然后设置 GOPATH
环境变量
安装 C 相关工具
sudo apt-get install bison ed gawk gcc libc6-dev make
在 macOS 下安装:
brew install go
可以使用 go version
来验证是否安装成功。
在安装好的 Go 目录下,有几个重要的目录
/bin
,可执行文件,编译器,Go 语言相关工具/doc
,文档/lib
,文档模板/misc
,支持 Go 编辑器相关配置/os_arch
包含标准库包对象文件 .a
/src
,源代码/src/cmd
,Go 和 C 编译器和命令行脚本$GOROOT
表示该 go 的安装目录,值一般都是 /usr/local/
, 当然,也可以安装在别的地方$GOARCH
表示目标机器的处理器架构,它的值可以是 386、amd64 或 arm$GOOS
表示目标机器的操作系统,它的值可以是 arwin、freebsd、linux 或 windows$GOPATH
采用和 $GOROOT
一样的值,但从 Go 1.11 本开始,你必须修改为其它路径。它可以包含多个包含 Go 语言源码文件、包文件和可执行文件的路径,而这些路径下又必须分别包含三个规定的目录:src
、pkg
和 bin
, 这三个目录分别用于存放源码文件、包文件和可执行文件GOPATH 可以理解成工作目录,一般需要包括 3 个文件夹:
src
源文件,通过包名区分pkg
编译后的文件bin
可执行文件(go install),只需要将 $GOPATH/bin
加入环境变量就可以在操作系统任意位置执行创建一个 workspace,然后开始 hello world,在 workspace 下新建 src/hello
目录,在目录下创建文件 vim hello.go
package main
import "fmt"
func main() {
fmt.Printf("hello, world\n")
}
退出文件,在 hello 目录下执行 go build
,此时会生成一二可执行文件 hello,执行 ./hello
可以看到输出。
函数体定义
func 函数名(参数列表)(返回值列表) {
// 函数体
}
如果不进行编译,也可以直接 go run hello.go
来运行。
在 Go 语言中有四个关键字和定义类型相关,var
,const
,type
和 func
前两个和变量相关,第三个可以用来自定义类型,func
定义方法。
_
和其他强类型语言一样,Go 语言内置一些基础类型,比如 Strings,Numbers(int32,int64,float32,float64 等等),Booleans。这些类型本质上是原始类型。当对值进行增加或者删除市,会创建一个新值。当把这些值传递给方法时,会传递一个对应值的副本。
Go 语言中有下面几个引用类型:切片、映射、通道、接口和函数类型。当声明上述类型时,创建的变量被称为标头(header)值,每个引用类型创建的标头值是包含一个指向底层数据结构的指针。
header 中包含一个指针,通过复制来传递一个引用类型的值的副本。
结构类型用来描述一组数据值。
Go 语言有很多保留字
在 Go 语言中变量初始化和变量赋值是不同的概念。
常见的语法,比如:
var var2 = 10
var3 := 11
这里 :=
表示同时进行变量声明和初始化。出现在 :=
左侧的变量不应该是已经被声明过的。
*
, /
, %, ++, –逻辑运算符: &&, | , ! |
位运算符:&, | , ^, « , » , &^ |
赋值运算符:=, +=, -=, *=, %=, &=, | =, ^=, «=, »= |
<-
const PI = 3.14
我们对于一些事物的不理解或者畏惧,原因都在于这些事情所有意无意带有的绚丽外衣和神秘面纱。只要揭开这一层直达本质,就会发现一切其实都很简单。
在最开始了解到这个应用的时候,我无法简单地用一句话来形容这个应用,大部分人将它称为背单词软件,单词记忆应用,部分人有拿他作为知识管理应用,甚至有人拿他来学习乐谱,诗歌,但总之如果要用简单的话来描述这个软件,那么跨平台必定是关键词,另外一个关键词就是卡片,在另外一个就是循环记忆,那么至于卡片上承载什么样的内容,就完全由用户来决定了。
德国心理学家[[莱特纳]]在 1970 年出版了他一部重要的著作《How to learn to learn》,他在这本书中引用艾宾豪斯的遗忘曲线,发明了「莱特纳系统」,也就是「间隔式复习」的方法,让记忆达到最佳。
[[Anki]] 就是间隔式复习的一个实现方式。Anki 中通过模拟卡片的前后两面,通过内置的算法,间隔记忆卡片的内容,可以在卡片上写任何内容。
很长一段时间内我都无法很好的尝试使用 [[Anki]] 来进行记忆,烦恼我的一点理由就是 Anki 的卡片制作过程,我知道很多人都说学习记忆是在卡片制作过程中,但是我发现制作卡片花费的时间已经超过我使用纸张来记录的时间。所以很长一段时间内 Anki 就躺在我所有的设备上,虽然偶尔会打开一下,但是依然没有养成每天记忆的习惯,反而在其他背单词软件中坚持了下来。但是在使用线程的单词记忆软件的时候,我不时的会想起 Anki 来,也渐渐地发现线程的单词记忆软件有其自身的缺点,而这个缺点正是 Anki 可以弥补的(虽然可能需要花费一些时间来熟悉 Anki)。
比如使用通常的软件来背单词,优势在于这些软件可能事先已经准备好了单词集,发音,例句,讲解等等,然而在使用过程中就会发现这些东西始终是字面上的东西,即使记忆了和多遍,依然没有被录入到自己的脑袋里。反而有些时候,比如某一次到异国他乡遇到的一个单词,像烙印一样深深地印在脑子里,每一次想到这地方脑海里便会回忆起这个单词。丝毫没有可以去记忆,但潜意识中就已经将这个单词记忆下来了。所以这个时候我又想起了 Anki,对于想要记忆的东西,不妨用自己的语言描述放到 Anki 的背后,写一段故事也好,描述一个场景也好,自己写下来的东西,每次翻到的时候记忆总是要比别人准备好的东西要深刻。
另外一个使用 Anki 的误区便是,当你发现你在制作卡片时陷入了不间断的 Copy/Paste ,那么请立即停下来,就像 这里 说的那样,首先去理解你要记忆的东西,否则你会陷入无限的知识债务。这一点和做笔记的时候不停摘录而不去消化,买书屯书而不读是一样的,理解了才能真正成为你自己的东西。
end up accruing a lot of ‘knowledge debt’ that you’ll have to pay for down the line.
应该花费更多的时间来理解需要记忆的内容,而不是在制作卡片上。当对内容理解越深刻,那么以后 reviewing 或者 recalling 的时候花费的时间也会减少。
官方网站:
下载解压之后有 README,看其中说明,安装即可。
任何需要记忆的内容都可以使用 Anki 帮助进行,Anki 不感知内容,支持图像,音频,视频,甚至科学符号(LaTeX),比如你可以使用 Anki:
Anki 背后的理念:
官方文档已经非常细致,可以直接 阅读 ,这边只列举一些比较重要的内容。
apkg
文件卡片,Anki 的核心概念,正面问题,背面答案,或者正面单词,背面解释。
来自朗文的解释:a set of playing cards
,翻译为一组卡牌
朗文的解释:a short description that gives important details about a person, a group of people, or a place
,翻译为档案,介绍也都可以,在 Anki 的 File 菜单中,可以切换 Profile,不至于导入别人的卡牌之后弄乱自己的设置,或者自己在使用时也可以根据不同的场景定义不同的 Profile。
学习过程中,打开 Decks 可以看到一个 Overview,卡片的种类被分为三种类型:
进入到卡片学习,底部会有多个按钮,第一次学习的卡片会出现三个按钮:
再次学习一个卡片的时候,也就是 review 阶段时,有四个按钮
上面的按钮对应的快捷键是 1,2,3,4。
每一张卡片都会经历三个阶段:新卡片、学习中、结束。
官网那一定是最全的,包含各国语言
Add-ons
推荐几个(只适用于我目前使用的 2.1 版本,随着时间变化,下面的 id 可能失效):
[[AnkiConnect]]源码地址:https://github.com/FooSoft/anki-connect
这个插件将 Anki 的功能暴露一份 RESTful 接口,这样就可以用接口方式来操纵 Anki。安装开启该插件后会监听 8765,默认绑定 HTTP 服务到 127.0.0.1,只有本机可以访问该服务。如果想要其他网络访问,可以设置环境变量 ANKICONNECT_BIND_ADDRESS
为 0.0.0.0
。
可以从不同的来源将词添加到 Anki
2021 年更新
之前推荐的 Chrome to Anki 插件已经很久没有更新,所以又找到了 Saladict 这样一款插件,在设置中可以很方便地找到如何连接 Anki。
需要借助一款 Chrome 插件
和一个 Anki 插件
这两个插件都是开源 12 的,看官方的说明也很简单就略过了。
虽然目前一直在寻找方法能够间 GoldenDict 查词记录自动制作卡片到 Anki,但是目前尚未找到合适的方法,虽然有了解到可以使用 mdx-sever
共享一个 HTTP 服务,然后使用上面的方法自动制作,但感觉依然有些麻烦。Anki 上的卡片还是自己手动创建比较稳妥。
对于 Kindle 我很少将它连到电脑上做导出导入的事情,所以这个不准备弄了。
如果对于 Kindle 有重度依赖,并且希望使用 Anki 的方式来整理标注的话,可以试试 ankindle 这样一个插件,可以导出单词和标注,并且制作成 flashcard 用来记忆。
几个小小的 tips.
Add-ons
固然是非常有用,非常强大的,但是千万不要在上面花费过多的时间。在软件工程领域有句话,越早的优化可能带来灾难,get things done 要比优化重要的多。参考官方的 repo
需要注意的是目前这个 Anki Sync Server 只支持特定版本的客户端,需要到 GitHub 页面自己确认一下。
可以使用 这个 docker-compose :
version: "3"
services:
anki-sync-server:
container_name: anki-sync-server
image: kuklinistvan/anki-sync-server:latest
restart: always
ports:
- "27701:27701"
volumes:
- ./data:/app/data
sudo docker exec -it anki-sync-server /bin/sh
# help
/app/anki-sync-server/ankisyncctl.py --help
# add user
/app/anki-sync-server/ankisyncctl.py adduser username
input password
# list users
/app/anki-sync-server/ankisyncctl.py lsuser
# modify password
/app/anki-sync-server/ankisyncctl.py passwd username
菜单,工具,插件,安装插件 2124817646
:
http://1.2.3.4:27701
http://1.2.3.4:27701/msync/
在客户端,设置,高级设置,自定义同步服务器中设置。
ab 是针对 HTTP 服务进行性能压力测试的工具,它最初被设计用来测量 Apache 服务器的性能指标,主要用来测试 Apache 服务器每秒能够处理多少请求以及响应时间,但这个命令也可以用来测试通用的 HTTP 服务器性能,比如 Nginx,tomcat,resin 等等。
吞吐量是系统每秒钟处理的请求数量,可以通过 总请求数量 / 请求花费时间 来计算。
服务器平均请求等待时间指的是服务器平均处理一个请求花费的时间,公式是 总花费时间 / 请求数量,这个指标是吞吐量的倒数。(Time per request)
指的是某一时刻服务器同时接受的连接数。
sudo apt install apache2-utils
ab -c 10 -n 10000 -k -H "Accept-Encoding: gzip, deflate" http://localhost:8080/
解释
-c concurrency
并发数-n requests
一次测试的请求数量-k
表示 keep alive,保持连接-H headers
自定义 Header举例
ab -k -c 10 -n 100 https://www.einverne.info/
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking www.einverne.info (be patient).....done
Server Software: nginx
Server Hostname: www.einverne.info
Server Port: 443
SSL/TLS Protocol: TLSv1.2,ECDHE-RSA-AES128-GCM-SHA256,2048,128
Document Path: /
Document Length: 53802 bytes
Concurrency Level: 10
Time taken for tests: 1.125 seconds
Complete requests: 100
Failed requests: 0
Keep-Alive requests: 0
Total transferred: 5400681 bytes
HTML transferred: 5380200 bytes
Requests per second: 88.91 [#/sec] (mean)
Time per request: 112.470 [ms] (mean)
Time per request: 11.247 [ms] (mean, across all concurrent requests)
Transfer rate: 4689.35 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 5 48 35.3 44 163
Processing: 9 62 65.7 47 559
Waiting: 7 59 64.7 45 543
Total: 25 109 75.4 83 564
Percentage of the requests served within a certain time (ms)
50% 83
66% 111
75% 123
80% 128
90% 225
95% 275
98% 337
99% 564
100% 564 (longest request)
对于实际场景中经常需要用的登录问题,如果接口需要验证 Cookie ,那么使用 -C
写到 Cookie 内容
ab -n 100 -C key=value http://localhost
或者使用 -H
带 Cookie
自定义多个字段
ab -n 100 -H "Cookie: Key1=Value1; Key2=Value2" http://localhost
ab 只能测试简单的 RESTful 接口,只能应付简单的压测任务。如果需要更加专业的压测工具可以使用 jmeter。
这里的 Dash 可不是一加手机的快充技术,在使用 Youtube DL 的时候频繁的接触到 DASH 这个关键词,查了一下 DASH 是流媒体技术,全称是 Dynamic Adaptive Streaming over HTTP,自适应流媒体技术,通过 HTTP 服务传送流媒体,在 YouTube,Netflix,Hulu 等流媒体网站中被频繁应用,国内 Bilibili 也引入了该技术 1。
该技术的大致实现原理是在服务端将视频分片,每个分片都有自身的编码方式,甚至不同的分辨率,码率等等,而在客户端根据当前网速或者设备自行选择需要播放的分片,可以实现不同画质内容无缝切换。所以在 YouTube 切换画质时完全不会黑屏,更不会影响观看。更加具体的原理解释可以参考这里
另外几个值得一说的功能是
DASH 技术与编码器无关,可以使用 H.265, H.264, VP9 等等任何编码器进行编码。
DASH 音视频流标识文件被称为 Media Presentation Description,包含了一组结构化音频视频内容。
MP4Box 命令 可以对 MP4 文件进行合并,切割,提取等操作。更多可以参考官网
总而言之, MP4Box 命令可以实现如下:
MP4Box 可以用于将现成内容打包到 ISO 媒体文件,比如 MP4,3GP 等文件中。需要注意的是 MP4Box 命令并不会重新编码音频,视频,图片文件。将 DivX 文件转变为 MP4 文件:
MP4Box -add file.avi new_file.mp4
或者添加第二条音轨到上一条命令输出的文件
MP4Box -add audio2.mp3 new_file.mp4
MP4Box 可以从现存的容器中获取资源,可以使用 -info
来查看媒体资源
MP4Box -info file.avi
然后使用如下类似方法导入文件的音轨
MP4Box -add file.avi#audio new_file.mp4
MP4Box 可以用于准备各种协议的传输分发协议,主要是 HTTP 下载或者 RTP streaming。
To prepare a file for simple progressive HTTP download, the following instruction will interleave file data by chunks of 500 milliseconds in order to enable playback while downloading the file (HTTP FastStart):
MP4Box -inter 500 file.mp4
To prepare for RTP, the following instruction will create RTP hint tracks for the file. This enables classic streaming servers like DarwinStreamingServer or QuickTime Streaming Server to deliver the file through RTSP/RTP:
MP4Box -hint file.mp4
To prepare for adaptive streaming (MPEG-DASH), the following instruction will create the DASH manifest and associated files. For more information on DASH see this post:
MP4Box -dash 1000 file.mp4
查看 MP4Box dash 相关的帮助:
MP4Box -h dash
DASH Options:
-mpd m3u8 converts HLS manifest (local or remote http) to MPD
Note: not compatible with other DASH options (except -out and -tmp) and does not convert associated segments
-dash dur enables DASH-ing of the file(s) with a segment duration of DUR ms
Note: the duration of a fragment (subsegment) is set
using the -frag switch.
Note: for onDemand profile, sets duration of a subsegment
-dash-strict dur [DEPRECATED, will behave like -dash]
-dash-live[=F] dur generates a live DASH session using dur segment duration, optionally writing live context to F
MP4Box will run the live session until 'q' is pressed or a fatal error occurs.
-ddbg-live[=F] dur same as -dash-live without time regulation for debug purposes.
-frag time_in_ms Specifies a fragment duration of time_in_ms.
* Note: By default, this is the DASH duration
-out filename specifies output MPD file name.
-tmp dirname specifies directory for temporary file creation
* Note: Default temp dir is OS-dependent
-profile NAME specifies the target DASH profile: "onDemand",
"live", "main", "simple", "full",
"hbbtv1.5:live", "dashavc264:live", "dashavc264:onDemand"
* This will set default option values to ensure conformance to the desired profile
* Default profile is "full" in static mode, "live" in dynamic mode
-profile-ext STRING specifies a list of profile extensions, as used by DASH-IF and DVB.
The string will be colon-concatenated with the profile used
比如随便拿一个 mp4 文件:
MP4Box -dash 2000 -rap -profile dashavc264:onDemand input.mp4
解释:
-dash 2000
按照 1s 来切-rap
强制让分段从随机点开始-profile dashavc264:onDemand
可以查看 dash specifications 来查看更多 profile 相关的信息这个操作不会对视频文件进行重新编码,只是将视频进行切片,所以非常快。执行命令结束后会得到 .mpd
文件和 *_dashinit.mp4
两个额外的文件。生成的这两个文件放到 HTTP 服务器中就可以在支持 mdp 播放的播放器中播放。
https://www.bilibili.com/read/cv867888/ ↩
常看计算机相关图书的话对,Mastering XXX,XXX in Action 肯定不会陌生,不同系列的图书定位是有差别的,刚开始学习一种技术时,选择一本合适的书非常重要。所以这里就我个人的感受来说一下这几个系列的区别。
大部分 Mastering 系列图书都是 Packt Publishing 出版社出版的。Mastering 系列的图书是大而全的书籍,从介绍开始,到使用,再到具体的技术细节都有涉及。翻译为中文一般叫做“精通 XXX”,“深入理解 XXX”。
适合有一定基础的初学者阅读。
常见的有:
Cookbook 系列由 O’REILLY 出版社出版,这个系列会侧重于该语言,该工具的使用技巧和方法,会涵盖周边的工具库,算法等等,包含大量的编程技巧和示例代码。该系列的书比较实用,目录编排会通过实例来展示工具或者语言的实用,是一种实用主义的书。Cookbook 直译是食谱的意思,联想来就能够知道这个系列的书目的是为了让读者能做出一道菜来,通过组织不同的原材料(组织代码),最后获得一道美味的食物(达成的目标)。
该系列的书能够让读者认识到是什么,怎么用,最后能够做什么。其实从 cookbook 原本的意思中也能够感知到
a book that gives instructions on cooking and how to cook individual dishes
适合有一定编程能力的学习者参考。
常见的比如:
in Action
系列的图书也是比较著名的一个系列,一般翻译为 “XXX 实战”,该系列图书由 MANNING 出版社出版,国内一般由人民邮电出版社翻译。听这个名字就知道这是偏实战的一本书,通常情况下会在书中有一个贯穿全书的例子,比如用 Redis 的特性实现某个系统功能等等。
但总得来说也是一本入门级别的书籍,适合初学者和有一定经验的从业者。
常见:
适合初学者,我看过 《Learning Python》 这本,是我看过的所有的 Python 相关书籍中最详细的一本,每一个语言的细节,每一个用法的区别都是非常详细的。
Learning 系列的图书也是 O’Reilly 出版社的系列,这系列的图书比较初级,但是细节部分很详细,推荐初学者快速入门。
常见:
Head First 系列的图书看的不多,最出名的可能是那本《Head First 设计模式》了吧,但是 Head First 系列书我查了一下都比较老,这个系列可能是这里面最没有存在感的一个系列了。至于特色部分等我看一些之后回来补上。
补充 Head First 系列,之所以叫做 Head First 是这个系列的图书开创了一种学习模式,通过大量的配图,对话,营造一种比较好的理解方式,通过联想记忆,让读者能够长时间集中注意力然后达到学习的目的。
常见:
Thinking in 系列,一般翻译为 XXX 编程思想。该系列的图书主要是讲述一种编程思维,用该语言的思维来抽象现实问题。
该系列常见的:
Dive into 系列一般翻译为“深入 XXX”,也是比较全面的介绍性书籍,书籍的组织方式一般也是由浅入深。
常见;
既然已经写了这么多了,也不在乎多这一类的书籍,Primer 最熟悉的一本应该就是 C++ Primer 了,最开始还以为是一本 C++ 中高级的书,但其实是一本初级入门读本,从 Primer 单词的释义就能看出
a book that contains basic instructions
所以见到此类的书大可直接阅读。
对于新的一项技术,如果处于是什么都不太清楚的状态,推荐先找 Learning 系列的图书,如果没有可以找 Mastering 或者 Cookbook 系列的图书,先从直观上对该技术有一个总体的了解,是什么,有什么功能,能够做什么。然后具体对其中的细节进行学习。
在之前介绍 Appium 的时候就提到了一些 Selenium ,如果说 Appium 是移动端测试框架,那么 Selenium 就是 Web 端测试框架。简单的理解就可以认为我们可以编程控制浏览器的行为。Selenium 支持 Chrome,Firefox,Safari 等主流浏览器,也支持 PhantomJS, Headless Chrome 等等无头 (headless) 浏览器(无界面)。Selenium 支持的语言也非常多 Java, C#,Python, Ruby,JavaScript 1 等等
官网
安装 Python 客户端
pip install selenium
Python client Driver 的文档在这里
安装第三方驱动,所有支持的驱动可以在这里 找到。几个重要的 Driver
举例
import unittest
from selenium import webdriver
class GoogleTestCase(unittest.TestCase):
def setUp(self):
self.browser = webdriver.Firefox()
self.addCleanup(self.browser.quit)
def testPageTitle(self):
self.browser.get('http://www.google.com')
self.assertIn('Google', self.browser.title)
if __name__ == '__main__':
unittest.main(verbosity=2)
https://www.seleniumhq.org/download/ ↩
KIE 的使用和踩坑记录。
决策表默认使用的是 None 的 hit policy,这里涉及到一个问题也就是规则执行的顺序,默认的 None 其实是并发所有规则一同执行的,那么也就隐藏了一问题,如果传入的参数满足多条规则,那么极有可能造成结果不符预期的情况。
更多关于决策表 Hit Policy 的内容可以参考这篇 —- 决策表规则执行顺序
比如对于这条规则
rule "Row 1 testTable"
activation-group "first-hit-policy-group testTable"
dialect "mvel"
when
data : testData( eval( s == 5 ), eval( 0<=random && random<100 ))
then
data.setResult( "168" );
end
在创建决策表 Asset 的时候,如果选择了 FIRST_HIT
的决策表在每条规则会有条这样的规则:
activation-group "first-hit-policy-group testTable"
表示的是顺序从上到下一条一条执行。
今天无意间看到 Python 的 round() 方法,它支持第二个可选参数 round(number[, ndigits])
,看其文档可以知道
所以可以简单的将该函数记忆成四舍五入的方法,然而该方法在执行过程中有些情况需要特别注意,尤其是在输入数字为浮点数时。
>>> round(0.5)
1.0
>>> round(-0.5)
-1.0
Python 2 中
Python 2.7.13 (default, Aug 27 2018, 10:30:14)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> round(6.5)
7.0
Python 3 中
Python 3.6.1 (default, Jul 11 2017, 16:32:55)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> round(6.5)
6
当不提供 ndigits 时返回的是 integer 而提供 ndigits 时提供的是输入参数的类型
>>> type(round(1.4))
<class 'int'>
>>> type(round(1.454,2))
<class 'float'>
另外需要注意的是,因为 Float 在不同机器上表示方式不是精确的,所以在计算四舍五入时会发现有些数字会有很奇怪的输出,比如官方文档上给出的 2.675,保留 2 位,那么结果是:
>>> round(2.675,2)
2.67
另外 round 的第二个参数可以传入负数
>>> round(1234, -3)
1000.0
我手上的这款威联通机身前部有一个 USB 端口,平时用处也不多,但是今天看文档看到了威联通的 USB 一键备份,于是就找到了 Hybird Backup Sync 这样一个内置的应用。以前没仔细研究,发现这个应用能够做的事情还挺多,包括云端备份,或者是 Rsync 备份到 NAS,或者外部硬盘备份,总之这也可以单独拿出来写一篇文章了。
回到 USB 一键备份的主题上来,我原本的习惯并不把 U 盘当做便携的数据存储,大部分情况下 U 盘都是启动盘,装机盘,少部分没有网络环境需要便携的数据备份的时候才会用 U 盘来拷贝一些数据。那么这个时候 USB 一键备份的功能就体现了价值,在我使用 U 盘的绝大多数情况下我都不会将资料存放在 U 盘中超过一天,基本上随用随拷贝,用完即删除。所以往往有些时候从外部拷贝了一些材料,那么就可以往 NAS 上一插,自动进行备份即可。
USB 一键备份的设置在 Hybird Backup Sync 应用中,最下方外部备份,其中有一个 Tab 就是 USB 一键备份设置,如果前端的备份按钮无效,到这边设置下看看是否设置正确。在该设置下可以选择存储设备连接到前端 USB 的运行模式:
设置为一键备份之后,可以设置备份方向,一般都是从 USB 到 NAS 吧。
将 U 盘连接前端 USB
无奈现在还是很多人使用百度云,以前用一个 bcloud 在 linux 上还能解决 80% 的需求,但是后来封了,也就一直没有理。不过后来发现 aria2 也能够现在百度云的资源,所以想着 qnap 威联通上也应该是能够安装的,使用 docker 会更加容易些。
在 Container Station 中搜索 xujinkai/aria2-with-webui
安装即可。镜像是开源的地址在:https://github.com/XUJINKAI/aria2-with-webui
在设置中,网络选项下需要注意
其中容器的 8080 端口可以选择性映射,这个端口用来浏览下载的目录列表,对于暴露外网的服务千万小心。
所以映射完之后,威联通的 6800 端口是 webui 界面,6080 端口是 aria2 服务的端口。
在共享文件夹选项中,可以设置需要挂载的本机共享文件夹,镜像中有两个挂载路径
/data
这个挂载点用来存放下载的文件目录/conf
这个挂载点是 aria2 的配置目录分别在威联通上新建共享目录来挂载这两个目录即可。
docker run -d \
--name aria2-with-webui \
-p 6800:6800 \
-p 6080:80 \
-v /share/aria2-data:/data \
-v /share/aria2-conf:/conf \
-e PUID=1000 \
-e PGID=1000 \
-e SECRET=NOBODYKNOWSME \
xujinkai/aria2-with-webui
在完成容器创建之后,可以访问 http://[qnap-ip]:6080 来浏览 aria2 webui,在界面中找到“设置”,“连接设置”
在 aria2 RPC 主机和端口设置中,设置主机地址为威联通的 IP 地址,或者远程域名,端口为 6800
,如果设置了密码,需要在这里配置密码。
设置密码的过程,在 /conf
挂载点,找到 aria2.conf
文件,在文件中添加配置
rpc-secret=123456
如果在外网访问,一定要设置这个密码,如果在内网,可以不用设置。
在保存配置文件之后,需要重启容器。
在完成 aria2 的安装之后,就是如何将百度云的内容导出到 aria2 下载,答案就是 BaiduExport
手动安装插件之后,重新刷新百度云网页,在选中文件之后就会看见多出来一个 “导出下载”的按钮,在 aria2 rpc 的设置中,填写 rpc 服务地址
http://[qnap-ip]:6800/jsonrpc
如果设置了密码令牌,则需要
http://token:123456@[qnap-ip]:6800/jsonrpc
此时,选中想要下载的文件,然后使用 ARIA2 RPC
导出下载,然后去 WEBUI 查看下载状态即可。