记录每天所学到的、想到的和遇到的:
Linux coreutils 里的 rmdir 命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
man rmdir
NAME
rmdir - remove empty directories
SYNOPSIS
rmdir [OPTION]... DIRECTORY...
DESCRIPTION
Remove the DIRECTORY(ies), if they are empty.
--ignore-fail-on-non-empty
ignore each failure that is solely because a directory is non-empty
-p, --parents
remove DIRECTORY and its ancestors; e.g., 'rmdir -p a/b/c' is similar to 'rmdir a/b/c a/b a'
|
其实也可以用 find
:
1
|
find . -type d -empty -delete
|
How to remove all empty directories in a subtree?
Jetbrians IdeaVIM 的 Forward 和 Back 不工作了
nmap <C-i> :action Forward<CR>
nmap <C-o> :action Back<CR>
https://youtrack.jetbrains.com/issue/VIM-2225
google chrome 无法播放视频
今天发现 YouTube
无法播放视频了,于是很纳闷?难道我这几天新安装了什么插件吗?仔细一回想,没有啊。
然后我从命令行启动 Chrome
发现以下日志:
1
2
3
4
5
6
|
❯ google-chrome-stable
[62820:62820:0513/165342.261311:ERROR:vaapi_wrapper.cc(1136)] vaQuerySurfaceAttributes failed, VA error: invalid parameter
[62820:62820:0513/165342.261383:ERROR:vaapi_wrapper.cc(1083)] FillProfileInfo_Locked failed for va_profile VAProfileH264Main and entrypoint VAEntrypointVLD
[62820:62820:0513/165342.261421:ERROR:vaapi_wrapper.cc(1136)] vaQuerySurfaceAttributes failed, VA error: invalid parameter
[62820:62820:0513/165342.261452:ERROR:vaapi_wrapper.cc(1083)] FillProfileInfo_Locked failed for va_profile VAProfileH264High and entrypoint VAEntrypointVLD
|
奇怪,看起来是音视频硬件加速出了问题。
从 vainfo
发现了诡异的地方:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
❯ vainfo
vainfo: VA-API version: 1.14 (libva 2.14.0)
vainfo: Driver version: Splitted-Desktop Systems VDPAU backend for VA-API - 0.7.4
vainfo: Supported profile and entrypoints
VAProfileMPEG2Simple : VAEntrypointVLD
VAProfileMPEG2Main : VAEntrypointVLD
VAProfileMPEG4Simple : VAEntrypointVLD
VAProfileMPEG4AdvancedSimple : VAEntrypointVLD
<unknown profile> : VAEntrypointVLD
VAProfileH264Main : VAEntrypointVLD
VAProfileH264High : VAEntrypointVLD
VAProfileVC1Simple : VAEntrypointVLD
VAProfileVC1Main : VAEntrypointVLD
VAProfileVC1Advanced : VAEntrypointVLD
|
有一行是 unknown profile
https://forum.manjaro.org/t/nvaapi-video-acceleration-on-google-chrome-stable-not-working/100109/3
从这个 issue
看到说需要安装 libva-vdpau-driver-chromium
?奇怪,以前我从来没安装过这个包啊。
1
2
|
yay -S libva-vdpau-driver-chromium
# note: Installing libva-vdpau-driver-chromium will remove: libva-vdpau-driver
|
安装 =libva-vdpau-driver-chromium= 完之后:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
❯ vainfo
vainfo: VA-API version: 1.14 (libva 2.14.0)
vainfo: Driver version: Splitted-Desktop Systems VDPAU backend for VA-API - 0.7.4
vainfo: Supported profile and entrypoints
VAProfileMPEG2Simple : VAEntrypointVLD
VAProfileMPEG2Main : VAEntrypointVLD
VAProfileMPEG4Simple : VAEntrypointVLD
VAProfileMPEG4AdvancedSimple : VAEntrypointVLD
VAProfileH264Main : VAEntrypointVLD
VAProfileH264High : VAEntrypointVLD
VAProfileVC1Simple : VAEntrypointVLD
VAProfileVC1Main : VAEntrypointVLD
VAProfileVC1Advanced : VAEntrypointVLD
|
再次启动 chrome 又发现新的问题
[48720:48720:0513/172226.125496:ERROR:gl_utils.cc(319)] [.WebGL-0x3b600379bf00]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels
奇怪?这次看起来是显卡的问题, GPU stall
了。
linux 的 faillock
今天感觉键盘上有很多灰尘,想擦一擦,于是先锁屏,然后用湿巾疯狂擦了几下键盘,擦完发现因不小心触碰了很多次解锁键,失败次数过多,得等 10 分钟后才能解锁。
于是了解到了: faillock
https://linux.die.net/man/8/faillock
只能以 root 身份从 tty 登录,然后
1
2
|
faillock --user ${USER} --reset
|
vim 中的 ysiw, 和 cs
1
2
3
4
5
6
7
8
|
ci" - change inside double quotes
ci) - change inside curved brackets
ci} - change inside curly brackets
|
ysiw]
surround a text object with ‘=’
https://github.com/tpope/vim-surround/issues/128
linux 下从进程的 pid 去寻找这个 pid 属于哪个 docker 容器。
今天有同事发现公司一台服务器占用的资源较多,他从 =top= 拿到了 =pid= 。
于是搜了一下, =/proc/= 下面可以查看 =/proc/${pid}/cgroup= 来得到 =containerId=
1
2
3
4
5
6
7
8
9
10
11
12
|
❯ docker run -d --rm --net="host" --name mymongo -e MONGO_INITDB_ROOT_USERNAME=root -e MONGO_INITDB_ROOT_PASSWORD=123456 mongo:5.0.0
e7cd5c86843ddb2fe6e1b96e24702f193bf319ffc5f667f1728bff1f7fb18d6e
❯ ps aux | grep -i mongod
999 1015717 21.3 0.1 1534516 105496 ? Ssl 16:11 0:00 mongod --auth --bind_ip_all
exec 1016018 0.0 0.0 9760 2436 pts/74 S+ 16:11 0:00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn --exclude-dir=.idea --exclude-dir=.tox -i mongod
❯ cat /proc/$(pidof mongod)/cgroup
0::/system.slice/docker-e7cd5c86843ddb2fe6e1b96e24702f193bf319ffc5f667f1728bff1f7fb18d6e.scope
❯ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e7cd5c86843d mongo:5.0.0 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes mymongo
|
今天学到了 xargs 的 –max-procs 参数。
我负责公司以太坊节点的数据导出到 apache parquet
的工作,我为erigon
写的导出工具是单线程的,导出数据不仅会有磁盘的I/O
操作,也会有一些消耗CPU
的压缩操作。
以太坊节点所在的机器有16
个核,我以前是这样写并发导出脚本的:(为了突出重点,我做了精简)
1
2
3
4
5
6
7
8
9
10
|
MAX_PROCESS=14
parallelCount=0
for endBlock in $(seq 10000 -1000 1); do
${EXPORT_CLI} &>> export.log &
if [ ${parallelCount} -eq ${MAX_PROCESS} ]; then
wait
parallelCount=0
fi
done
wait
|
这段代码的缺点是:在 ${parallelCount} -eq ${MAX_PROCESS}
为true
的时候,程序会一直等待,即使并发任务数量降为1
。这不是我能够容忍的。
于是我了解到了 xargs
的 --max-procs
-P max-procs, –max-procs=max-procs
Run up to max-procs processes at a time; the default is 1. If max-procs is 0, xargs will run as many processes as possible at a time. Use the -n option or the -L option with -P; otherwise chances are that only one exec will be done. While xargs is running, you can send its process a SIGUSR1 signal to increase the number of commands to run simultaneously, or a SIGUSR2 to decrease the number. You cannot increase it above an implementation-defined limit (which is shown with –show-limits). You cannot decrease it below 1. xargs never terminates its commands; when asked to decrease, it merely waits for more than one existing command to terminate before starting another.
于是我将代码这样修改:
1
2
3
4
5
6
7
|
function run_export_trace(){
block=$1
export_cli=$2
${export_cli} &>> export.log
}
export -f run_export_trace
seq 14340000 -${STEP} 1 | xargs -i --max-procs ${MAX_PROCESS} bash -c "run_export_trace {} ${EXPORT_CLI}"
|
完美!这样cpu
就不会闲着了。
我想将我的私人文件不被 git track, 但又不方便加入到 .gitignore 里面
我在和他人合作开发一个项目的时候,会自己写很多私有的脚本,每次在 git add
的时候都要关心一下有没有把不该track
的东西给track
了,本来可以加入到 .gitignore
里, 但是我又不想把我的私人文件加入到 .gitignore
里。
搜了一下, 也可以加入到 .git/info/exclude
里, 这个文件不会被 git track.
https://git-scm.com/docs/gitignore
Linux umount 时遇到: target is busy
今天坐在我工位对面的同事尝试对存放以太坊节点数据的磁盘执行 umount
操作, 遇到了 target is busy
这个问题。我的直觉告诉我这应该是有个进程正在读写这块硬盘。所以 umount
才会失败。
于是立即学习一下 core/psmisc
包里面的fuser
命令,和 lsof
命令。
从man
手册可以查到:
fuser: fuser displays the PIDs of processes using the specified files or file systems.
fuser returns a non-zero return code if none of the specified files is accessed or in case of a fatal error. If at least one access has been found, fuser returns zero.
fuser
的ACCESS
列展示了相关进程的具体 access 信息
c current directory.
e executable being run.
f open file. f is omitted in default display mode.
F open file for writing. F is omitted in default display mode.
r root directory.
m mmap'ed file or shared library.
. Placeholder, omitted in default display mode.
fuser
有 -m
选项:
-m NAME, –mount NAME
NAME specifies a file on a mounted file system or a block device that is mounted. All processes accessing files on that file system are listed. If a directory is specified, it is automatically changed to NAME/ to use any file system that might be mounted on that direc‐
tory.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
❯ fuser -m /run/media/exec/vax/ -v
USER PID ACCESS COMMAND
/run/media/exec/vax: root kernel mount /run/media/exec/vax
exec 269858 ..c.. zsh
exec 269933 f...m gitstatusd-linu
❯ fuser -m /run/media/exec/vax/ -v
USER PID ACCESS COMMAND
/run/media/exec/vax: root kernel mount /run/media/exec/vax
exec 269933 f...m gitstatusd-linu
❯ fuser -m /run/media/exec/vax/ -v
USER PID ACCESS COMMAND
/run/media/exec/vax: root kernel mount /run/media/exec/vax
exec 269933 f...m gitstatusd-linu
❯ fuser -m /run/media/exec/vax/ -v
USER PID ACCESS COMMAND
/run/media/exec/vax: root kernel mount /run/media/exec/vax
|
我注意到,即使我的zsh
离开了 外置硬盘所在的目录时, 这个硬盘依然被使用着,因为我用了 zsh 的一个 git status daemon 插件,这个插件估计会定时获取远程 git 仓库的状态。所以 fuser 展示了 gitstatusd-linux
后来我退出了 zsh shell
, gitstatusd-linux
才退出。
https://unix.stackexchange.com/questions/3109/how-do-i-find-out-which-processes-are-preventing-unmounting-of-a-device
vim 使用 column 命令将若干列文本对齐
我的需求是这样的,想把这三列文本从上面的样子变成下面的样子:
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
|
private String transactionHash;
private String blockHash;
private Long blockNumber;
private String fromAddress;
private Long gas;
private Long gasPrice;
private String input;
private Long nonce;
private String toAddress;
private Integer transactionIndex;
private BigDecimal transactionValue;
private Long blockTimestamp;
private Receipt receipt;
private String transactionHash;
private String blockHash;
private Long blockNumber;
private String fromAddress;
private Long gas;
private Long gasPrice;
private String input;
private Long nonce;
private String toAddress;
private Integer transactionIndex;
private BigDecimal transactionValue;
private Long blockTimestamp;
private Receipt receipt;
|
只需进入 vim
的VISUAL
模式,选中那十几行,然后 :!column -t
即可。
将 Google NCR 设置为浏览器默认搜索引擎
我不喜欢 google 返回我和我位置信息相关的搜索结果,于是设置一下 Google NCR (No Current Region)
https://10wontips.blogspot.com/2018/07/always-search-google-in-english-by.html
我今天学到的 Linux 命令: disown
为了搞懂 disown
命令,必须得搞明白 linux
的 jobs
这个概念。
job
其实就是 shell
管理下的进程,每个 job
都有唯一的 job ID
, job
有 3 中状态: foreground
, background
(在命令末尾用了 & 符号), stopped
(按下 Ctrl-Z 会使得前台进程处于该状态)
与 job
相关的命令有这几个:
1
2
3
|
jobs # 列出 jobs 列表
bg %n # 让该 job 在后台工作
fg %n # 让该 job 在前台工作
|
如果你其他以 cmd &
的方式让一个进程工作在后台,当你退出 shell
后,该进程就会挂掉,要么你用 nohup
来启动,或者考虑 disown
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
$ help disown
disown: disown [-h] [-ar] [jobspec ... | pid ...]
Remove jobs from current shell.
Removes each JOBSPEC argument from the table of active jobs. Without
any JOBSPECs, the shell uses its notion of the current job.
Options:
-a remove all jobs if JOBSPEC is not supplied
-h mark each JOBSPEC so that SIGHUP is not sent to the job if the
shell receives a SIGHUP
-r remove only running jobs
Exit Status:
Returns success unless an invalid option or JOBSPEC is given.
|
disown
可以让指定 job
从job table
中移除,这样 即使你退出 shell
, 后台进程也不会挂掉。
其中 -h
参数可以让 disown
在终端退出之后才生效。
vim 用户必须了解的 的 motion 和 operation
https://www.barbarianmeetscoding.com/boost-your-coding-fu-with-vscode-and-vim/editing-like-magic-with-vim-operators/
awk 不定长句子的最后一个单词:
NF 表示这行句子的字段数。
vmtouch: 一个可以分析/控制文件系统缓存的工具
我拥有很多 roamXXXX.org
文件, 还有一个超级大的 org-journal
文件,每当我第一次用emacs
打开这些大文件后,感受到明显的卡顿,我认为这明显的卡顿其中从磁盘冷加载文件贡献了 30% 的卡顿,然后就是解析大文件,格式化和 highlight 贡献了 70% 的卡顿。于是我想让电脑在第一次开机的时候,将这些预读一下,旁加载到page cache
里。最简单粗暴的方法,就是写个循环,把这些文件都 cat * > /dev/null
, 后来找到了更为优雅的工具: vmtouch
https://hoytech.com/vmtouch/
1
2
3
|
vmtouch -vt ~/.emacs.d/
vmtouch -vt ~/org/roam/
vmtouch -vt ~/org/daily/
|
vmtouch 可以将文件 touch
进内存, 也可以将内存中的文件缓存 evict
出内存。
vmtouch 的用了这些系统调用:
1
2
3
4
5
6
|
#include <sys/mman.h>
int mincore(void *addr, size_t length, unsigned char *vec);
#include <fcntl.h>
int posix_fadvise(int fd, off_t offset, off_t len, int advice);
|
scrcpy 控制安卓手机
我拥有一个安卓手机,没有 root,今天想通过 Linux 系统来控制手机,于是折腾了一下,找到了 scrcpy 这个包:

1
2
3
|
❯ sudo pacman -Ss scrcpy
archlinuxcn/scrcpy 1.19-1 [installed]
Display and control your Android device
|
https://github.com/Genymobile/scrcpy
注意是scrcpy
不是scrapy
, scrapy
是 python 的一个爬虫框架,我们需要的是scrcpy
我本来可以通过 usb 数据线链接手机,然后开启 adb 调试模式的,但是嫌麻烦。找到了通过 wifi 链接手机 adb 调试的方案:
并且通过 adb 解锁手机锁屏。
https://stackoverflow.com/questions/29072501/how-to-unlock-android-phone-through-adb
这样就能愉快的操控手机了~
Linux 控制外接显示器的亮度
因为我最近把外接显示器放置的比较远,我目前在坐的位置是面对窗户并且面朝东。早上阳光非常刺眼,就得将显示器亮度调高点才合适,晚上又得吧显示器亮度调暗。我懒得伸手去操作显示器,所以从终端控制:
我用的 archlinux,需要这个包
1
2
3
4
|
❯ sudo pacman -Sii ddcutil
Repository : extra
Name : ddcutil
Description : Query and change Linux monitor settings using DDC/CI and USB.
|
然后 load i2c-dev module
现在 ddcutil 就可以使用了:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
~
❯ sudo ddcutil capabilities | grep "Feature: 10"
Feature: 10 (Brightness)
~
❯ sudo ddcutil getvcp 10
VCP code 0x10 (Brightness ): current value = 50, max value = 100
~
❯ sudo ddcutil setvcp 100
Missing argument(s)
~
❯ sudo ddcutil setvcp 10100
~
❯ sudo ddcutil capabilities | grep "Feature: 10"
Feature: 10 (Brightness)
~
❯ sudo ddcutil getvcp 10
VCP code 0x10 (Brightness ): current value = 50, max value = 100
~
❯ sudo ddcutil setvcp 10 100
~
❯ sudo ddcutil setvcp 10 20
~
❯ sudo ddcutil setvcp 10 100
|
大功告成,以后我再也不用伸胳膊去够显示器后面的调节按钮了。
:-D
Wikiwand: Wikipedia Modernized, 一个可以让你的 wikipedia 页面更好看的 chrome 插件!
https://chrome.google.com/webstore/detail/wikiwand-wikipedia-modern/emffkefkbkpkgpdeeooapgaicgmcbolj
使用 kdeconnect-cli 为手机分享文件或文字
因为懒得去动鼠标/触摸板来 操作 kdeconnect 的图形界面,所以研究了一下如何在终端里将文件分享给手机。
1
2
3
4
5
|
kdeconnect-cli -l
kdeconnect-cli -a --id-only
kdeconnect-cli -d ${deviceid} --ping
kdeconnect-cli -d ${deviceid} --share ${realpath_of_file}
kdeconnect-cli -d ${deviceid} --share-text ${text} # 这会把文本分享给手机的粘贴板。
|
https://userbase.kde.org/KDE_Connect/Tutorials/Useful_commands
一个可以为远古时期的网页设置 syntax highlighting 的 firefox 插件:Enlight
https://addons.mozilla.org/en-US/firefox/addon/enlight/
zsh 快捷键相关的
其实很久以前就知道 bash/zsh 有很多移动鼠标的快捷键是从 emacs 那里移过来的。
今天我在 zsh 下工作时,巧合地触发了 M-x 键,它给我弹出了个 execute prompt
, 于是我研究一番,zsh 下的 M-x 竟然和 emacs 的 M-x 相通,都是用来execute-command
的
https://unix.stackexchange.com/questions/440159/regarding-altx-in-zsh-and-how-to-bind-altx-to-something-else
ssh forward 遇到 bind: Cannot assign requested address
我今天在执行ssh -N -L port1:address:port2 server
时遇到了这个问题:
https://www.electricmonk.nl/log/2014/09/24/ssh-port-forwarding-bind-cannot-assign-requested-address/
原来是 ssh 试图 bind ipv6 地址
指定 ssh -4 使用 ipv4 地址 即可。
用命令行将 html 导出为图片
- 用
google-chrome
1
|
google-chrome-stable --headless --disable-gpu --virtual-time-budget=10000 --window-size=3840,2160 --screenshot https://www.google.com
|
List of Chromium Command Line Switches
https://developers.google.com/web/updates/2017/04/headless-chrome
https://dschnurr.medium.com/using-headless-chrome-as-an-automated-screenshot-tool-4b07dffba79a
- 用
wkhtmltoimage
1
|
wkhtmltoimage --width 1980 --height 1024 --quality 100 --javascript-delay 10000 https://www.google.com google.png
|
Emacs 将 org-journal-entry 同步到 telegram channel 里
我使用 org-journal
来记录生活,但是 org-journal
是离线的,我创建了个 bot
来将单条 org-journal-entry
同步到 channel
里。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
(defun exec/get-org-entry-summary ()
(interactive)
(setq urlraw (format
"https://api.telegram.org/bot%s/[email protected]%s&text="
(read-file "/home/vory/.emacs.d/config/tgsync.token")
(read-file "/home/vory/.emacs.d/config/chatid.priv")
))
(setq urlraw (concat urlraw (buffer-substring (line-beginning-position) (line-end-position))))
(message urlraw)
(setq urlq (url-encode-url urlraw))
(setq url-proxy-services
'(("http" . "127.0.0.1:1081")
("https" . "127.0.0.1:1081")))
(url-retrieve-synchronously urlq)
(message "sync to telegram channel success"))
|
茴香豆的茴有几种写法之 VIM 有哪几种退出方式?
日志里面第一列是 ip, 查询出现次数前 10 的 ip
1
|
cat xxx.log | awk '{ print $1 }' | sort -n | uniq -c | sort -r -k1 | head 10
|
grep pdf 文件
ripgrep-all
为 tmux 的 pane 名称设置不同的 emoji 后缀
生活要过的多姿多彩,同样的,我的终端也必须多姿多彩。于是我给 tmux
的panel
添加了随机的emoji
后缀
写一个shell
脚本,放进我喜欢的emoji
1
2
3
4
|
EMOJIS=(😀 😃 😄 😁 😆 😅 🤣 😂 🙂 🙃 😉 😊 😇 🥰 😍 🤩 😘 )
SELECTED_EMOJI=${EMOJIS[$RANDOM % ${#EMOJIS[@]}]};
echo -n $SELECTED_EMOJI
|
然后在tmux
里这样设置pane
的名称,:
1
|
set-option -g automatic-rename-format '#{b:pane_current_path}[#(/home/vory/Dotfiles/tmux/pick.sh)]'
|
大功告成!
direvent:
GNU direvent - Summary [Puszcza]
OCR 应用: tesseract
有时候身边的同事在排查问题的时候,会从用户那里得到图片形式的hash
,为了debug
,我本可以手工将图片形式的哈希转化为文本形式的,可是我实在是嫌麻烦,于是玩了下这个从 2006 年开始由Google
maintain 的 OCR
工具: tesseract-ocr/tesseract
ArchLinux 下所需的包

1
|
> sudo pacman -S tesseract tesseract-data-chi_sim tesseract-data-chi_tra tesseract-data-eng
|
第一个是主程序,其他的都是由Google
训练好的中文和英文模型库。
tesseract
的使用规则是这样的:
1
2
3
4
|
tesseract FILE OUTPUTBASE [OPTIONS]... [CONFIGFILE]...
# If FILE is stdin or - then the standard input is used.
# If OUTPUTBASE is stdout or - then the standard output is used.
|
我的使用流程是: 从屏幕上截图,截图会自动保存到粘贴版,然后:
1
|
xclip -sel clip -target image/png -o | tesseract stdin stdout -l chi_sim -c preserve_interword_spaces=1
|
如果不加preserve_interword_spaces=1
的话,识别出的结果就会有烦人的空格。
结果很准确,甚至是同时有中文英文和符号的图片都能识别!
使用 sed 获取一个文件位于两个关键词之间的内容
比如:
> cat file.txt
first line :head
second line
third line
apple
forth line
...
tiger
last line
tail
1
2
3
4
5
6
|
> sed -n '/apple/,/tigger/p' file.txt
apple
forth line
...
tiger
|
goland 缺失的功能
我用goland
开发公司的项目,很喜欢goland
的rename usages of 变量/函数 A to 变量/函数 B
的功能,但是我却不能对 import 这么做, 要是想改变整个项目都某一个包的引用,不得不使用 sed
:
1
|
find . -name '*.go' -type f -exec sed -i 's/tg-service/tg-service\/bridge/g' {} ';'
|
*nix 环境,快速生成大量随机的 leetcode 测试用例
当我在 leetcode
做了一道算法题后, 我会先在心里考虑一下输入的边界情况(或者非法输入),时间复杂度(要是数据里过大并且我的算法时间复杂度太差就会 Time Limit Exceed)。
所以我要么手动在 test cases
里手写测试用例, 要么用 linux
下这么几个有用的命令随机生成大量的测试用例:
1
2
3
4
5
6
|
seq # print a sequence of numbers
shuf # generate random permutations
paste # merge lines of files
|
用这三个简单的工具, 一般就能生成我想要的测试数据了。
比如我想生成一个数组, 数组的每个元素都是数字,整个数组要是 unsorted:
要是想要超大的数据量, 我一般会写到 /tmp/
里,再配合 xclip
将内容读进到 粘贴板, 最终粘贴到网页里去
https://leetcode.com/problems/combination-sum/solution/
1
2
3
|
seq 100 | shuf | paste -s -d ,
|
我喜欢用 printf
配合这些工具输出我想要的格式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
> cat gen.sh
N=100
if [[ $# -eq 1 ]];then
N=$1
fi
for n in $(seq $N) ;
do
if [[ $(($RANDOM % 3 )) -eq 0 ]];then
echo $n
fi
done
> printf "[%s]\n" "$(./gen.sh 365 | paste -s -d , )"
[3,10,11,18,21,22,32,37,40,44,45,46,48,50,52,53,55,57,61,63,64,65,66,68,69,76,79,90,91,93,95,96,99,100]
> printf "[%s]\n" "$(./gen.sh 365 | paste -s -d , )" | xclip -sel clip
# 生成随机结果, 并且复制到粘贴板
|
心中的疑惑
- 在终端里快速生成大量随机数的最佳实践是什么?
gorm 链接 MySQL 处理 Error 1390 错误
我在公司负责的项目中使用了 gorm, 有一次 批量插入数据时遇到了 1390 :too many placeholders
所以我不得不减少数据量,为了解决问题将代码这样修改:
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
|
import(
gmysql "github.com/go-sql-driver/mysql"
)
type Transactions []Transaction
func (ts Transactions) Insert() error {
if len(ts) == 0 {
return nil
}
err := db.Clauses(clause.OnConflict{
DoNothing: true,
}).Create(&ts).Error
if err == nil {
return nil
}
var mysqlErr *gmysql.MySQLError
if errors.As(err, &mysqlErr) && mysqlErr.Number == 1390 {
mid := len(ts) / 2
if err := ts[:mid].Insert(); err != nil {
return err
}
if err := ts[mid:].Insert(); err != nil {
return err
}
return nil
}
return err
}
|
https://stackoverflow.com/questions/18100782/import-of-50k-records-in-mysql-gives-general-error-1390-prepared-statement-con