isatty
在终端中,许多程序会将输出进行配色等的美化。但当输出被重定向到文件中时,我们肯定不希望这些控制字符被写入文件。所以一些程序会使用 isatty
判断当前得标准输出是不是连接到了终端上,从而自动使用合理的输出方式。
一个 python 的 demo 如下
1 | import os |
当标准输出在终端中且没有重定向时,会输出 tty find
,否则输出 No tty
1 | ➜ python tty_test.py |
在终端中,许多程序会将输出进行配色等的美化。但当输出被重定向到文件中时,我们肯定不希望这些控制字符被写入文件。所以一些程序会使用 isatty
判断当前得标准输出是不是连接到了终端上,从而自动使用合理的输出方式。
一个 python 的 demo 如下
1 | import os |
当标准输出在终端中且没有重定向时,会输出 tty find
,否则输出 No tty
1 | ➜ python tty_test.py |
在使用 virtualbox guest windows 安装 office 时,虚拟机会在安装程序启动时卡死。经过搜索找到了这篇讨论,其中指出 windows10 guest 需要打开虚拟机的 PAE/NX 选项。经过尝试打开该选项之后就可以正常安装 office。
不存在,至少在 C 语言标准中是这样。这里的解释非常清楚。所以如果需要在多个文件中声明同一个变量,稳妥的方法就是只在一个地方定义,其他地方显式使用extern
修饰。
众所周知,比特币网络以及其他使用 PoW 的区块链网络都通过挖矿保证网络的安全性。其原理大致就是通过算力的分散性实现区块产生能力的分散,从而避免网络被少数攻击者操纵。
进一步地,比特币网络使用的是基于双 SHA256 的碰撞的 PoW,矿工需要得到一个拥有小于网络要求的双 SHA256 值的区块,这样的区块可以被网络接受,矿工也会获得对应的奖励。由于(目前)没有高效的双 SHA256 的碰撞算法,唯一的方法就是暴力尝试。因此,比特币挖矿就是在算大量区块的双 SHA256 值,直到找到满足网络要求的区块。
到这里,我们已经解决了题目中的问题,本文也就完结了。接下来的问题是:这些允许矿工枚举的区块是怎么产生的。容易想象,作为包含了交易信息的区块,其中的大部分内容应该是固定的,那么一个比较合理的方法是设计一个独立的字段用于挖矿。比特币的区块结构中也确实设计了一个 4 字节的 nonce 字段用于矿工挖矿。
到这里,我们又解决了前面提出的问题,本文再一次完结了。用脚趾头数一下就可以发现,4 字节的 nonce 在现在根本不够产生足够挖矿的区块。现在一台比特币矿机的算力可能都有数十乃至数百 T,一秒钟就能把整个 nonce 字段枚举很多遍了。因此,仅仅使用 nonce 进行挖矿是完全不够的。因此,矿工还需要在其他的位置进行枚举。
在这种情况下,矿工将目光转向了 coinbase 交易,coinbase 交易是矿工构造的为自己提供挖矿奖励的交易。相比于其他交易,coinbase 交易既没有资金输入,也不需要签名。因此,coinbase 交易被规定在签名位置可以放指定前缀的任意值(bip34要求),而交易信息会通过一个称为 Merkle Tree 的结构打包到区块中,从而修改 coinbase 交易可以改变区块的哈希值,矿工可以修改这里的值来得到足够的可枚举范围。(同时这里往往也会放一些矿场信息之类的私货)
https://learn.saylor.org/mod/book/view.php?id=36375&chapterid=19428
https://learnmeabitcoin.com/technical/coinbase-transaction#footnote-messages
(上一次配 vim 还是上大学之前,转眼就快本科毕业了。)
这次主要是把一部分 .vimrc
中的配置迁移到 neovim 的 lua 风格配置上,同时把一部分插件迁移到 neovim 的生态中。
配置主要存放在 ~/.config/nvim
,目录结构大致为
1 | ├── init.lua |
其中 core
中存放全局配置,plugins
中存放插件相关配置,init.lua
中引用各个配置,因此后面每个文件配置时都需要在 init.lua
中 require
。
为了配置迁移的平滑性,先在 init.lua
中加入下面的代码,使其读取原本的 .vimrc
文件
1 | vim.cmd [[ |
在 core
文件夹中,创建 options.lua
用于配置 neovim 的选项,我的配置如下
1 | -- 基础配置 |
在 core
文件夹中,创建 keymaps.lua
用于配置键位映射,我的配置如下
1 | -- 按键映射 |
上面这些基本是从 .vimrc
中直接翻译过来
我原本使用 plugged
进行插件管理,这次将新的插件使用 packer
配置,之后会把 plugged
中的插件逐步替换和迁移过来。
在 plugins
文件夹中创建 packer-setup.lua
用于 packer
的自动安装。我这里使用的安装目录是 ~/.local/share/nvim/site/pack/packer
,后面通过 packer
安装的插件也会存放在这个目录。
1 | local packer_setup = {} |
在 plugins
文件夹中创建 packer.lua
用于 packer
的插件管理。安装插件只需要在这里添加 use
语句。
1 | -- 保存本文件时自动更新插件 |
neovim 的主要特性之一就是添加了对 Language Server Protocol 的原生支持,我也把原本基于 YouCompleteMe 的补全迁移到 Nvim LSP client 上。用到的插件主要有 nvim-lspconfig
、nvim-cmp
、cmp-nvim-lsp
,还有一些其他的插件提供辅助功能,具体可以看上面的插件列表。我尝试了 LuaSnip
,但是感觉不如一直使用的 ultisnips
顺手,所以目前继续使用 ultisnips
。LSP 协议支持自定义 style 的 formatting,但 clangd 对这个特性的支持并不好(来源: https://clangd.llvm.org/features#formatting),因此我保留了原本使用的 vim-autoformat 插件用于 formatting。
主要的配置文件就是配置 LSP 的 lspconfig.lua
和配置补全的 nvim-cmp.lua
,其中 LSP 的键位基本是默认的,补全则根据以前使用的键位做了一些配置
lspconfig.lua
1 | -- Mappings. |
nvim-cmp.lua
1 | -- ultisnips setup |
添加了在打开目录时调用 nvim-tree
的 autocmd
1 | -- disable netrw |
配置了高亮、折叠和彩虹括号(需要 p00f/nvim-ts-rainbow
)
1 | require'nvim-treesitter.configs'.setup { |
使用了状态栏 nvim-lualine/lualine.nvim
和配色 rebelot/kanagawa.nvim
,我使用了一个 appearance.lua
文件管理这两个插件的配置
1 | -- 配色 |
Hello World