Random walk to my blog

my blog for sharing my knowledge,experience and viewpoint

0%

本文基于Golang 1.14

用法以及注意事项

Go blog中介绍了map的基本用法。在Go blog之外,这里介绍几个值得注意的点。

map作为集合(set)

Golang中,没有集合的类型。所以一般是把map当做集合来用。
看下面例子

1
2
3
4
5
6
7
func main(){
// 预分配内存
set := make(map[int]bool,10)
for i := 0; i < 10; i++{
set[i] = true
}
}

其实对例子进行优化,不使用bool类型,来节省空间。

1
2
3
4
5
6
7
8
9
10
11
12
func main(){
// 预分配内存
set := make(map[int]struct{},10)
for i := 0; i < 10; i++{
set[i] = struct{}{}
}
_,ok := set(1)
// 存在
if ok {

}
}

使用空的结构体struct{},会比使用byte节省空间。经过编译器的优化,struct{}指向runtime.zerobase,不占用空间。

阅读全文 »

defer语句是在函数返回之前,执行一段代码,正如在Golang 规范描述的:

Instead, deferred functions are invoked immediately before the surrounding function returns, in the reverse order they were deferred.(defer函数在它被返回之前进行调用,以defer声明的逆序调用)

阅读全文 »

基于Session的认证

HTTP协议是无状态(stateless)的,这意味着,如果在一个请求中,用户传递了用户名和密码,通过了我们的认证。在用户的下一个请求中,我们仍然不能识别这个认证通过的用户,还需要认证一遍,因为两次HTTP请求是没有关联。
为了解决这个问题,session,也就是基于cookie的认证产生了。

阅读全文 »

本文介绍一下OAuth(Open Authentication).

账号密码登录

当我们登录一个网站时,我们经常需要输入账号密码。

1
2
3
4
5
6
   网站                           数据库
+------------+ +------------------------+
| 账号 | --------------> | 对密码做散列(hash) |
| 密码 | <--session-- | 验证散列值 |
+------------+ | 在数据库中寻找信息 |
+-------------------------+
阅读全文 »

开发登录功能的时候,需要保存用户的密码。用户的密码一般不是明文(plain text),而是经过散列(hash)或者加密(encrypt)保存的。本文介绍几个常用的保存密码的算法。

考虑以下的User表。

1
2
3
4
5
6
7
CREATE TABLE `user`(
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
`account` VARCHAR(128) NOT NULL DEFAULT '' COMMENT '账号',
`password_hash` VARCHAR(1024) NOT NULL DEFAULT '' COMMENT '密码散列值',
`salt` VARCHAR(128) NOT NULL DEFAULT '' COMMENT '盐',
PRIMARY KEY(`id`),
)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='用户账号表';
阅读全文 »

在Golang的Web编程中,有时候我们创建了一个SQL的表,需要编写对应的结构体的代码。这是一项繁琐无聊的工作。本文介绍一种自动将创建表格的SQL语句转换成Golang的ORM结构体的代码,从而提高编程效率。代码来自于我的Github

例子

例子:下面是一个创建user表的sql语句

1
2
3
4
5
6
7
8
9
10
CREATE TABLE `USER`(
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'primary key',
`ip_address` INT NOT NULL DEFAULT 0 COMMENT 'ip_address',
`nickname` VARCHAR(128) NOT NULL DEFAULT '' COMMENT 'user note',
`description` VARCHAR(256) NOT NULL DEFAULT '' COMMENT 'user description',
`creator_email` VARCHAR(64) NOT NULL DEFAULT '' COMMENT 'creator email',
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'create time',
`deleted_at` TIMESTAMP NULL DEFAULT NULL COMMENT 'delete time',
PRIMARY KEY(`id`)
)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='user table';
阅读全文 »

1.如果内容能被转化为数字类型,尽量使用数字类型而不是字符类型

如果要保存IPv4地址,
反例

1
`ip_address` VARCHAR(15) NOT NULL

正例。

1
`ip_address` INT UNSIGNED NOT NULL

原因

  • 因为IPv4地址可以转化成一个int类型的十进制整数。转化方法:ip中的每一段转化为两位的十六进制整数。例如,192.160.98.123转化为十六进制数是,C0,A0,62,7B,C0A0627B转化为十进制数是3231736443。
    阅读全文 »