2023-09-23 07:12:58    72    0    0

工作满四年了,过去将近一年时间在凉屋的工作让我产生了极大的转变和技术成长,在进入凉屋之前,我的技术欠缺到了现在的我完全不敢相信的程度,但之前的工作也不是完全浪费时间,所以想记录一下自己工作以来的经历,以后尽可能地将尽可能多的经验转换为决策的依据。

关于在浪潮为什么换工作,是因为浪潮工资太低,周六甚至没有加班费,而加班强度一点也不低,老板“周一来讲讲周六为什么不加班”的言论让人非常不舒服,搬服务器、一根根内存条排查问题也不是一个亟需成长的程序员整天应该做的事情。在觉得自己没有任何留下去的理由后,经过朋友的推荐,去了华为 OD,至于为什么 OD 也去,是因为当时不知道 OD 代表什么,本来就比较佛系,不想在非技术领域探究太多,所以考虑到工资几乎是浪潮y8500块钱的两倍,还能换个领域扩展知识和见识,没有理由不去。现在想想当时如果还留在浪潮,可能还会有很长时间在免费加班做边缘的事情,这种情况是我一定会马上做出改变的。

不过在浪潮工作期间我也学到了很多知识,虽然没有在工作中用到太多,例如从校园走到职场的热情让我啃完了《C和指针》、《Linux应用程序设计》、《UNIX/LINUX shell 编程指南》这几本书,对 linux 应用编程的学习到了华为工作中还在持续发挥重要作用。在写操作系统安装、更新脚本的过程中熟练应用了 shell 编程,从计算机上电、到 BIOS/bootloader 工作、再到 linux 系统的启动流程能略懂一二,能够自己修改操作系统镜像也是一个让极客很满足的技能。

后来到了华为,在华为的第一份工作是消息队列的 demo 开发,用于5G消息,还学习负载均衡的理论知识,因为可能会做负载均衡的服务,但后来真正开始开发,则是5G消息的 MSRP 服务,简单来说就是应用层富文本的解析、转发服务,同时需要关注底层的 TCP + MSRP 协议栈。MSRP 服务的所有数据都存在内存中,包括会话、链路的池子,缓存+顺序处理的 MSRP 包消息队列。华为在将一些虚拟机时代的应用迁移到容器中,但这种迁移并不彻底,在华为有很多被称为大颗粒的服务,实际上就是将原来虚拟机上运行的单体应用打包到了容器中运行,只体现了容器镜像的开发/生产环境一致、快速部

2022-02-23 14:16:24    37    0    0

资源管理

  • 资源包括:
    • 内存(栈或堆)
    • 访问硬盘或其他介质(如网络)上的文件所需的文件句柄
    • 网络连接
    • 线程、锁、定时器和事务
    • 其他操作系统资源,如Windows的GDI(图形设备接)句柄
  • 处理资源时,需要在正常和异常分支都合理地进行资源释放(例如delete释放new创建的对象),但异常分支变多时,很可能忘记,任何一个分支只要有一个忘记释放,就会导致资源泄漏,对于生命周期长或快速分配很多资源的进程,资源泄漏是很严重的问题,还可能导致存在拒绝服务(DOS)攻击漏洞。
  • 一个解决方法就是在栈上创建对象,即不要创建对象的指针。

资源申请即初始化

  • 资源申请即初始化(Resource Acquisition is Initialization,RAII)是帮助我们安全处理资源的术语,该术语也被称为“构造时获得,析构时释放”,或者“基于范围的资源管理”。
  • RAII利用类的构造函数和析构函数的对称性,我们可以在类的构造函数中分配资源,在析构函数中释放资源。下面的示例是一个适用于不同资源的简单模板类,不需要用户去new创建对象或delete释放对象。
    被管理资源:
  1. using namespace std;
  2. class Foo {
  3. public:
  4. void foo();
  5. private:
  6. string name;
  7. };
  8. void Foo::foo() {
  9. name = "foo";
  10. cout << name << endl;
  11. }

模板类实现的资源管理类:

  1. template <typename RESTYPE>
  2. class ScopedResource final {
  3. public:
  4. ScopedR
2022-02-20 16:27:55    42    0    0

说明

  • 该博客由《C++代码整洁之道-C++17可持续软件开发模式实践》总结而来,部分内容有异议所以加上了自己的看法。

良好的命名

  • 源代码文件、命名空间、类、模板、函数、参数、变量和常量等,都应该具有有意义且富有表现力的名字。

名称应该自注释

  • 不好的命名就像打包搬家的箱子上写“东西”,而不是“餐具”等有意义的分类,浪费时间且没有意义。
  • 不好的命名:
  1. unsigned int num;
  2. bool flag;
  3. std::vector<Customer> list;
  4. Product data;
  • 好的命名:
  1. unsigned int numberOfArticles;
  2. bool isChanged;
  3. std::vector<Custom> customers;
  4. Product orderedProduct;
  • 命名也不应该过长,否则也会影响可读性,不要在函数、变量等的命名中包含文件名、类名等上下文信息。

使用域中的名称

  • 领域驱动设计(Domain-Driven Design,DDD)是试图将业务领域的事物和概念映射到代码中,使软件系统成为一个真实系统的模型。
  • 类、方法、参数、返回类型等命名都使用业务领域内典型的术语,具有领域知
2022-02-14 15:58:02    47    0    0

配置网络

配置静态IP

  • 这里安装的CentOS虚拟机,用的桥接模式,所以网关、掩码用宿主机的,IP配置一个不冲突的(宿主机ping不通的)。
  • 最小安装的CentOS没有ifconfig命令,所以用ip addr命令查看网口,然后修改相应的配置:
  1. $ ip addr
  2. ...
  3. 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
  4. ...
  5. $ vi /etc/sysconfig/network-scripts/ifcfg-ens33
  6. ...
  7. ONBOOT=yes
  8. BOOTPROTO=static
  9. IPADDR=172.31.18.55
  10. NETMASK=255.255.248.0
  11. GATEWAY=172.31.16.1
  12. $ systemctl restart network

配置DNS

  • 宿主机执行ipconfig /all可以获取到DNS地址,虚拟机中在/etc/resolv.conf中配置。
  1. $ cat /etc/resolv.conf
  2. nameserver 116.116.116.116
  3. nameserver 120.80.88.88

配置国内镜像源

  • 配置阿里云开源镜像源:
  1. $ mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
  2. $ curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
  3. $ sed -i -e '/mirrors.cloud.aliyuncs.com/d' -e '/mirrors.aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo
  4. $ yum cle
2022-02-14 15:29:48    44    0    0

VMware workstation pro配置

  • 由于希望虚拟机像局域网中的一台真实主机一样,所以选择桥接网络,让虚拟机的虚拟网络适配器通过主机的网卡上网。

title

安装过程的问题

  • 虚拟机窗口太小,点不到“下一步”按钮,可以修改窗口拉伸:

title

  • 也可以按Alt+F7拖动安装窗口。

首次修改root密码

  1. $ sudo passwd root

安装后的网络配置

  • 在主机执行ipconfig /all命令查看可以上网的网卡的IP地址、掩码、网关和DNS,在虚拟机中设置:

title

  • DNS配置后要重启network-manager服务,root用户执行:
  1. $ /etc/init.d/network-manager restart
  • ping www.baidu.com,能ping通说明网络配置好了。
  • 通过grep 配置的静态IP地址 /etc可以看到网络的配置文件。
  1. $ apt update # 访问源列表中的每个网址,读取软件列表并缓存
  2. $ apt upgrade # 安装可以更新的软件

配置livepatch

  • 配置livepatch后可以自动修补安全漏洞,需要先注册Ubuntu One账号,然后启用livepatch:

title

配置SSH

  • dpkg -l | grep ssh查看SSH有没有安装,默认只安装ssh-client,需要手动安装ssh-server。
  • 执行以下命令:
  1. apt install ssh-server
  2. systemctl status sshd # 查看SSH服务有没有运行

参考链接

2022-02-14 15:25:54    62    0    0

备份源列表文件sources.list

  1. $ sudo cp /etc/apt/sources.list /etc/apt/sources.list_backup

替换合适的源

  1. $ cat /etc/lsb-release
  2. DISTRIB_ID=Ubuntu
  3. DISTRIB_RELEASE=20.04
  4. DISTRIB_CODENAME=focal
  5. DISTRIB_DESCRIPTION="Ubuntu 20.04.3 LTS"
  • ubuntu 18阿里云镜像配置如下:
  1. $ cat /etc/apt/sources.list
  2. deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
  3. deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
  4. deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
  5. deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
  6. deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
  7. deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
  8. deb-src http://mirrors.aliyun.com/ubunt
2022-02-13 11:48:46    40    0    0

docker安装

使用阿里yum源安装

  1. $ yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  2. $ yum install docker-ce docker-ce-cli containerd.io

配置docker.service

/lib/systemd/system/docker.service:

  1. ...
  2. ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock
  3. ...

title

  1. $ systemctl deamon-reload
  2. $ systemctl restart docker

goland配置docker服务器

title
title

编写Dockerfile

  1. FROM golang:1.17
  2. WORKDIR /app
  3. ADD relax /app
  4. COPY static /app/static
  5. COPY conf /app/conf
  6. COPY views /app/views
  7. CMD ["/app/relax"]

配置交叉编译

title

配置dockerfile部署

title
title

2022-02-13 06:41:33    47    0    0

按路径挂载

  • 宿主机上的目录会覆盖容器中的目录:
  1. docker run -d --name nginx03 -P -v /home/xxx/conf/nginx:/etc/nginx nginx

具名挂载

  • 以下命令会将容器内的/etc/nginx挂载到/var/lib/docker/volume/卷名/_data,这里卷名就是etc-nginx:
  1. $ docker run -d --name nginx01 -P -v etc-nginx:/etc/nginx nginx
  2. $ ll /var/lib/docker/volumes/etc-nginx/_data/
  3. 总用量 36
  4. drwxr-xr-x 3 root root 4096 2 13 13:43 ./
  5. drwx-----x 3 root root 4096 2 13 13:43 ../
  6. drwxr-xr-x 2 root root 4096 2 13 13:43 conf.d/
  7. -rw-r--r-- 1 root root 1007 12 28 23:28 fastcgi_params
  8. -rw-r--r-- 1 root root 5349 12 28 23:28 mime.types
  9. lrwxrwxrwx 1 root root 22 12 28 23:40 modules -> /usr/lib/nginx/modules
  10. -rw-r--r-- 1 root root 648 12 28 23:40 nginx.conf
  11. -rw-r--r-- 1 root root 636 12 28 23:28 scgi_params
  12. -rw-r--r-- 1 root root 664 12 28 23:28 uwsgi_params
  • 执行以下命令,具名挂载会显示卷名:
  1. $ docker ps
  2. CONTAINER ID IMAGE COMMAND
2022-02-07 15:20:48    94    0    0

创建beego项目

  1. > bee new test

编写Controller描述

  • Controller上的注释用来描述该Controller的用处:
  1. // Operations about User
  2. type UserController struct {
  3. beego.Controller
  4. }

title

编写接口信息

  • 对GET/POST/PUT/DELETE接口的描述写在相应方法的上方:
  1. // @Title Create user
  2. // @Description Create a user
  3. // @Param body body models.User true "body for user info"
  4. // @Success 200 {int} models.User.Id
  5. // @Failure 403 body id empty
  6. // @router / [POST]
  7. func (u *UserController) Post() {
  8. var user models.User
  9. json.Unmarshal(u.Ctx.Input.RequestBody, &user)
  10. uid := models.AddUser(user)
  11. u.Data["json"] = map[string]string{"uid": uid}
  12. u.ServeJSON()
  13. }

title

models中定义的外部可访问的结构会自动显示在文档中

title

在路由设置文件中编写API描述

  • API的描述在routers/router.go的文件开始处定义:
  1. // @APIVersion 1.0.0
  2. // @Title beego Test API
  3. // @Description beego has a cool tool to autogenera
2021-09-06 12:31:41    95    0    0

【前言】

Go的工程可以放在两种位置:

  • 一种是在GOPATH环境变量目录中
  • 一种是在GOPATH环境变量目录外,使用go mod命令进行包管理

一些小伙伴可能长时间使用一种方法,遇到一个新的项目使用了另一种方法,就会不太熟悉,且不熟悉Goland提供了哪些支持,这篇文章介绍两种方法以及在Goland中的相应配置。

【使用GOPATH】
1、配置全局GOPATH环境变量
全局的GOPATH环境变量用于存放下载安装的Go项目代码和二进制文件,执行go install会编译出可执行文件,并拷贝到$GOPATH/bin目录下;执行go get会将代码下载到$GOPATH/src目录下,并进行编译和安装,相比go install增加了下载源码步骤。
title
title

2、配置项目的“临时”GOPATH

GOPATH下有三个目录:

  • src:源代码,以Go的包进行管理
  • bin:编译安装后可执行文件的路径
  • pkg:编译中间文件的存放路径,例如编译一个非main包产生的静态库文件

在全局GOPATH之外创建一个Go的工程,将工程的目录临时添加到GOPATH环境变量中,注意要将工程目录放在GOPATH最前面,Go的编译器等相关工具会按GOPATH的顺序进行搜索,我们要让工程目录的优先级最高,此时go install和go get产生的文件都在工程目录下:
title

为了能让Goland自动设置我们工程的“临时”GOPATH,可以在这里进行设置:
title

【使用go mod】
我们使用和上面例子同样的工程,首先删除设置的“临时”GOPATH,可以看到Goland已经不识别工程中的包了:
title

需要将包的路径改为工程中的绝对路径:
title

go modules是Go 1.11之后支持的依赖管理方式,我们需要设置一下系统环境变量和Go的环境变量:

  1. set GO111MODULE=auto
  2. go env -w GO111MODULE=auto
  3. go env -w GOPROXY=https://goproxy.cn,https://goproxy.io,direct

GO111MODULE设置为auto是指,在GOPATH下的工程,默认使用旧的GOPATH的管