#823 代码中的 TODO 注释
开发者 2022-08-19《Stop Using TODO for Everything》建议采用更加明确的标记来注释代码:
FIXME
/BUG
需要修复(缺陷)CHECKME
/REVIEW
需要审查DOCME
需要文档TESTME
需要测试HACK
/OPTIMIZE
需要优化
我就是喜欢在代码中写 TODO,以后可以照着这个建议搞些花样。
coding in a complicated world
《Stop Using TODO for Everything》建议采用更加明确的标记来注释代码:
FIXME
/BUG
需要修复(缺陷)CHECKME
/REVIEW
需要审查DOCME
需要文档TESTME
需要测试HACK
/OPTIMIZE
需要优化我就是喜欢在代码中写 TODO,以后可以照着这个建议搞些花样。
双因素 / 多因素认证,就是指处理密码之外,再加一些辅助手段用来加强认证。
常见的 2FA 方式:
应该有人脸,指纹,声纹,虹膜等方式的组合(甚至在异形 4 中有吹气的方式),这些在我们的数字生活中这些认证方式多少都有一些体验吧。
事先给客户一张密码表,然后需要的时候要求客户按要求输入指定位置的数字用来验证身份。
原理应该和微信让用户指认哪个头像是自己的好友一样。
银行的 U 盾
一次性密码,One Time Password
TOTP 的全称是"基于时间的一次性密码"(Time-based One-time Password)。它是公认的可靠解决方案,已经写入国际标准 RFC6238。
不知道密码学上是什么原理,只知道可以每分钟生成一个 6 位密码。只要双方算法和密钥一致,就能实现认证。
软件的,谷歌身份验证器,微软身份验证器,这种。
硬件的,银行的动态口令,早些年网易的将军令,这种。
FIDO(Fast IDentity Online,线上快速身份验证)联盟是成立于2012年7月的行业协会。其宗旨是为解决强制认证设备的交互性和用户面临大量复杂的用户名和密码。
主要是一些巨头(Google,微软)和搞 2FA 硬件设备的厂商组件的联盟,目标是通过一个标准,让符合标准的技术能够到处适用,用起来更方便、更安全。
官方定义的愿景是 “减少世界对密码的依赖”。
协议:
说明:
阿里巴巴的 IFAA
腾讯的 TUSI
今天的《科技爱好者周刊(第 219 期):如何防止帐号被黑》中说:
上周有一起安全事件。两家著名的美国互联网公司----Twillo 和 Cloudflare----被攻击了,前者还被攻破了。
手段还是钓鱼,不止钓密码,也钓了 TOTP 验证码。所以阮一峰在文章中的意思是,物理密钥会更安全。
这么说确实有道理,其实我好多次都想买一个,就是太贵,两三百。
阮一峰还提到,有部分实践(Web Authentication)在尝试采用本地设备的认证手段作为第二因子,比如手机和笔记本上的指纹识别和人脸识别。
还是希望有厂商能够推出廉价一些的 Key。
# 安装 <https://winget.run/pkg/MariaDB/Server>
winget install mariadb.server
# 这一步应该是安装程序自动执行了
# 但是没有自动安装服务,也没有为 root 配置密码
# 有很多参数,可以参考 `mysql_install_db --help`
# mysql_install_db
# 安装服务
& 'C:\Program Files\MariaDB 10.8\bin\mysqld.exe' --install-manual MariaDB
# 根据资料,可以指定配置文件,但是我没有这么操作过,都是用的默认值:
# --defaults-file=D:\DB02\my.ini
# 如果启动另一个服务进程,记得在配置文件中指定新的 datadir
# 启动服务
# services.msc 中手动启动服务,或者,
# 管理员权限启动命令行,然后执行:
net start MariaDB
sc start MariaDB
# 停止服务
net stop MariaDB
sc stop MariaDB
# 删除服务
sc delete MariaDB
C:\>dir "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\MariaDB 10.8 (x64)"
驱动器 C 中的卷是 Windows
卷的序列号是 56D1-41EB
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\MariaDB 10.8 (x64) 的目录
2022/08/15 21:33 <DIR> .
2022/08/15 21:33 <DIR> ..
2022/08/15 21:33 1,154 Command Prompt (MariaDB 10.8 (x64)).lnk
2022/08/15 21:33 909 Database directory (MariaDB 10.8 (x64)).lnk
2022/08/15 21:33 1,000 Error log (MariaDB 10.8 (x64)).lnk
2022/08/15 21:33 944 HeidiSQL.lnk
2022/08/15 21:33 1,000 my.ini (MariaDB 10.8 (x64)).lnk
2022/08/15 21:33 1,208 MySQL Client (MariaDB 10.8 (x64)).lnk
6 个文件 6,215 字节
2 个目录 309,073,027,072 可用字节
默认的 MariaDB 安装在 C:\Program Files\MariaDB 10.8
,数据在 data 子目录,配置文件 my.ini
就在 data 子目录。
PS:震惊,我才发现 MariaDB 自带了一个 heidisql!!!
这个时候可以直接通过 root 登录上去,不需要密码。
搜索 mysql.user 可以发现:
MariaDB [(none)]> select host, user, password, plugin, authentication_string from mysql.user;
+-----------+-------------+----------+-----------------------+-----------------------+
| Host | User | Password | plugin | authentication_string |
+-----------+-------------+----------+-----------------------+-----------------------+
| localhost | mariadb.sys | | mysql_native_password | |
| localhost | root | | | |
| victus | root | | | |
| 127.0.0.1 | root | | | |
| ::1 | root | | | |
+-----------+-------------+----------+-----------------------+-----------------------+
5 rows in set (0.001 sec)
mariadb-admin status -uroot
mysql -uroot
# 设置密码
# 如果忘记密码登录不进去了,怎么重置,这是另一个话题了
& 'C:\Program Files\MariaDB 10.8\bin\mysqladmin.exe' -uroot password 123456
SHOW VARIABLES LIKE "%char%";
Variable_name | Value |
---|---|
character_set_client | utf8mb4 |
character_set_connection | utf8mb4 |
character_set_database | latin1 |
character_set_filesystem | binary |
character_set_results | utf8mb4 |
character_set_server | latin1 |
character_set_system | utf8mb3 |
character_sets_dir | C:\Program Files\MariaDB 10.8\share\charsets\ |
SHOW VARIABLES LIKE "%system%";
SHOW VARIABLES LIKE "%log%";
SHOW VARIABLES LIKE "%version%";
SHOW VARIABLES LIKE "%dir%";
SHOW CHARACTER SET;
SHOW COLLATION;
来自相同站点的更多内容
也行,其实就是按域名搜索Windows 11 右键菜单样式调整了,像是变成两级了,我经常需要点击 “显示更多选项”(Show more options),感觉很麻烦,今天在网上找到了解决办法:
# enable
reg add "HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32" /f /ve
# disable
reg delete "HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}" /f
# restart explorer
taskkill /f /im explorer.exe
start explorer.exe
regExport.bat
:
reg export HKEY_CURRENT_USER\Software\SimonTatham\PuTTY "%USERPROFILE%\Desktop\puttySettings.reg"
reg export HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\Sessions "%USERPROFILE%\Desktop\puttySessions.reg"
或者:
regedit /e "%USERPROFILE%\Desktop\puttySettings.reg" HKEY_CURRENT_USER\Software\SimonTatham\PuTTY
regedit /e "%USERPROFILE%\Desktop\puttySessions.reg" HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\Sessions
main.go
:package main
import (
"fmt"
"os"
"github.com/spf13/pflag"
"github.com/spf13/viper"
)
func main() {
// 1. 设置 Viper 配置
viper.SetConfigName("config") // 配置文件名(不带后缀)
viper.AddConfigPath(".") // 配置文件路径
viper.SetConfigType("yaml") // 配置文件类型
viper.AutomaticEnv() // 自动读取环境变量
// 2. 设置命令行参数
pflag.String("name", "", "project name")
pflag.String("host", "", "host address")
pflag.String("port", "", "port number")
pflag.String("config", "./config.yaml", "config file") // 配置文件参数
pflag.Parse()
viper.BindPFlags(pflag.CommandLine) // 将命令行参数绑定到 Viper
// 3. 读取配置文件
if configFile := viper.GetString("config"); configFile != "" {
fmt.Println(configFile)
if err := viper.ReadInConfig(); err != nil {
fmt.Fprintf(os.Stderr, "读取配置文件失败:%v\n", err)
os.Exit(1)
}
}
// 4. 读取配置项
projectName := viper.GetString("name")
port := viper.GetInt("port")
fmt.Printf("ProjectName: %s, Port: %d\n", projectName, port)
}
config.yaml
:name: hello
host: 10.10.0.172
port: 9090
type RemoteProvider interface {
Set(key string, value []byte) error
Watch(key string) (chan *RemoteResponse, chan error)
Get(key string) ([]byte, error)
}
通过对 key 做哈希,来实现 Redis 服务器的分片。
用这个例子来演示这个小库的用法:
package main
import (
"crypto/rand"
"encoding/base64"
"fmt"
"log"
"time"
"github.com/go-redis/redis"
"github.com/serialx/hashring"
)
func RandomString(length int) (string, error) {
b := make([]byte, length)
_, err := rand.Read(b)
if err != nil {
return "", err
}
return base64.URLEncoding.EncodeToString(b)[:length], nil
}
func main() {
redisServers := map[string]int{
"redis1:6379": 200,
"redis2:6379": 100,
}
redisClients := []*redis.Client{}
for uri, _ := range redisServers {
redisClients = append(redisClients, redis.NewClient(&redis.Options{Addr: uri}))
}
log.Println(redisServers)
ring := hashring.NewWithWeights(redisServers)
stat := map[string]int{}
for uri, _ := range redisServers {
stat[uri] = 0
}
for i := 0; i < 100; i++ {
randstr, _ := RandomString(8)
key := "test:randkey:" + randstr
node, ok := ring.GetNode(key)
if !ok {
log.Panicf("cannot assign a redis client by key: %#v", key)
}
log.Printf("%s -> %s", key, node)
stat[node]++
var client *redis.Client
for _, _client := range redisClients {
if node == _client.Options().Addr {
client = _client
break
}
}
if client == nil {
log.Panicf("redis client assigned error: %#v", node)
}
client.Set(key, 1, time.Minute)
}
fmt.Println(stat)
}
https://github.com/bits-and-blooms/bloom/v3
package main
import (
"fmt"
"github.com/bits-and-blooms/bloom/v3"
)
func main() {
filter := bloom.New(1000000, 5)
filter.Add([]byte("apple"))
filter.Add([]byte("banana"))
filter.Add([]byte("orange"))
fmt.Println(filter.Test([]byte("apple")))
fmt.Println(filter.Test([]byte("banana")))
fmt.Println(filter.Test([]byte("orange")))
fmt.Println(filter.Test([]byte("grape")))
fmt.Println(filter.Test([]byte("watermelon")))
}
setup_module(module)
/ teardown_module(module)
引入包的时候执行setup_function(function)
/ teardown_function(function)
setup()
/ teardown()
测试模块载入的时候执行setup_class(cls)
/ teardown_class(cls)
setup_method(self, method)
/ teardown_method(self, method)
setup(self)
/ teardown(self)
nose 语法,会被上面两个方法覆盖Supported nose Idioms
setup()
andteardown()
at module/class/method level: any function or method calledsetup
will be called during the setup phase for each test, same forteardown
.SkipTest
exceptions and markers- setup/teardown decorators
__test__
attribute on modules/classes/functions- general usage of nose utilities