2020年2月26日
#
Refer to How to Easily Create Ramdisk on Linux
This tutorial will show you how to quickly create a RAM disk in any Linux distro (Debian, Ubuntu, Linux, Fedora, Arch Linux, CentOS, etc). Compared to commercial Windows RAM disk software that costs money, Linux can utilize this cool feature 100% free of charge.
What is RAM Disk?
RAM disk is also known as RAM drive. It’s a portion of your RAM that are formated with a file system. You can mount it to a directory on your Linux system and use it as a disk partition.
Why use RAM disk?
RAM is ultra-fast compared to even the fastest solid state drive (SSD). As you may know, the main performance bottleneck in today’s computer is the speed of hard drive, so moving programs and files to the RAM disk yields super fast computing experience.
Pros of RAM disk:
- Ultra-fast
- Can sustain countless reads and writes
Cons of RAM disk:
- RAM is volatile which means all data in RAM disk will be lost when the computer shutdowns or reboots. However, this can be a pro in some situations, if you use it wisely.
- RAM is expensive so it has limited capacity. You need to make sure not allocate too much space for RAM disk, or the operating system would run out of RAM.
You can do a lot of interesting things with RAM disk.
- RAM disk is best suited for temporary data or caching directories, such as Nginx FastCGI cache. If you use a SSD and there will be a lot of writes to a particular directory, you can mount that directory as a RAM disk to reduce wear out of SSD.
- I also use RAM disk to temporary store screenshots when writing articles on this blog, so when my computer shut down, those screenshots will automatically be deleted on my computer.
- You may not believe it, but I use RAM disk to run virtual machines inside VirtualBox. My SSD is about 250G. I can’t run many VMs directly on the SSD and I’m not happy about the speed of my 2TB mechanical hard drive (HDD). I can move the VM from HDD to RAM disk before starting the VM, so the VM can run much faster. After shutting down the VM, I move the VM files back to HDD, which takes less than 1 minute. This of course requires your computer to have a large capacity RAM.
How to Create a RAM Disk in Any Linux Distro
First make a directory which can be anywhere in the file system such as
sudo mkdir /tmp/ramdisk
If you want to let every user on your Linux system use the RAM disk, then change its permission to 777.
sudo chmod 777 /tmp/ramdisk
Next, check how much free RAM are left on your system with htop
command line utility because we don’t want to use too much RAM.
htop

Then all left to do is to specify the file system type, RAM disk size, device name and mount it to the above directory. You can see from the screenshot above that I have plenty of free RAM, so I can easily allocate 1GB for my RAM disk. This can be done with the following one-liner. It will be using tmpfs
file system and its size is set to 1024MB. myramdisk
is the device name I gave to it.
sudo mount -t tmpfs -o size=1024m myramdisk /tmp/ramdisk
To allocate 10G for the RAM disk, run this instead.
sudo mount -t tmpfs -o size=10G myramdisk /tmp/ramdisk
If we issue the following command
mount | tail -n 1
We can see it’s successfully mounted.

Now if I copy my VirtualBox machines file (5.8G) into the RAM disk, my RAM usage suddenly goes up to 9.22G.

If I unmount RAM disk,
sudo umount /tmp/ramdisk/
Everything in that directory will be lost and RAM usage goes down to original.

This is how you can test if your RAM disk is working.
Test RAM Disk Speed
To test write speed of RAM disk, you can use dd utility.
sudo dd if=/dev/zero of=/tmp/ramdisk/zero bs=4k count=100000
Which gave me 2.8GB/s write speed.

To test read speed, run:
sudo dd if=/tmp/ramdisk/zero of=/dev/null bs=4k count=100000
Which gave me 3.1 GB/s read speed.
I also did a speed test on my SSD. The write speed is 534MB/s and read speed 1.6GB/s.
Auto-mount on System Boot
Edit /etc/fstab
file.
sudo nano /etc/fstab
Add an entry like this:
myramdisk /tmp/ramdisk tmpfs defaults,size=1G,x-gvfs-show 0 0
x-gvfs-show
will let you see your RAM disk in file manager. Save and close the file. Your Linux system will automatically mount the RAM disk when your computer boots up.
To mount it immediately without reboot, run the following command.
sudo mount -a
2019年11月28日
#
1. 使用pure或者view函數(shù),直接拿到返回值,但不是所有的函數(shù)都能聲明成pure/view。
2. 使用event包裝返回值,但是在emit之前返回的函數(shù)是沒(méi)有event的,如果需要每條path都返回有意義的return value,可能需要定義很多個(gè)event。(不考慮require throw的情況下)
3. 使用web3.eth.Contract.call,需要ABI和deployed address,這個(gè)用法有個(gè)缺點(diǎn)是將函數(shù)變成了constant的,即和1一樣無(wú)法改變合約內(nèi)部狀態(tài),只能說(shuō)在特定的場(chǎng)景下有用。
4. EIP-758(https://eips.ethereum.org/EIPS/eip-758),返回returnData在subscribe的通道上,但是看目前的狀態(tài)還是draft。
2019年3月27日
#
原文
在此在使用git提交代碼時(shí)候,有時(shí)候會(huì)遇到一個(gè)問(wèn)題,就是自己明明只修改了其中幾行,提交上去以后發(fā)現(xiàn)整個(gè)文件都被修改了,在設(shè)置了格式風(fēng)格以后還會(huì)有提交不上去的情況,這個(gè)時(shí)候經(jīng)常讓人摸不到頭腦,其實(shí)就是CRLF和LF在作怪
CRLF LF CR 都是什么意思:
CRLF: 是carriagereturnlinefeed的縮寫(xiě)。中文意思是回車換行。
LF: 是line feed的縮寫(xiě),中文意思是換行。
CR: 是carriagereturn的縮寫(xiě)。中文意思是回車。
簡(jiǎn)單的換行回車為什么會(huì)引出這么多的問(wèn)題呢,關(guān)鍵在于操作系統(tǒng)之間的分歧:
早期的mac系統(tǒng)使用CR當(dāng)做換行,現(xiàn)在也已經(jīng)統(tǒng)一成了LF
Unix(包含現(xiàn)在大量使用的linux)系統(tǒng)使用LF
windows系統(tǒng)使用LFCR當(dāng)做換行(自作聰明的兼容性??)
也正是因?yàn)椴煌到y(tǒng)的分歧,在多人協(xié)作共同開(kāi)發(fā)的時(shí)候,可能導(dǎo)致提交代碼時(shí)候產(chǎn)生問(wèn)題。
解決方法:
Android Studio內(nèi)部可以設(shè)置不同模式,具體位置在setting-->搜索code style見(jiàn)下圖:
其中有四個(gè)選項(xiàng)System-Dependent LF CR CRLF,默認(rèn)是System-Dependent,也就是根據(jù)你是什么系統(tǒng)選擇什么類型,如果想要自定義的話可以在這里設(shè)置,以后創(chuàng)建的新代碼也默認(rèn)用設(shè)置的方式
而如果想單獨(dú)修改某個(gè)文件的類型,也可以在右下角進(jìn)行修改,見(jiàn)下圖:
跨平臺(tái)合作時(shí)候的解決方式:
當(dāng)我們使用git庫(kù)提交代碼的時(shí)候,有的人可能使用mac,有的人使用linux,有的人使用windows,不同的開(kāi)發(fā)環(huán)境如果都是按照自己系統(tǒng)的方式任意修改換行類型,難免會(huì)讓代碼庫(kù)整體混亂或者產(chǎn)生許多沒(méi)有必要的代碼更新
那么解決該問(wèn)題的方式有:core.autocrlf命令
git為了防止以上問(wèn)題擾亂跨平臺(tái)合作開(kāi)發(fā),使用命令可以轉(zhuǎn)化LF和CRLF
具體體現(xiàn)為:
- git config --global core.autocrlf true
Git可以在你push時(shí)自動(dòng)地把行結(jié)束符CRLF轉(zhuǎn)換成LF,而在pull代碼時(shí)把LF轉(zhuǎn)換成CRLF。用core.autocrlf來(lái)打開(kāi)此項(xiàng)功能,如果是在Windows系統(tǒng)上,把它設(shè)置成true,這樣當(dāng)簽出代碼時(shí),LF會(huì)被轉(zhuǎn)換成CRLF
- git config --global core.autocrlf input
Linux或Mac系統(tǒng)使用LF作為行結(jié)束符;當(dāng)一個(gè)以CRLF為行結(jié)束符的文件不小心被引入時(shí)你肯定想進(jìn)行修正,把core.autocrlf設(shè)置成input來(lái)告訴 Git 在push時(shí)把CRLF轉(zhuǎn)換成LF,pull時(shí)不轉(zhuǎn)換
- git config --global core.autocrlf false
在本地和代碼庫(kù)中都保留CRLF,無(wú)論pull還是push都不變,代碼庫(kù)什么樣,本地還是什么樣子
當(dāng)然在多人跨平臺(tái)工作時(shí)候,最好還是約定使用LF,還是CRLF,然后不同系統(tǒng)進(jìn)行對(duì)應(yīng)的設(shè)置,這樣是工作規(guī)范,也有利于提高工作效率,希望以上可以幫助大家。
作者:sososun
鏈接:https://www.jianshu.com/p/dd7464cf32b5
來(lái)源:簡(jiǎn)書(shū)
簡(jiǎn)書(shū)著作權(quán)歸作者所有,任何形式的轉(zhuǎn)載都請(qǐng)聯(lián)系作者獲得授權(quán)并注明出處。
2019年1月17日
#
原文
在此
由于Go沒(méi)有為slice提供shuffle函數(shù),所以需要自己想辦法。由于我只需要隨機(jī)一次遍歷1 -> N,所以這段code最匹配。
func main() {
vals := []int{10, 12, 14, 16, 18, 20}
r := rand.New(rand.NewSource(time.Now().Unix()))
for _, i := range r.Perm(len(vals)) {
val := vals[i]
fmt.Println(val)
}
}
似乎go不像scala有那種惰性求值的特性,所以這里的r.Perm()還是產(chǎn)生了一個(gè)slice,如果N很大可能是個(gè)問(wèn)題。
2018年8月14日
#
測(cè)試中想通過(guò)命令行傳遞一些參數(shù)給test func,網(wǎng)上找了一些資料但過(guò)程不是很順利,這里記錄一下。
首先go test有一個(gè)-args的參數(shù)說(shuō)可以達(dá)到這個(gè)目的,但實(shí)測(cè)下來(lái)發(fā)現(xiàn)有沒(méi)有沒(méi)區(qū)別。。。
google查到的大部分也是用到了flag類型。
flag.go的注釋寫(xiě)的比較清楚
/*
Package flag implements command-line flag parsing.
Usage:
Define flags using flag.String(), Bool(), Int(), etc.
This declares an integer flag, -flagname, stored in the pointer ip, with type *int.
import "flag"
var ip = flag.Int("flagname", 1234, "help message for flagname")
If you like, you can bind the flag to a variable using the Var() functions.
var flagvar int
func init() {
flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
}
Or you can create custom flags that satisfy the Value interface (with
pointer receivers) and couple them to flag parsing by
flag.Var(&flagVal, "name", "help message for flagname")
For such flags, the default value is just the initial value of the variable.
After all flags are defined, call
flag.Parse()
to parse the command line into the defined flags.

*/
因此需要做的事情就是:
1. 定義flag,這個(gè)需要在main()執(zhí)行之前完成,我這里在test文件里面用全局變量完成,但a可以放在函數(shù)里面。
var (
// Define global args flags.
pA = flag.Int("a", 0, "a.")
a = 0
)
2. parse flag,這個(gè)要在test func執(zhí)行之前,所以可以考慮加入一個(gè)init()在test文件里。
func init() {
flag.Parse()
a = *pA
}
后面使用這些變量就沒(méi)有問(wèn)題了,比如這樣
func TestInit(t *testing.T) {
flag.Parse()
t.Log("a = ", a)
}
這里用到的主要是flag的功能,測(cè)試用發(fā)現(xiàn)有沒(méi)有-args問(wèn)題不大,所以這個(gè)用法可能不是很符合go test的要求,先用起來(lái)再說(shuō)了。
REF
1. https://www.golangtc.com/t/584cbd16b09ecc2e1800000b
2. https://stackoverflow.com/.../process-command-line-arguments-in-go-test
3. https://hsulei.com/2017/08/23/gotest如何使用自定義參數(shù)/
原文在此
學(xué)習(xí)shell的時(shí)候總是被shell里的條件判斷方式搞得頭疼,經(jīng)常不知道改 用[],[[]],(())還是test,let,而很少有書(shū)把它們的關(guān)系講解的很清楚(應(yīng)該是我悟性差或是看書(shū)太少),今天總結(jié)一下,基礎(chǔ)的東西如它們 的使用方法不再贅述,重點(diǎn)說(shuō)說(shuō)它們的區(qū)別的使用時(shí)應(yīng)該注意的地方。
先說(shuō)[]和test,兩者是一樣的,在命令行里test expr和[ expr ]的效果相同。test的三個(gè)基本作用是判斷文件、判斷字符串、判斷整數(shù)。支持使用與或非將表達(dá)式連接起來(lái)。要注意的有:
1.test中可用的比較運(yùn)算符只有==和!=,兩者都是用于字符串比較的,不可用于整數(shù)比較,整數(shù)比較只能使用-eq, -gt這種形式。無(wú)論是字符串比較還是整數(shù)比較都千萬(wàn)不要使用大于號(hào)小于號(hào)。當(dāng)然,如果你實(shí)在想用也是可以的,對(duì)于字符串比較可以使用尖括號(hào)的轉(zhuǎn)義形式, 如果比較"ab"和"bc":[ ab \< bc ],結(jié)果為真,也就是返回狀態(tài)為0.
然后是[[ ]],這是內(nèi)置在shell中的一個(gè)命令,它就比剛才說(shuō)的test強(qiáng)大的多了。支持字符串的模式匹配(使用=~操作符時(shí)甚至支持shell的正則表達(dá) 式)。簡(jiǎn)直強(qiáng)大的令人發(fā)指!邏輯組合可以不使用test的-a,-o而使用&&,||這樣更親切的形式(針對(duì)c、Java程序員)。當(dāng) 然,也不用想的太復(fù)雜,基本只要記住
1.字符串比較時(shí)可以把右邊的作為一個(gè)模式(這是右邊的字符串不加雙引號(hào)的情況下。如果右邊的字符串加了雙引號(hào),則認(rèn)為是一個(gè)文本字符串。),而不僅僅是一個(gè)字符串,比如[[ hello == hell? ]],結(jié)果為真。
另外要注意的是,使用[]和[[]]的時(shí)候不要吝嗇空格,每一項(xiàng)兩邊都要有空格,[[ 1 == 2 ]]的結(jié)果為“假”,但[[ 1==2 ]]的結(jié)果為“真”!后一種顯然是錯(cuò)的
3.最后就是let和(()),兩者也是一樣的(或者說(shuō)基本上是一樣的,雙括號(hào)比let稍弱一些)。主要進(jìn)行算術(shù)運(yùn)算(上面的兩個(gè)都不行),也比較適合進(jìn) 行整數(shù)比較,可以直接使用熟悉的<,>等比較運(yùn)算符。可以直接使用變量名如var而不需要$var這樣的形式。支持分號(hào)隔開(kāi)的多個(gè)表達(dá)式
2018年8月1日
#
圖片來(lái)源:https://blog.slock.it/public-vs-private-chain-7b7ca45044f
2018年7月21日
#
REF: https://dominik.honnef.co/posts/2014/12/an_incomplete_list_of_go_tools/
go get github.com/golang/lint/golint
go get github.com/kisielk/errcheck
go get golang.org/x/tools/cmd/benchcmp
go get github.com/cespare/prettybench
go get github.com/ajstarks/svgo/benchviz
go get golang.org/x/tools/cmd/stringer
go get github.com/josharian/impl
go get golang.org/x/tools/cmd/goimports
go get sourcegraph.com/sqs/goreturns
go get code.google.com/p/rog-go/exp/cmd/godef
go get github.com/nsf/gocode
go get golang.org/x/tools/cmd/oracle
go get golang.org/x/tools/cmd/gorename
go get github.com/kisielk/godepgraph
2018年7月14日
#
Introduction
Solidiay doc about ABI and contract access.
https://solidity.readthedocs.io/en/develop/abi-spec.html
https://solidity.readthedocs.io/en/latest/introduction-to-smart-contracts.html?highlight=selfdestruct
http://www.ethdocs.org/en/latest/contracts-and-transactions/accessing-contracts-and-transactions.html
http://ethdocs.org/en/latest/contracts-and-transactions/contracts.html#testing-contracts-and-transactions
https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=suicide [global variables like msg.sender]
ABI intro in Ethereum Wiki.
https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI#argument-encoding
https://github.com/ethereum/go-ethereum/wiki/Contract-Tutorial
JAON rpc api of Eth.
https://github.com/ethereum/wiki/wiki/JSON-RPC#json-rpc-api
https://github.com/ethereum/wiki/wiki/JavaScript-API#contract-methods
Deploy a contract using RPC.
https://github.com/rsksmart/rskj/wiki/Deploying-contracts-using-RPC-calls
A tool to generate the grpc server code for a contract
https://github.com/getamis/grpc-contract
How to test.
http://ethereum-tests.readthedocs.io/en/latest/test_types/transaction_tests.html
https://github.com/ethereum/cpp-ethereum/blob/develop/doc/generating_tests.rst
go-ethereum里面有一批vm和contract相關(guān)的tests,結(jié)合ABI和contract的定義,可以很容易的寫(xiě)一批自己定制的測(cè)試,從web3js或者直接在go project里面調(diào)用都可以。
2017年6月19日
#
https://stackoverflow.com/questions/13620281/what-is-the-maven-shade-plugin-used-for-and-why-would-you-want-to-relocate-java
Uber JAR, in short, is a JAR containing everything.
Normally in Maven, we rely on dependency management. An artifact contains only the classes/resources of itself. Maven will be responsible to find out all artifacts (JARs etc) that the project depending on when the project is built.
An uber-jar is something that take all dependencies, and extract the content of the dependencies and put them with the classes/resources of the project itself, in one big JAR. By having such uber-jar, it is easy for execution, because you will need only one big JAR instead of tons of small JARs to run your app. It also ease distribution in some case.
Just a side-note. Avoid using uber-jar as Maven dependency, as it is ruining the dependency resolution feature of Maven. Normally we create uber-jar only for the final artifact for actual deployment or for manual distribution, but not for putting to Maven repository.
Update: I have just discovered I haven't answered one part of the question : "What's the point of renaming the packages of the dependencies?". Here is some brief updates and hopefully will help people having similar question.
Creating uber-jar for ease of deployment is one use case of shade plugin. There are also other common use cases which involve package renaming.
For example, I am developing Foo
library, which depends on a specific version (e.g. 1.0) of Bar
library. Assuming I cannot make use of other version of Bar
lib (because API change, or other technical issues, etc). If I simply declare Bar:1.0
as Foo
's dependency in Maven, it is possible to fall into a problem: A Qux
project is depending on Foo
, and also Bar:2.0
(and it cannot use Bar:1.0
because Qux
needs to use new feature in Bar:2.0
). Here is the dilemma: should Qux
use Bar:1.0
(which Qux
's code will not work) or Bar:2.0
(which Foo
's code will not work)?
In order to solve this problem, developer of Foo
can choose to use shade plugin to rename its usage of Bar
, so that all classes in Bar:1.0
jar are embedded in Foo
jar, and the package of the embedded Bar
classes is changed from com.bar
to com.foo.bar
. By doing so, Qux
can safely depends on Bar:2.0
because now Foo
is no longer depending on Bar
, and it is using is own copy of "altered" Bar
located in another package.