此文内的链接都为互联网上的博客技术文章,在此整理目录为学习用。
不定时更新和检查,某些链接会过期,多多包涵。
JAVA菜鸟教程
java 调用类的Main()方法
win7安装两个jdk,1.7和1.8,下载、安装、配置环境变量,方便切换
jWIN7:jdk(多版本)安装注意!
win10系统安装jdk8全过程
阿里巴巴 Java 开发手册1.4.0 转
阿里巴巴java开发手册
阿里巴巴java开发规范:( 八) ) 注释规约
idea 代码规范插件设置及文件头注释设置
Java 代码 各种不规范示范
JAVA中分为基本数据类型及引用数据类型
Java基本数据类型总结
java 基本数据类型及自动类型提升
int和Integer有什么区别
该如何创建字符串,使用” “还是构造函数?
<dependency>
<groupId>commons-langgroupId>
<artifactId>commons-langartifactId>
<version>2.6version>
dependency>
java 字符串截取的几种方式
Java工具类StringUtils常用方法整理
StringUtils详细介绍
getter/setter
关于面向对象编程中很多人用get()和set()方法,而不用public的一点总结
java对象 POJO和JavaBean的区别
java中的POJO是什么意思?
Java各种对象(PO,BO,VO,DTO,POJO,DAO,Entity,JavaBean,JavaBeans)的区分
深入浅出JDBC
Field ‘userID’ doesn’t have a default value 问题的解决
w3cschool: JUnit - API
JUnit4单元测试学习笔记
Junit 使用–高级篇
Spring 对 Controller、Service、Dao 进行Junit单元测试总结
Java JUnit测试实现控制台输入的正确姿势
Java 从命令控制台输入数据读取输入流System.in的几种常用方法
Java控制台输入选择超时处理方式(修正1)
Log4j 详细使用教程
log4j 使用及配置分析记录
log4j 的8个日志级别
从 slf4j 关闭日志记录
Spring MVC + Slf4j + Log4j2 日志文件系统配置
知乎:Log4j2 与 Slf4j 的最佳实践
完美 spring boot 使用 log4j2 按级别输出到不同文件
Log4j2中的同步日志与异步日志
Log4j2同步异步性能比较以及教程和问题(坑)汇总
IDEA+Log4j2 设置控制台打印彩色日志
Java 集合系列——by skywang12345
Java集合类: Set、List、Map、Queue使用场景梳理
java集合入门和深入学习
《深入理解Java集合框架》系列文章
java集合详解 简述
List总结(LinkedList, ArrayList等使用场景和性能分析——by skywang12345)
java 获取json字符串中key对应的值
java基础io流—— OutputStream和InputStream
Java IO流详解
java IO流的概念理解
Java输入、输出、IO流 类层次关系梳理
Java如何正确的使用try catch finally关闭文件流的总结
Java 遍历文件夹的几种方式及简单性能对比
Java SimpleFileVisitor遍历文件夹与File遍历文件夹的速度对比
Java遍历文件夹的两种方法
【java】当文件目录不存在时自动创建文件目录
Java 7 中 NIO.2 的使用——文件递归操作
Java 怎么使用 SimpleFileVisitor 类遍历文件系统
Java递归搜索指定目录下具有某个后缀名的所有文件
Windows 7下 搭建 基于 ssh 的sftp 服务器
在 Windows 上使用 FTP/SFTP 服务端
java之 Jsch 实现Linux的文件上传与下载
JAVA SFTP 文件上传、下载及批量下载
Java中如何优雅正确的终止线程
线程中断机制,精确控制方法执行
Java多线程(3):取消正在运行的任务
java设置一段代码执行的超时时间的简单方法 间接实现获取Connection超时问题
Java方法设置超时
Java中的Runnable、Callable、Future、FutureTask的区别与示例
java多线程-概念&创建启动&中断&守护线程&优先级&线程状态(多线程编程之一)
Java多线程编程:Callable、Future和FutureTask浅析(多线程编程之四)
一次Java线程池误用引发的血案和总结
Java中线程池,你真的会用吗?
深入源码分析Java线程池的实现原理
Java并发:终止线程和关闭线程池
【Java8源码分析】线程池-Executor与ExecutorService的全面剖析
ExecutorService shutdown 系列方法的理解
Stack Overflow:Turning an ExecutorService to daemon in Java
教程:MySQL DBA
Mysql 循环插入10000条数据
MySQL批量插入数据性能比较
Mysql 查看连接数,状态 最大并发数
Mysql 查看连接数,状态
MySQL 編碼挑選與差異比較
utf8_bin vs. utf8_unicode_ci vs. utf8_general_ci
MySQL监控全部执行过的sql语句
mysql如何跟踪执行的sql语句
mysql 5.7日志查看
查看是否开启日志记录:
show variables like '%general_log%';
另:临时开启日志记录:
set global general_log='on';
永久开启,在 my.ini 文件 的 [mysql] 节点 设置:
general-log=1
general_log_file=自定义路径+记录文本文件.log
[mysqld]
general-log=1
general_log_file=C:\ProgramData\MySQL\MySQL Server 5.5\data\mysqls.log
MySQL字符编码问题
SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%';
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
character-set-client-handshake=FALSE
character-set-server=utf8
collation-server=utf8_bin
10分钟学会理解和解决MySQL乱码问题
Ubuntu中修改mysql的编码
关于解决mysql和jsp乱码问题的总结:注意连接DB字符串里边的符号
连接mysql的jdbc驱动最新版的问题:The server time zone value is unrecognized or represents
MySQL的安装、卸载
windows10上安装mysql(详细步骤)
ubuntu完全卸载mysql
Windows:启动/停止/重启MySQL:(Windows下不能直接重启MySQL)
net stop MySQL
net start MySQL
Ubuntu:启动/停止/重启MySQL数据库:
sudo start mysql
sudo stop mysql
sudo restart mysql
通过cmd窗口导入导出mysql数据库
mysql有data文件夹恢复数据的方法
MySQL误操作后如何快速恢复数据:利用binlog2sql快速闪回
GitHub:binlog2sql
MySQL 经典案例分析:Specified key was too long
索引长度过长 ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes
show variables like 'innodb_large_prefix';
set global innodb_large_prefix=1;
show variables like 'innodb_file_format';
set global innodb_file_format=BARRACUDA;
Mysql 建表错误1071 - Specified key was too long; max key length is 767 bytes
【解决】升级MySQL版本:导入sql文件报错
1.建表时候直接指定使用utf8字符集而不是utf8mb4(这个方案就是修改字符集,当然你也可以修改mysql的全局配置实现);也可以修改数据库那些编码格式
2.使用innodb建表,并设置mysql配置项innodb_large_prefix=on,这种办法就是设置启用innodb_large_prefix选项,将约束项扩展至3072byte
3.建表默认格式改为 dynamic 或c ompressed
4.升级MySQL版本,比如 5.5 → 5.7。版本5.5之后 innodb_large_prefix 默认为on
5.(不推荐,不要动数据库!)修改字段长度即utf8下面255,utf8mb4下面191
MS SQL 2008数据库完全卸载指南
SQL server 2008 安装时 安装程序支持规则“重新启动计算机”失败:删除 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager 里的PendingFileRenameOperations 项
SqlServer.Management.Dmf.PolicyStore”的类型初始值设定项引发异常:下载文件
sql server 2008附加数据库失败:MDF和LDF文件修改权限
重启MS SQL数据库:
net stop sqlserveragent
net stop mssqlserver
net start mssqlserver
net start sqlserveragent
W3CSchool - Spring
JAVA思维导图 - Spring
spring思维导图,让spring更加简单易懂
Spring容器
DAO设计模式实现数据库的增删改查(进一步封装JDBC工具类)
IoC-spring 的灵魂(带你轻松理解IOC思想及bean对象的生成过程)
Spring核心思想,IoC与DI详解(如果还不明白,放弃java吧)
Spring IOC原理总结
关于Spring IOC (DI-依赖注入)你需要知道的一切
知乎:浅谈控制反转与依赖注入
知乎:如何用最简单的方式解释依赖注入?依赖注入是如何实现解耦的?
Spring读书笔记-----Spring的Bean之Bean的基本概念
细说Spring——AOP详解(AOP概览)
Spring-aop 全面解析(从应用到原理)
易百教程:Spring使用@Autowired注解自动装配
Spring自动装配@Autowired的三种方式
Spring@Autowired注解与自动装配
Spring中 @Autowired注解与@Resource注解的区别
@Configuration注解、@Bean注解以及配置自动扫描、bean作用域
【译】标签@Resource @Autowired 和@Inject的区别
Spring依赖注入:注解注入总结
Spring中什么时候用@Resource,@service,及Spring注解@Component、@Repository、@Service、@Control
Spring Injection with @Resource, @Autowired and @Inject
Spring Best Practices for Writing Configuration Files
使用说明:自动扫描IOC组件
Spring5:@Autowired注解、@Resource注解和@Service注解
Spring中jdbcTemplate的用法实例(一)
Spring中的JDBCTemplate使用(非常详细的配置过程)
Spring-jdbc:JdbcTemplate使用简介
Spring JdbcTemplate API:常用方法queryForObject、RowMapper、queryForList
JdbcTemplate系列(一)----使用详解:配置JdbcTemplate的三种方式,DAO实现类
利用spring的JdbcTemplate查询返回结果映射到自定义类型:BeanPropertyRowMapper
Spring JdbcTemplate查询示例
Spring4-使用JdbcTemplate和事务处理
spring 配置 DataSource 三种方式:DBCP、C3P0
Spring实战6-利用Spring和JDBC访问数据库:配置数据源的多种方式
Spring3.x中配置DBCP2.0数据库连接池
DBCP数据库连接池的简单使用
DBCP连接池学习
dbcp2数据源配置详解
c3p0数据库连接池的使用详解
为什么HikariCP被号称为性能最好的Java数据库连接池,如何配置使用
HikariCP配置详解+多数据源
hikariCP连接池配置 转
有关Hikaricp连接池配置的解读
【spring MVC】新手从零新建第一个hello world项目
在Eclipse中使用Maven构建SpringMVC项目
SpringMVC 快速入门
Spring MVC【入门】
springmvc(一) springmvc框架原理分析和简单入门程序
史上最全最强SpringMVC详细示例实战教程
打造功能完整的博客系统:Spring MVC实战入门
Java Tutorial 第四堂(1)使用 spring-webmvc 框架
SpringMVC:从Controller跳转到另一个Controller
ModelAndView传值到JSP页面的四种方法
Spring MVC 到 Spring Boot 的简化之路
Spring MVC 统一异常处理
JSP中文乱码问题
Spring MVC RedirectAttributes的用法解决法
Spring mvc框架 controller间跳转 ,重定向 ,传参
Stack Overflow:Spring MVC Multiple ModelAttribute On the Same Form
Spring+Springmvc+Mybatis maven整合ssm框架详解
SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)
SSM框架——详细整合教程(Spring+SpringMVC+MyBatis):MyBatis Generator自动创建代码
SSM框架——使用MyBatis Generator自动创建代码
MyBatis:增删查改的返回值
关于MyBatis mapper的insert, update, delete返回值:增删改:返回所影响的行数,不是行号
mybatis: 返回主键ID(自增和非自增)
mysql插入数据后返回自增ID的方法,last_insert_id(),selectkey
mybatis-generator-1.3.2 使用方法
mybatis自动生成mapper中的insert与 insertseletive,updateByPrimaryKey,updateByPrimaryKeySelective 方法的区别
通俗易懂的RESTful API实践详解(含代码)
【整理】Spring Rest接口开发专题
Spring REST API
https://blog.csdn.net/qq_26892215/article/details/81985784
阮一峰:RESTful API 设计指南
阮一峰:RESTful API 最佳实践
Way Lau:RESTful API 设计最佳实践
Spring Boot 各版本的Java版本要求
SpringBoot 官方页面:生成项目
SpringBoot 入门教程(一)详解intellij idea搭建SpringBoot
一文搞懂SpringBoot启动原理
构建微服务:Spring boot 入门篇
参数校验(validator)
一起来学SpringBoot | 第十九篇:轻松搞定数据验证(一)
@NotNull和@NotEmpty和@NotBlank区别
@NotNull、@NotEmpty、@NotBlank的区别
使用 Lombok 替代Getter和Setter 方法
使用 Lombok 消除冗余 getter 和 setter 代码
基于 SpringBoot + Mybatis 实现 SpringMVC Web 项目
Spring boot Mybatis 整合(完整版)
基于 SpringBoot2.0+ 优雅整合 SpringBoot+Mybatis
SpringBoot中异步请求和异步调用
Spring Boot中使用@Async实现异步调用
SpringBoot集成篇(二) 异步调用 @Async
Spring boot 注解@Async无效,不起作用
SpringBoot使用Async注解失效分析、解决(spring异步回调)
Java CompletableFuture 详解
使用CompletableFuture优化你的代码执行效率
Spring Boot使用@Async实现异步调用:ThreadPoolTaskScheduler线程池的优雅关闭
Spring Boot系列二 Spring @Async异步线程池用法总结
SpringBoot | 第二十章:异步开发之异步请求
实战Spring Boot 2.0系列(四) - 使用WebAsyncTask处理异步任务
spring boot–使用异步请求,提高系统的吞吐量
Spring Boot 使用WebAsyncTask异步返回结果:指定线程池
高并发场景下的Web异步任务WebAsyncTask:WEB请求
SpringBoot 防止重复请求,重复表单提交超级简单的注解实现
Spring定时任务详解(@Scheduled注解)
Springboot学习笔记(二)-定时任务
SpringBoot | 第二十二章:定时任务的使用
开发踩坑记录之二:谨慎使用Spring中的@Scheduled注解
在线Cron表达式生成器
实战Spring Boot 2.0系列(六) - 单机定时任务的几种实现
知乎:SpringBoot中并发定时任务的实现、动态定时任务的实现
Spring Boot 定时任务(动态添加修改删除定时任务)
SpringBoot 创建定时任务(配合数据库动态执行)
ThreadPoolTaskScheduler 的使用,定时任务开启与关闭
Executor框架(一)Callable、Future、Executor和ExecutorService
Executor框架(二)Executors、ThreadPoolExecutor以及线程池执行任务的行为方式
Executor框架(三)ScheduledExecutorService-和-BlockingQueue
接口 java.util.concurrent.ScheduledFuture的使用
ThreadPoolExecutor甚至在ScheduledFuture被取消后运行
知乎:最牛逼的任务调度工具 | Quartz
Quartz的使用与持久化(springboot整合)
spring-boot-2.0.3之quartz集成,不是你想的那样哦!
SpringBoot整合Quartz简单完整例子
SpringBoot整合Quartz作为调度中心完整实用例子
【Quartz】Quartz存储与持久化-基于quartz.properties的配置
SpringBoot 整合 Quartz 实现依赖数据库数据动态设置定时任务
精通SpringBoot——第十篇:使用Quartz实现动态配置定时任务
quartz初次使用踩坑记
记一次Quartz重复调度(任务重复执行)的问题排查
MockMvc 的测试HTML文件响应:Spring MockMvc tutorial
Spring Boot 的简单教程(二) web页面开发(Thymeleaf篇)
Spring Boot 最佳实践(四)模板引擎Thymeleaf集成
thymeleaf标签之 th:href 的使用
thymeleaf报错:Neither BindingResult nor plain target object for bean name ‘***’
thymeleaf 3.0 的 th:onclick
springBoot记录Http访问日志(简单入门2)
(4) spring-boot+logback+log4j2+MDC
Spring Boot 日志处理篇 - 偏应用
springboot springmvc拦截器 拦截POST、PUT、DELETE请求参数和响应数据,并记录操作日志
实战Spring Boot 2.0系列(二) - 全局异常处理和测试
SpringBoot记录HTTP请求日志
Spring boot 2.0 Actuator 的健康检查
一起来学SpringBoot | 第十四篇:强大的 actuator 服务监控与管理
springboot全局字符编码设置(解决乱码问题)
Spring Boot 中文乱码问题解决方案汇总
spring boot 解决后台返回 json 到前台中文乱码
SpringBoot乱码
Springboot问题解决:javax.servlet.ServletException: Circular view path [****]: would dispatch…
Spring Bean的循环依赖解决方案:The dependencies of some of the beans in the application context form a cycle
spring boot 两个war包同时在tomcat中部署后启动报错:Unable to register MBean [HikariDataSource (null)] with key 'dataSource’
Navicat Premium 12.1.20.0 安装与激活
Navicat12 证书过期 解决办法:删注册表项
Maven官方仓库:mvnrepository
换为阿里云仓库镜像:
在Maven安装路径下conf文件夹的 settings.xml,配置本地仓库:
<localRepository>F:\Tools\maven\repolocalRepository>
然后在 mirrors 节点添加:
<mirrors>
<mirror>
<id>aliyunid>
<name>aliyunname>
<url>http://maven.aliyun.com/nexus/content/groups/public/url>
<mirrorOf>centralmirrorOf>
mirror>
mirrors>
ubuntu16.04安装maven
Maven教程(一)
POM文件结构
pom.xml 文件详解
【Maven】配置文件小结
Maven的pom.xml文件详解------Build Settings
Maven灵活构建
maven内置属性详细说明
Maven单元测试
Eclipse配置外部Maven
普通 Java 项目转换为 Maven 项目
使用maven给spring项目打可直接运行的jar包(配置文件内置外置的打法)
使用Maven运行Java main的3种方式
maven配置依赖github上的项目
知乎:tar包和jar包和war包的区别?
修改jar包源码,成功编译,应用到项目中
修改Jar包源码(无需反编译工具)
maven-compiler-plugin
学习Maven之Maven Surefire Plugin(JUnit篇)
maven依赖冲突查找
eclipse maven maven-compiler-plugin 报错 解决
编译错误: 程序包xxx 不存在
编译报错:程序包org.junit不存在
关于Maven resource配置中include与exclude的关系
报错:Error: Plugin org.apache.maven.plugins:maven-clean-plugin:2.5 or one of its dependencies could not be resolve
maven的package与install命令区别:package是把jar打到本项目的target下,而install时把target下的jar安装到本地仓库,供其他项目使用.
Maven 错误 Failure to transfer …was cached in the local repository…
MyBatis学习总结
Mybatis官方文档
Mybatis深入浅出系列
Mybatis从入门到精通:Mybatis使用之环境搭建
mybatis 中的 update 返回值解析
MyBatis 详解(一对一,一对多,多对多)
(十五)mybatis 逆向工程
mybatis中resultMap配置细则
Mybatis中的resultType和resultMap
mybatis:insert与insertseletive,updateByPrimaryKey,updateByPrimaryKeySelective的区别
mybatis Generator最佳实践(数据库:mysql)
SSM框架——使用 MyBatis Generator 自动创建代码
mybatis-generator-1.3.2 使用方法
Mybatis Generator 最完整配置详解
【MyBatis学习14】MyBatis和Spring整合
Spring-Spring整合MyBatis详解
spring与mybatis四种整合方法
mybatis整合Spring的基本步骤
spring配置mybatis自动扫描mapper.java和mapper.xml配置文件
Spring与MyBatis整合 、 Spring整合MyBatis应用
Spring集成MyBatis完整示例
mybatis绑定错误-- Invalid bound statement (not found)
Mybatis返回int类型为空时报错 attempted to return null from a method with a primitive return type (int)
使用MyBatis查询 返回类型为int,但是当查询结果为空NULL,报异常的解决方法
Linux常用命令大全
部署 JavaWeb 项目到云服务器
linux下部署java项目
Postman 使用方法详解
postman使用技巧
廖雪峰教程:GitHub教程
ubuntu16.04 搭建git服务器简单教程
手把手教你搭建git服务器
遇到问题:Permanently added the RSA host key for IP address … to the list of known host
windows下git bash中文乱码解决办法
git永久保存账号密码,免去git重复输入账号密码操作
廖雪峰教程:Git 忽略特殊文件
eclipse git提交忽略文件gitignore,以及不起作用问题解决
eclipse git提交忽略文件gitignore,以及不起作用问题解决
gitignore不起作用解决办法
先编辑好.gitigore文件,再执行:
git rm -r --cached .
git add .
git commit -m "update gitignore"
Apache Tomcat下载、安装、配置图文教程
Tomcat 部署项目的三种方法
Linux下Tomcat端口号以及进程相关命令
修改Tomcat8w.exe可执行路径:Path to executable
eclipse/myeclipse中的内置tomcat和外部tomcat的区别
如何安装和配置两个不同版本的tomcat
tomcat配置及中文乱码问题的解决方案
Tomcat 进入管理页面提示:401 Unauthorized
tomcat访问host-manager出现403问题解决
Tomcat:登录账号配置、外网登录授权
提示: Tomcat 8.0 installation is expected
eclipse中server location为灰色,不能修改
关于Tomcat出现The origin server did not find a current representation for the target resourc…的问题
关于Tomcat出现“The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.”的问题
路径问题:The origin server did not find a current representation…
Linux, CentOS, Ubuntu 解决 Tomcat 启动速度巨慢问题
云服务器启动tomcat很慢
启动tomcat报错:No Spring WebApplicationInitializer types detected on classpath
关于Tomcat下项目被启动两次为问题
解决Tomcat启动时项目重复加载问题
SpringBoot2.x填坑(四):生产上SpringBoot2.x Scheduled定时任务重复执行两次解决方案
设置Eclipse的类文件和xml文件代码自动补全
elclipse web.xml自动提示补全问题
Eclipse设置背景色:色调:85。饱和度:123。亮度:205
java基础加强–eclipse工程下的.classpath文件与加载配置文件进行反射
将本地maven项目上传至github
Eclipse Push出现rejected - non-fast-forward错误
eclipse连接github报错: cannot open git(can’'t connect to any…
在 eclipse.ini 文件添加一句:-Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2
Eclipse 的 Debug 介绍与技巧
Eclipse的Debug调试技巧大全
错误 Cannot change version of project facet Dynamic Web Module to 2.5
Eclipse报错:Type org.apache.maven.archiver.MavenArchiver.getManifest(org.apache.maven.project.MavenProject, org.apache.maven.archiver.MavenArchiveConfiguration)
史上最简单的 IntelliJ IDEA 教程
idea生成类注释和方法注释的正确方法
IDEA激活教程
Intellij IDEA 添加jar包的三种方式
IntelliJ IDEA中maven打包配置
IntellJ IDEA 配置Maven以及修改默认Repository
Intellij IDEA 配置Maven(内置Maven和修改本地仓库地址和阿里云中央仓库)
IntelliJ IDEA maven库下载依赖包速度慢的问题
解决 Intellij IDEA Cannot Resolve Symbol ‘XXX’ 问题的四板斧:也可以删掉target文件夹
springboot项目提示“Failed to determine a suitable driver class”
Maven 打包时丢失properties文件
<build>
<resources>
<resource>
<directory>configdirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
<include>**/*.ymlinclude>
includes>
resource>
<resource>
<directory>src/main/resourcesdirectory>
resource>
resources>
build>
IDEA - 配置Tomcat并运行Web项目
在IDEA上配置外部tomcat
idea中tomcat使用方式(1)------使用外部tomcat服务
Tomcat部署时war和war exploded区别以及平时踩得坑
idea 导入eclipse maven项目
Maven项目从Eclipse导入到IDEA
2019年 Intellij IDEA 创建 WEB项目
IntelliJ IDEA 创建SSM项目
IDEA 使用Git Clone项目
idea 忽略不需要提交 git、svn 的目录或文件
IDEA在clone的时候提示Permission denied (publickey). fatal: Could not read from remote repository.
Cannot start compilation: the output path is not specified for module
解决 idea application context not configured for this file 的问题
idea Error:(3, 32) java: 程序包 org.springframework.boot 不存在
idea tomcat 启动报错 not found for the web module
idea配置Tomcat ,Deployment添加时没有Artifact…选择的解决方案
解决 Could not autowire. No beans of ‘xxxx’ type found 的错误提示
mybatis / mapper 文件提示:No data sources are configured to run this sql
idea常见问题整理
IDEA中xml文件头报错:URI is not registered (Settings | Languages & Frameworks | Schemas and DTDs)
IntelliJ IDEA控制台junit不能用Scanner输入:
IDEA Error:configuring application listener of class Intellij IDEA Error configuring application listener of class org.springframework.web.context.ContextLoaderListener
网络广播
spring boot restful API 从零到一完整实践
https://www.cnblogs.com/a757956132/p/4777748.html
https://www.jianshu.com/p/566a3d9a792d