Golang 的错误处理

Go 的错误处理一直是初学 Go 开发者不断吐槽的一个点。Go 没有像一般语言那样提供try catch的处理方式,而是通过函数返回值的方式直接返回。 需要不断的进行判断 if err != nil { return err } Rob Pike 也做了说明 Values can be programmed, and since errors are values, errors can be programmed. Rob Pike 在这篇文章里也展示了如果优雅的 handle error。 标准的Error interface Go j的标准包提供了一个 error interface type error interface { Error() string } 创建 error // Example 1 func demo() (bool, error) { return false, errors.New("A new error") } // Example 2 fmt....

May 20, 2021 · 4 min

Golang优雅的退出主线程

当我们想终止一个运行中golang程序, 往往会使用 ctrl+c 或者 kill -9 <pid> 来杀死程序。当我们正在运行一些原子性操作的代码的时候(比如写文件), 这样操作的话可能会导致问题产生。 因此需要有一个优雅的处理方式,等原子性的操作代码处理完后,再终止程序。 可以使用 golang的 os.Signal 来捕获系统的终止操作 sig := make(chan os.Signal) signal.Notify(sig, syscall.SIGINT, syscall.SIGKILL, syscall.SIGTERM) POSIX中定义的信号 使用2个channel通信的方式 func main() { sig := make(chan os.Signal) stopCh := make(chan struct{}) finishedCh := make(chan struct{}) signal.Notify(sig, syscall.SIGINT, syscall.SIGKILL) go func(stopCh, finishedCh chan struct{}) { for { select { case <-stopCh: fmt.Println("stopped") finishedCh <- struct{}{} return default: time.Sleep(time.Second * 10) } } }(stopCh, finishedCh) //程序被挂起 等待singal <-sig stopCh <- struct{}{} //等待子routine 返回 <-finishedCh fmt....

May 15, 2021 · 2 min

开始使用React Hooks

Hooks 是React16.8最新引入的特性。使用Hooks可以在函数式组件中管理state。 Hooks 带来的好处可以让更简洁的让UI与状态分离,使代码更加清晰。 说明 使用Hooks的前提是在函数式组件中。所以不能再使用React类组件的几个生命周期函数(需要通过useEffect来实现) 开始 前端项目万物基于TODO APP 😂 , 接一下使用Hooks来创建一个TODO APP。 useState useState 接受一个初始化参数, 返回一个值和set方法 todo 组件: const todo = props => { const [todoName, setTodoName] = useState('') const [todoList, setTodoList] = useState([]) const inputChangeHandler = event => { setTodoName(event.target.value) } const todoAddHandler = () => { setTodoList(todoList.concat(todoName)) } return ( <React.Fragment> <input type="text" placeholder="Todo" value={todoName} onChange={inputChangeHandler} /> <button type="button" onClick={todoAddHandler}>Add</button> <ul> {todoList.map((item, index) => ( <li key={index}>item</li> ))} </ul> </React....

March 12, 2019 · 3 min

开始使用GraphQL

GraphQL简介 GraphQL是一种api查询语言,GraphQL并不用绑定具体的数据库或者存储引擎,它是描述请求的一个规范,类似于RESTful, 可以利用已有的代码和技术来进行数据源管理。一个GraphQL查询是一个被发往服务端的字符串,该查询在服务端被解释和执行后返回JSON数据给客户端。 GraphQL基本语法 GraphQL基本语法可以分为 Fields,Arguments, Alias, Fragments,Operation name,Variables 操作可以分为Query和Mutation,query就是对数据进行查询,而mutation则是对数据进行操作,如增删改。 GraphQL是强类型的协议,支持的具体的数据类型有Int, Float, String, Boolean, ID Query //下面是一个简单的GraphQL查询,获取id为1的用户的ID,名字,邮箱,所有评论 //其中id,name,email,comments都为fields //id:1为arguments //nickname为alias //...queryComments是fragment //findUser是operation name 可以省略 query findUser { user(id: 1) { id name:nickname #可以给字段设置alias email comments { content } # ...queryComments } } fragment queryComments on Comments { content } Mutation //新建一个用户,然后返回id和名字 //❗️表示字段必输 mutation createUser($id: ID!, $name: String!, $email: String) { createUser(id: $id, name: $name, email: $email) { id name } } //variables { "id": 1, "name": "Tom", "email": "tom@test....

May 8, 2018 · 1 min

Docker常用命令

Docker note docker info显示详细的信息 docker 命令行格式docker <command> <sub-command> (option) command 一般指manage command,比如docker container run --detach\-d参数,使container在后台运行 docker container run 会一直新建一个container,使用docker container start启用一个已存在的 docker container --help docker container logs [containerName]显示container 日志信息 docker container top [containerName]显示container进程 docker container run -d -p 3306:3306 --name db -e MYSQL_RANDOM_ROOT_PASSWORD=yes mysql 新建一个mysql, docker container logs db 查看生成的密码 docker container inspect container配置详细 docker container stats查看所有container 状态 docker container exec -it [name] bash 进入container docker container port [name] docker image history [imagename:tag] 查看历史 docker image tag ....

January 8, 2018 · 1 min

理解Laravel IOC容器

理解Laravel IOC容器 IOC容器是Laravel框架一个非常重要的概念 依赖注入 理解IOC容器首先要从依赖注入开始。依赖注入和控制反转是差不多因果关系,通过使用依赖注入这种手段实现功能模块对其依赖组件的控制反转。 拿一个使用OAuth登录应用场景举例: interface Login { public function login(); } //微信账号登录 class WechatLogin implements Login { public function __construct(){} public function login() {} } //新浪微博登录 class WeiboLogin implements Login { public function __construct(){} public function login() {} } //QQ登录 class QQLogin implements Login { public function __construct(){} public function login() {} } //站点登录 class SiteLogin { protected $oauthClient; public function setOauthClient($oauthClient) { $this->oauthClient = $oauthClient } public function appLogin() { $this->oauthClient->login(); } } 一般可以使用两种方法实现注入...

November 25, 2017 · 2 min

PHP反射机制

PHP反射机制 介绍 reflection is the ability of a computer program to examine, introspect, and modify its own structure and behavior at runtime — wikipedia 反射的关键点就是在运行时分析类或者对象的状态,导出或提取出关于类,方法,属性,参数等信息。 代码例子 Reflection/Profile.php namespace codetest\Reflection; /** * Class Profile * * @package codetest\Reflection */ class Profile { public function getUserName() { return 'Foo'; } } $reflectionClass = new ReflectionClass('codetest\Reflection\Profile'); //当然也可以 $reflectionClass = new ReflectionClass(codetest\Reflection\Profile::class); var_dump($reflectionClass->getName()); // output: codetest\Reflection\Profile var_dump($reflectionClass->getDocComment()); // output: /** // * Class Profile // * // * @package codetest\Reflection // */ 应用场景 PHP的反射API,一般用到ReflectionClass和ReflectionMethod,...

November 21, 2017 · 2 min

Composer Autoload 配置说明

Composer Autoload 配置说明 谈到现代PHP,肯定离不开Composer。对于库的自动加载信息,Composer 生成了一个 vendor/autoload.php 文件。你可以简单的引入这个文件,你会得到一个免费的自动加载支持。(注意⚠️:php5.3之后才有namespace) require 'vendor/autoload.php'; namespace的应用大大的给开发提供的便利。autoload 是composer.json中的一个配置参数。autoload利用命名空间进行对应规则或标准的路径映射,从而找到最终的类文件。 四种Autoload模式 1. PSR-0 在 psr-0 key 下你定义了一个命名空间到实际路径的映射(相对于包的根目录)。注意,这里同样支持 PEAR-style 方式的约定(与命名空间不同,PEAR 类库在类名上采用了下划线分隔)。 请注意,命名空间的申明应该以 \\ 结束,以确保 autoloader 能够准确响应。 在 install/update 过程中,PSR-0 引用都将被结合为一个单一的键值对数组,存储至 vendor/composer/autoload_namespaces.php 文件中。 { "autoload": { "psr-0": { "Monolog\\": "src/", "Vendor\\Namespace\\": "src/", "Vendor_Namespace_": "src/" } } } ⚠️下划线 _ 对 psr-0 是有特殊意义的。psr-0 的加载器会将类名中的 _ 解析成目录分隔符。 即 Foo_Bar_Test 类会去加载 Foo/Bar/Test.php 文件。 2. PSR-4 将实际路径定义为命名空间。 { "autoload": { "psr-4": { "Monolog\\": "src/", "Vendor\\Namespace\\": "" } } } 3....

November 18, 2017 · 1 min

Laravel 生命周期

Laravel 生命周期 生命周期概述 入口 publuc/index.php是一个Laravel应用程序的入口,是整个框架的起点。index.php代码不多,主要的阶段就是: 加载Composer项目依赖 创建一个app实例容器 接收并且处理http请求 生命周期详解 加载项目依赖 Laravel使用Composer进行包的管理,所有组件的加载工作,仅需要一行代码 require __DIR__.'/../vendor/autoload.php'; 创建App实例 接下来便是创建应用实例(Illuminate\Foundation\Application),也叫服务容器 $app = require_once __DIR__.'/../bootstrap/app.php'; 整个初始化的过程包括:注册项目基础的ServiceProvider,注册SerciveProvider的Alias,注册目录路径等。 bootstrap/app.php中也完成了内核绑定。 Laravel会依据http请求的运行环境不同,将请求发送至相应的内核HTTP内核 或 Console内核。无论哪个内核,它们作用都是处理http请求。 最终,HTTP内核用handlemethod,单纯的接收一个Request以及返回一个Response。 HTTP内核 HTTP内核继承了Illuminate\Foundation\Http\Kernal类,它定义了在执行请求之前运行的 bootstrappers 数组。包含完成环境检测,配置加载,异常处理,Facades注册,ServiceProvider注册,启动服务这6个引导程序。 HTTP内核定义了所有被请求应用程序处理之前必须经过的HTTP中间件列表。 这些中间件可以处理 HTTP session 的读写, 可以判断服务器当前是否处于维护模式, 验证 CSRF token ( 为了保护服务器不受 CSRF 攻击 ) 等等功能. ServiceProvider 最重要的引导操作之一就是加载应用程序的ServiceProvider。应用程序的所有ServiceProvider都在config/app.php配置文件的providers数组中配置。所有的provider都会调用register方法,由boot方法负责调用所有的被注册provider。 ServiceProvider负责引导所有框架的各种组件,如数据库、队列、验证和路由组件。也就是说,框架提供的每个功能都它们来引导并配置。因此也可以说,ServiceProvider是整个 Laravel 引导过程中最重要的方面。 接收并处理请求 处理请求包含两个阶段: 创建请求实例 处理请求 创建请求实例 请求实例`Illuminate\Http\Request`的`capture() `方法,内部通过Symfony实例创建一个Laravel请求实例 /** * Create a new Illuminate HTTP request from server variables....

November 8, 2017 · 2 min