普拉多VX

人生一路,不问来时,不知归期

0%

Write写入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20


func write(){
//os.O_TRUNC 会清空原来的文件
//os.O_APPEND 在原来文件中追加
fileObj,err:=os.OpenFile("xx.txt",os.O_CREATE|os.O_WRONLY|os.O_APPEND,0644)

if err !=nil{
fmt.Printf("open file failed, err:%v\n",err)
return
}

str := "成都"
fileObj.Write([]byte(str))
fileObj.WriteString("\n")
fileObj.WriteString("哈哈哈")
fileObj.WriteString("\n")

defer fileObj.Close()
}

Bufio写入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

func writeByBufio(){
fileObj,err:=os.OpenFile("xx.txt",os.O_CREATE|os.O_WRONLY|os.O_APPEND,0644)

if err !=nil{
fmt.Printf("open file failed, err:%v\n",err)
return
}

defer fileObj.Close()
writer := bufio.NewWriter(fileObj)
writer.WriteString("xxxxxx") //将内容写入到缓冲区
writer.Flush() //将缓存区内容写入磁盘


}

Ioutil写入

1
2
3
4
5
6
7
8
9
func writeByIoutil(){
str := "测试123554434"
err:=ioutil.WriteFile("./xx.txt",[]byte(str),0644)
if err != nil{

fmt.Printf("write file failed,err:%v\n",err)
return
}
}

golang文件读取3种方式

  • 1.按行读取
  • 2.读取整个内容
  • 3.分段读取

打开文件

打开文件使用os模块,使用os.Open(文件路径)

1
os.Open("./xx.txt")

参考实例

1
fileObj,err := os.Open("./test.txt") //相对目录打开文件

按行读取文件

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
32
33
package main

import (
"bufio"
"fmt"
"io"
"os"
)

func main(){
fileObj,err:=os.Open("./xx.txt")

if err !=nil{
fmt.Printf("read file failed,err:%v\n",err)
return
}

defer fileObj.Close() //defer关闭文件
s :=bufio.NewReader(fileObj)

for { //for循环逐行读取文件
reader,err := s.ReadString('\n') //指定文件每行的换行符号

fmt.Print(reader) //打印内容

if err == io.EOF{ //如果是文件结尾会抛EOF错误

break
}

}

}

读取整个文件

使用ioutil来读取整个文件内容,如果文件过大则不建议使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package main

import (
"fmt"
"io/ioutil"
)

func main(){
content,err:=ioutil.ReadFile("./xx.txt")
if err !=nil{
fmt.Printf("read file failed, err:%v\n", err)
return
}
fmt.Print(string(content)) //将内容转成string输出
}

分块读取文件

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
32
33
34
35
36
37
package main

import (
"fmt"
"io"
"os"
)

func main(){

fileObj,err := os.Open("./xx.txt") //相对目录打开文件

if err != nil{
fmt.Printf("open file failed,err:%v\n",err)
return
}

defer fileObj.Close() //关闭文件

for {

var tmp = make([]byte,128) //按字节数读取文件内容
n,err:=fileObj.Read(tmp)

if err == io.EOF{
fmt.Print(string(tmp[:n]))
return
}

if err != nil{
fmt.Printf("read from file failed, err:%v\n",err)
}

fmt.Print(string(tmp))
}

}

panic

panic主要用于作异常处理,是一个内建的停止控制流函数。相当于其它编程语言的抛异常。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

package main

import "fmt"

func getname() string{

return "name"
}

func main(){


fmt.Println("starting......!")

a :=23
if a == 23 {
panic("crash") //手动触发宕机
}
fmt.Println(getname())


}

recover

recover是内建函数,可以让进入宕机流程恢复回来,同时recover仅在defer中有效。

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
package main

import "fmt"

func getname() string{

return "name"
}

func main(){

defer func(){
err:=recover()
if err !=nil{
fmt.Println("触发宕机捕获异常:",err)
}
}() //recover只能在defer中

fmt.Println("starting......!")

a :=23
if a == 23 {
panic("crash") //手动触发宕机,后面的代码不会执行
}
fmt.Println(getname())


}

Golang 指针

指针就是一个变量,用于存储另一个变量的内存地址。这个内存地址往往是在内存中存储的另一个变量的值的起始位置。

指针特点

  • 默认值是nil,没有NULL常量
  • 操作符”&”用于获取变量地址,”*” 通过指针目标对象
  • 不支持指针运算

实例
声明一个变量x 并且设置值为1, 声明变量p 值为x的地址

1
2
3
4
5
6
7
8
9
10
11
12
13

package main

import "fmt"


func main(){
x := 1
p := &x //&获取x的地址
fmt.Println(p) //打印地址
fmt.Println(x,*p) //*p获取x所对应的值

}

以上输出结果为

1
1 1

通过指针修改变量的值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

package main

import "fmt"


func main(){
x := 1
p := &x //&获取x的地址
fmt.Println(x,*p) //*p获取x所对应的值

*p = 3 //修改变量的值

fmt.Println(x,*p)

}

输出结果为

1
3 3   //*p指向x 修改*p等于修改x

指针作用函数参数

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

package main

import "fmt"


func incr(p,b *int) {
*p++
*b=*b+30
}


func main(){
x := 1
c :=2
p := &x //&获取x的地址
fmt.Println(x,*p) //*p获取x所对应的值

*p = 3 //修改变量的值

fmt.Println(x,*p)


//将x地址传递给incr函数,然后返回变量修改
incr(&x,&c)
fmt.Println(x,c)

}

输出结果为

1
2
3
1 1
3 3
4 32

new和make

在golang中,make和new都是分配内存的,但是它们之间还是有些区别的,只有理解了它们之间的不同,才能在合适的场合使用。

简单来说 new只是分配内存,不初始化内存,而make即分配又初始化内存。所谓的初始化就是给类型赋初值,比如字符为空,整型为0, 逻辑值为false等。

备注

  1. make 仅用来分配及初始化类型为 slice、map、chan 的数据。new 可分配任意类型的数据.
  2. new 分配返回的是指针,即类型 *Type。make 返回引用,即 Type.
  3. new 分配的空间被清零, make 分配空间后,会进行初始化.

new返回的是一个指针

1
2
3
name := new(string)
server := new(string)
fmt.Println(name,server) //输出0xc0000421f0 0xc000042200

golang 接口

接口可以理解为某一个方面的抽象,可以是多对一的(多个类型实现一个接口),是多态的体现。

接口是一组包含方法名、参数、返回值的未具体实现的方法的集合。

实现方式

1
2
3
4
type interfaceName interface { 
// 方法列表
GetName() string
}
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
package main

import "fmt"

type interfaceName interface {
// 方法列表
GetName() string
GetAge() int
}

type Name struct { //定义结构体
name string
age int
}

func (s Name) GetName() string { //实现两个方法
return s.name
}

func (s Name) GetAge() int {
return s.age
}

func main(){

s := Name{"roddy",28} //声明一个对象
a := s.GetName()
fmt.Println(a,s.GetAge(),s.age) //调用对象中的方法


}

空接口

空接口就是不包含任何方法的接口。所有类型都实现了空接口,并且空接口可以存任何类型的数据。

1
2
3
4
5
var allData interface{}

allData = 234

fmt.Println(allData,reflect.TypeOf(allData))

覆盖变量值

1
2
3
4
5
6
7
8
9
10
11
12
13
var allData interface{}
var allList interface{}

allData = 234

fmt.Println(allData,reflect.TypeOf(allData))

m :=123
ms := "check all"

allList = m
allList = ms //可覆盖此前的变量值
fmt.Println(allList) //此时的输出就为check all

接口零值

接口的默认值为nil

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main

import (
"fmt"

)



type DefaultI interface {
GetName()
}

func main(){

var mk DefaultI
fmt.Println(mk) //接口的默认值为nil

}

Ubuntu 16.4 Nginx设置访问密码

1.安装apache2-utils

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
root@rodddy:/# apt-get install apache2-utils
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
libopts25 python-meld3 python-pkg-resources
Use 'apt autoremove' to remove them.
The following additional packages will be installed:
libapr1 libaprutil1
The following NEW packages will be installed:
apache2-utils libapr1 libaprutil1
0 upgraded, 3 newly installed, 0 to remove and 199 not upgraded.
Need to get 82.1 kB/245 kB of archives.
After this operation, 810 kB of additional disk space will be used.
Do you want to continue? [Y/n] y

2.创建用户名和密码,并把用户名和密码保存到指定文件中

创建用户admin 保存的文件位置/usr/local/src/nginx/passwd

1
2
3
4
root@roddy:~# htpasswd -c /usr/local/src/nginx/passwd admin
New password:
Re-type new password:
Adding password for user admin

3.修改nginx配置文件

1
2
3
4
5
6
7
8
9
10
11
12
server {
listen 80;
server_name localhost;
.......

#新增两行
auth_basic "Please input password"; #这里是提示信息
auth_basic_user_file /usr/local/src/nginx/passwd;

location /{
.......
}

4.先检查下配置文件

1
2
3
4
root@roddy:~# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
root@roddy:~#

5.重新加载配置文件

1
root@roddy:~# systemctl  reload nginx.service

备注:

htpasswd命令选项参数说明

-c 创建一个加密文件
-n 不更新加密文件,只将htpasswd命令加密后的用户名密码显示在屏幕上
-m 默认htpassswd命令采用MD5算法对密码进行加密
-d htpassswd命令采用CRYPT算法对密码进行加密
-p htpassswd命令不对密码进行进行加密,即明文密码
-s htpassswd命令采用SHA算法对密码进行加密
-b htpassswd命令行中一并输入用户名和密码而不是根据提示输入密码
-D 删除指定的用户

创建用户

1
root@roddy:~# htpasswd -c /usr/local/src/nginx/passwd admin

添加用户(在原文件下)

1
root@roddy:~# htpasswd  -b /usr/local/src/nginx/passwd  roddy 123456

删除用户

1
root@roddy:~# htpasswd -D /usr/local/src/nginx/passwd admin

修改密码

1
root@roddy:~# htpasswd -b /usr/local/src/nginx/passwd admin 12345678

1.进入到源列表文件目录

1
root@roddy:/# cd  /etc/apt/sources.list.d/

2.编辑源列表文件

1
root@roddy:/etc/apt/sources.list.d/# vim  nginx.list

3.删除或者注释其中源即可

golang 结构体

什么是结构体?

结构体可以存不同项定义的数据类型,它是一组数据的集合。我们可以将数据按指定的格式进行保存和读取。

下面以一台服务器参数作为例子:

服务器名: ServerName
CPU: CPU
内存: Mem
硬盘: Disk
IP地址: IP

定义一个SERVER的结构体:

1
2
3
4
type 结构体名 struct {
member string // 成员及成员类型

}
1
2
3
4
5
6
7
type SERVER struct {
ServerName string
CPU int
MEM int
DISK int
IP string
}

创建结构体

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
package main

import "fmt"

type SERVER struct {
ServerName string
CPU int
MEM int
DISK int
IP string
}



func main(){
//{HOSTNAME 4 8 500 200.2.14.2} 创建一个结构体,并赋予值
fmt.Println(SERVER{"DBSERVER",4,8,500,"200.2.14.2"})


//也可以使用KEY->VALUE格式定义一个结构体
serverInfo := SERVER{ServerName:"web server",CPU:4,MEM:8,DISK:200,IP:"47.23.23.1"}

fmt.Println(serverInfo.IP)

//如果没有赋值,将使用缺省默认值
webInfo := SERVER{ServerName:"web 2server",DISK:200,IP:"47.23.23.2"}

fmt.Println(webInfo)


}

访问成员

使用方法为struct.xxxx 赋值或者访问

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
package main

import "fmt"

type SERVER struct {
ServerName string
CPU int
MEM int
DISK int
IP string
}


func main(){
//赋值
newServer.ServerName = "new server"
newServer.DISK = 500
newServer.MEM = 4
newServer.CPU = 2
newServer.IP = "2.2.3.2"

//读取

fmt.Printf("服务器名%s,磁盘:%d,内存:%d,CPU:%d,IP:%s", newServer.ServerName,
newServer.DISK, newServer.MEM,
newServer.CPU, newServer.IP,
)
}

结构体传递

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
func GetServerInfo(server SERVER){
fmt.Printf("server ip:%s\n",server.IP) //访问结构体中的成员信息
}

func main() {


var newServer SERVER

//赋值
newServer.ServerName = "new server"
newServer.DISK = 500
newServer.MEM = 6
newServer.CPU = 2
newServer.IP = "2.2.3.2"

GetServerInfo(newServer) //将结构体传递给GetServerInfo函数

}

结构体指针

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
//结构体做为参数传递,如果要修改数据,需要用结构体指针方式
func changeServer(server *SERVER){
if server.MEM > 4{
server.MEM = 8
}
}




var newServer SERVER

//赋值
newServer.ServerName = "new server"
newServer.DISK = 500
newServer.MEM = 6
newServer.CPU = 2
newServer.IP = "2.2.3.2"

changeServer(&newServer) //结构体指针传递

//读取

fmt.Printf("服务器名%s,磁盘:%d,内存:%d,CPU:%d,IP:%s", newServer.ServerName,
newServer.DISK, newServer.MEM,
newServer.CPU, newServer.IP,
)
//结果server.MEM =8

一直在做python后端开发,之前一直会遇见django 和vue结合后的垮域问题。现特记录下解决方法

什么是跨域

解释来源链接:https://www.jianshu.com/p/3961366f9ce9

跨域是指一个域下的文档或脚本试图去请求另一个域下的资源,这里跨域是广义的。
其实我们通常所说的跨域是狭义的,是由浏览器同源策略限制的一类请求场景。

什么是同源策略?

同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源是指”协议+域名+端口”三者相同,即便两个不同的域名指向同一个ip地址,也非同源。

同源策略限制以下几种行为:

  • Cookie、LocalStorage 和 IndexDB 无法读取
  • DOM 和 Js对象无法获得
  • AJAX 请求不能发送

1.安装django-cors-headers

1
pip install django-cors-headers

2.配置settings.py文件

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

//将corsheaders添加到apps中
INSTALLED_APPS = [
...
'corsheaders',
....
]



#跨域增加忽略
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True

CORS_ORIGIN_WHITELIST = (
'http://localhost:8000',
'http://127.0.0.1:8000',
)

CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
'VIEW',
)

CORS_ALLOW_HEADERS = (
'XMLHttpRequest',
'X_FILENAME',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
'Pragma',
)


MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware', //将corshaders添加到common之上
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django_user_agents.middleware.UserAgentMiddleware',
]

3.重新启动项目即可

匿名函数

匿名函数就是一个没有名字的函数,只有函数体,函数可以被作为一种类型被赋值给函数类型的变量,匿名函数往往是以变量方式被传递。

匿名函数的定义

1
2
3
4
func (参数列表)(返回值列表) {
函数体

}

调用方式

  • 声明时直接调用
  • 赋值给变量进行调用

实例:匿名函数调用

1.声明时直接调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

package main

import "fmt"

//func (参数列表)(返回值列表) {
// 函数体
//
//}

func main(){

func (userId,age int){
fmt.Printf("用户ID:%d,年龄:%d\n",userId,age)
}(1,24) //声明时直接调用

}

2.赋值给变量调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main

import "fmt"

//func (参数列表)(返回值列表) {
// 函数体
//
//}

func main(){

result :=func (a,b int )int{
return a+b
}

fmt.Println(result(2,6)) //直接赋值给result,然后调用即可

}

全局匿名函数

以上我们的函数调用都是一个局部调用,如何进行全局调用呢,可以将匿名函数赋值给一个全局变量,就可以程序中使用了。

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
32
33
34
35
36
37
38
39
40
package main

import "fmt"
//全局匿名函数
var (
getResult = func(a,b int,meth_type string) int {
if meth_type == "+" {
return a + b
}else if meth_type == "-" {

return a -b
}else if meth_type == "*" {
return a *b
}else{
return 1
}
}

)


func funcMethod(a,b int)(int,int,int){

//加法
add := getResult(a,b,"+") //函数中调用全局匿名函数
//减法
sub := getResult(a,b,"-")
//乘法
mul := getResult(a,b,"*")

return add,sub,mul

}

func main(){

fmt.Println(funcMethod(1,23))


}

函数闭包

闭包就是一个函数与其相关的引用环境组成的一个整体。它本质上是一个函数,但是这个函数会用于函数外的变量,它们共同组成的整体称为闭包。

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

package main

import "fmt"

//累积数据,返回值是一个func
func addUpper() func(int) int {
n := 10
n -= 1
c := 20

return func (x int) int {
c -= 2
fmt.Println(c)

n = n +x
return n
}
}

func main(){

t := addUpper() //t变量用于接收返回的函数

fmt.Println(t(5))

}

defer(延迟函数)

defer用来声明一个延迟函数,并把这个函数放到一个栈上,当外部的包含方法return之前,放回参数到调用方法之前调用。通常用于做资源释放,比如关闭io等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package main

import "fmt"

//defer 用于程序释放资源,用于延迟操作。


func f() {
//延迟调用,采用FILO(先进后出原则) 延迟函数执行按后进先出顺序执行,即先出现的defer后执行
i:=0
defer fmt.Println(i)
i++
defer fmt.Println(i)
return

}

func main() {
f() //结果是1 后是0
}

关闭文件io

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
func closeFile(){

f, _ := os.Open("Godefer.go")

//将文件名交给带有缓存的IO Reader
r := bufio.NewReader(f)

for {
line, err := r.ReadString('\n') //指定分割符
//判断是否是文件结尾
if err == io.EOF {
break
}
fmt.Print(line)
}

defer f.Close()

}

函数作用域

1.在函数内部声明/定义的变量叫局部变量,作用域仅限于函数内部

1
2
3
4
func change(){  
a := 124 //在change函数体内部声明的变量叫局部变量
fmt.Println(a)
}

2.函数外部声明/定义的变量叫全局变量,作用于在整个包内。如果变量的首字母大写,则可以外部访问调用(作用域为整个程序)

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
package main

import "fmt"

// 外部变量
var (
Name string = "default"
Age int64

)
func change(){
//修改的就是全局变量
Name = "1234"

}

func main() {

Age = 100
fmt.Println(Name,Age)

change()
Age = 100
fmt.Println(Name,Age)

}