平时开发过程中,无可避免我们需要处理各类异常,所以这里我们在公共模块中自定义统一异常,Spring Boot 提供 @RestControllerAdvice 注解统一异常处理,我们在GitEgg_Platform中新建gitegg-platform-boot子工程,此工程主要用于Spring Boot相关功能的自定义及扩展。

1、修改gitegg-platform-boot的pom.xml,添加spring-boot-starter-web和swagger依赖,设置optional为true,让这个包在项目之间依赖不传递。

        <dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-web</artifactid>
<optional>true</optional>
</dependency>
<dependency>
<groupid>com.gitegg.platform</groupid>
<artifactid>gitegg-platform-swagger</artifactid>
<optional>true</optional>
</dependency>

2、自定义通用响应消息类,Result和PageResult,一个是普通响应消息,一个是分页响应消息。

Result类:

package com.gitegg.platform.boot.common.base;

import com.gitegg.platform.boot.common.enums.ResultCodeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*; /**
* @ClassName: Result
* @Description: 自定义通用响应类
* @author GitEgg
* @date 2020年09月19日 下午9:24:50
*/
@ApiModel(description = "通用响应类")
@Getter
@ToString
public class Result<t> { @ApiModelProperty(value = "是否成功", required = true)
private boolean success; @ApiModelProperty(value ="响应代码", required = true)
private int code; @ApiModelProperty(value ="提示信息", required = true)
private String msg; @ApiModelProperty(value ="响应数据")
private T data; /**
*
* @param code
* @param data
* @param msg
*/
private Result(int code, T data, String msg) {
this.success = ResultCodeEnum.SUCCESS.code == code;
this.code = code;
this.msg = msg;
this.data = data;
} /**
*
* @param resultCodeEnum
*/
private Result(ResultCodeEnum resultCodeEnum ) {
this(resultCodeEnum.code, null, resultCodeEnum.msg);
} /**
*
* @param resultCodeEnum
* @param msg
*/
private Result(ResultCodeEnum resultCodeEnum , String msg) {
this(resultCodeEnum, null, msg);
} /**
*
* @param resultCodeEnum
* @param data
*/
private Result(ResultCodeEnum resultCodeEnum , T data) {
this(resultCodeEnum, data, resultCodeEnum.msg);
} /**
*
* @param resultCodeEnum
* @param data
* @param msg
*/
private Result(ResultCodeEnum resultCodeEnum , T data, String msg) {
this(resultCodeEnum.code, data, msg);
} /**
*
*
* @param data 数据
* @param <t> T 响应数据
* @
*/
public static <t> Result<t> data(T data) {
return data(data, ResultCodeEnum.SUCCESS.msg);
} /**
*
*
* @param data 数据
* @param msg 消息
* @param <t> T 响应数据
* @
*/
public static <t> Result<t> data(T data, String msg) {
return data(ResultCodeEnum.SUCCESS.code, data, msg);
} /**
*
*
* @param code 状态码
* @param data 数据
* @param msg 消息
* @param <t> T 响应数据
* @
*/
public static <t> Result<t> data(int code, T data, String msg) {
return new Result<>(code, data, msg);
} /**
* 返回Result
*
* @param
* @param <t> T 响应数据
* @返回Result
*/
public static <t> Result<t> success() {
return new Result<>(ResultCodeEnum.SUCCESS);
} /**
* 返回Result
*
* @param msg 消息
* @param <t> T 响应数据
* @返回Result
*/
public static <t> Result<t> success(String msg) {
return new Result<>(ResultCodeEnum.SUCCESS, msg);
} /**
* 返回Result
*
* @param
* @param <t> T 响应数据
* @返回Result
*/
public static <t> Result<t> success(ResultCodeEnum resultCodeEnum ) {
return new Result<>(resultCodeEnum);
} /**
* 返回Result
*
* @param
* @param msg 提示信息
* @param <t> T 响应数据
* @返回Result
*/
public static <t> Result<t> success(ResultCodeEnum resultCodeEnum , String msg) {
return new Result<>(resultCodeEnum, msg);
} /**
* 返回Result
*
* @param <t> T 响应数据
* @返回Result
*/
public static <t> Result<t> error() {
return new Result<>(ResultCodeEnum.ERROR, ResultCodeEnum.ERROR.msg);
} /**
* 返回Result
*
* @param msg 消息
* @param <t> T 响应数据
* @返回Result
*/
public static <t> Result<t> error(String msg) {
return new Result<>(ResultCodeEnum.ERROR, msg);
} /**
* 返回Result
*
* @param code 状态码
* @param msg 消息
* @param <t> T 响应数据
* @返回Result
*/
public static <t> Result<t> error(int code, String msg) {
return new Result<>(code, null, msg);
} /**
* 返回Result
*
* @param
* @param <t> T 响应数据
* @返回Result
*/
public static <t> Result<t> error(ResultCodeEnum resultCodeEnum ) {
return new Result<>(resultCodeEnum);
} /**
* 返回Result
*
* @param
* @param msg 提示信息
* @param <t> T 响应数据
* @返回Result
*/
public static <t> Result<t> error(ResultCodeEnum resultCodeEnum , String msg) {
return new Result<>(resultCodeEnum, msg);
} /**
*
* @param <t>
* @param flag
* @return
*/
public static <t> Result<t> result(boolean flag) {
return flag ? Result.success("操作成功") : Result.error("操作失败");
} }

PageResult类:

package com.gitegg.platform.boot.common.base;

import java.util.List;

import com.gitegg.platform.boot.common.enums.ResultCodeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data; /**
* @ClassName: PageResult
* @Description: 通用分页返回
* @author GitEgg
* @date
* @param <t>
*/
@Data
@ApiModel("通用分页响应类")
public class PageResult<t> { @ApiModelProperty(value = "是否成功", required = true)
private boolean success; @ApiModelProperty(value ="响应代码", required = true)
private int code; @ApiModelProperty(value ="提示信息", required = true)
private String msg; @ApiModelProperty(value ="总数量", required = true)
private long count; @ApiModelProperty(value ="分页数据")
private List<t> data; public PageResult(long total, List<t> rows) {
this.count = total;
this.data = rows;
this.code = ResultCodeEnum.SUCCESS.code;
this.msg = ResultCodeEnum.SUCCESS.msg;
}
}

3、自定义通用响应消息枚举类ResultCodeEnum。

package com.gitegg.platform.boot.common.enums;

/**
* @ClassName: ResultCodeEnum
* @Description: 自定义返回码枚举
* @author GitEgg
* @date 2020年09月19日 下午11:49:45
*/
public enum ResultCodeEnum { /**
* 成功
*/
SUCCESS(200, "操作成功"), /**
* 系统错误
*/
ERROR(500, "系统错误"), /**
* 操作失败
*/
FAILED(101, "操作失败"), /**
* 未登录/登录超时
*/
UNAUTHORIZED(102, "登录超时"), /**
* 参数错误
*/
PARAM_ERROR(103, "参数错误"), /**
* 参数错误-已存在
*/
INVALID_PARAM_EXIST(104, "请求参数已存在"), /**
* 参数错误
*/
INVALID_PARAM_EMPTY(105, "请求参数为空"), /**
* 参数错误
*/
PARAM_TYPE_MISMATCH(106, "参数类型不匹配"), /**
* 参数错误
*/
PARAM_VALID_ERROR(107, "参数校验失败"), /**
* 参数错误
*/
ILLEGAL_REQUEST(108, "非法请求"), /**
* 验证码错误
*/
INVALID_VCODE(204, "验证码错误"), /**
* 用户名或密码错误
*/
INVALID_USERNAME_PASSWORD(205, "账号或密码错误"), /**
*
*/
INVALID_RE_PASSWORD(206, "两次输入密码不一致"), /**
* 用户名或密码错误
*/
INVALID_OLD_PASSWORD(207, "旧密码错误"), /**
* 用户名重复
*/
USERNAME_ALREADY_IN(208, "用户名已存在"), /**
* 用户不存在
*/
INVALID_USERNAME(209, "用户名不存在"), /**
* 角色不存在
*/
INVALID_ROLE(210, "角色不存在"), /**
* 角色不存在
*/
ROLE_USED(211, "角色使用中,不可删除"), /**
* 没有权限
*/
NO_PERMISSION(403, "当前用户无该接口权限"); public int code; public String msg; ResultCodeEnum(int code, String msg) {
this.code = code;
this.msg = msg;
} public int getCode() {
return code;
} public void setCode(int code) {
this.code = code;
} public String getMsg() {
return msg;
} public void setMsg(String msg) {
this.msg = msg;
}
}

4、自定义异常类BusinessException和SystemException

package com.gitegg.platform.boot.common.exception;

import com.gitegg.platform.boot.common.enums.ResultCodeEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.Setter; /**
* @ClassName: BusinessException
* @Description: 业务处理异常
* @author GitEgg
* @date
*/
@Getter
@Setter
public class BusinessException extends RuntimeException { private int code; private String msg; public BusinessException() {
this.code = ResultCodeEnum.FAILED.code;
this.msg = ResultCodeEnum.FAILED.msg;
} public BusinessException(String message) {
this.code = ResultCodeEnum.FAILED.code;
this.msg = message;
} public BusinessException(int code, String msg) {
this.code = code;
this.msg = msg;
} public BusinessException(Throwable cause) {
super(cause);
} public BusinessException(String message, Throwable cause) {
super(message, cause);
} }
package com.gitegg.platform.boot.common.exception;

import com.gitegg.platform.boot.common.enums.ResultCodeEnum;
import lombok.Getter; /**
* @ClassName: SystemException
* @Description: 系统处理异常
* @author GitEgg
* @date
*/
@Getter
public class SystemException extends RuntimeException { private int code; private String msg; public SystemException() {
this.code = ResultCodeEnum.ERROR.code;
this.msg = ResultCodeEnum.ERROR.msg;
} public SystemException(String message) {
this.code = ResultCodeEnum.ERROR.code;
this.msg = message;
} public SystemException(int code, String msg) {
this.code = code;
this.msg = msg;
} public SystemException(Throwable cause) {
super(cause);
} public SystemException(String message, Throwable cause) {
super(message, cause);
} }

5、自定义统一异常处理类GitEggControllerAdvice.java

package com.gitegg.platform.boot.common.advice;

import com.gitegg.platform.boot.common.base.Result;
import com.gitegg.platform.boot.common.enums.ResultCodeEnum;
import com.gitegg.platform.boot.common.exception.BusinessException;
import com.gitegg.platform.boot.common.exception.SystemException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.ui.Model;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.servlet.NoHandlerFoundException; import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolationException; @Slf4j
@RestControllerAdvice
public class GitEggControllerAdvice { /**
* 服务名
*/
@Value("${spring.application.name}")
private String serverName; /**
* 微服务系统标识
*/
private String errorSystem; @PostConstruct
public void init() {
this.errorSystem = new StringBuffer()
.append(this.serverName)
.append(": ").toString();
} /**
* 应用到所有@RequestMapping注解方法,在其执行之前初始化数据绑定器
*/
@InitBinder
public void initBinder(WebDataBinder binder) { } /**
* 把值绑定到Model中,使全局@RequestMapping可以获取到该值
*/
@ModelAttribute
public void addAttributes(Model model) { } /**
* 全局异常捕捉处理
*/
@ExceptionHandler(value = {Exception.class})
public Result handlerException(Exception exception, HttpServletRequest request) {
log.error("请求路径uri={},系统内部出现异常:{}", request.getRequestURI(), exception);
Result result = Result.error(ResultCodeEnum.ERROR, errorSystem + exception.toString());
return result;
} /**
* 非法请求异常
*/
@ExceptionHandler(value = {
HttpMediaTypeNotAcceptableException.class,
HttpMediaTypeNotSupportedException.class,
HttpRequestMethodNotSupportedException.class,
MissingServletRequestParameterException.class,
NoHandlerFoundException.class,
MissingPathVariableException.class,
HttpMessageNotReadableException.class
})
public Result handlerSpringAOPException(Exception exception) {
Result result = Result.error(ResultCodeEnum.ILLEGAL_REQUEST, errorSystem + exception.getMessage());
return result;
} /**
* 非法请求异常-参数类型不匹配
*/
@ExceptionHandler(value = MethodArgumentTypeMismatchException.class)
public Result handlerSpringAOPException(MethodArgumentTypeMismatchException exception) {
Result result = Result.error(ResultCodeEnum.PARAM_TYPE_MISMATCH, errorSystem + exception.getMessage());
return result;
} /**
* 非法请求-参数校验
*/
@ExceptionHandler(value = {MethodArgumentNotValidException.class})
public Result handlerMethodArgumentNotValidException(MethodArgumentNotValidException methodArgumentNotValidException) {
//获取异常字段及对应的异常信息
StringBuffer stringBuffer = new StringBuffer();
methodArgumentNotValidException.getBindingResult().getFieldErrors().stream()
.map(t -> t.getField()+"=>"+t.getDefaultMessage()+" ")
.forEach(e -> stringBuffer.append(e));
String errorMessage = stringBuffer.toString();
Result result = Result.error(ResultCodeEnum.PARAM_VALID_ERROR, errorSystem + errorMessage);
return result;
} /**
* 非法请求异常-参数校验
*/
@ExceptionHandler(value = {ConstraintViolationException.class})
public Result handlerConstraintViolationException(ConstraintViolationException constraintViolationException) {
String errorMessage = constraintViolationException.getLocalizedMessage();
Result result = Result.error(ResultCodeEnum.PARAM_VALID_ERROR, errorSystem + errorMessage);
return result;
} /**
* 自定义业务异常-BusinessException
*/
@ExceptionHandler(value = {BusinessException.class})
public Result handlerCustomException(BusinessException exception) {
String errorMessage = exception.getMsg();
Result result = Result.error(exception.getCode(), errorSystem + errorMessage);
return result;
} /**
* 自定义系统异常-SystemException
*/
@ExceptionHandler(value = {SystemException.class})
public Result handlerCustomException(SystemException exception) {
String errorMessage = exception.getMsg();
Result result = Result.error(exception.getCode(), errorSystem + errorMessage);
return result;
} }

6、重新将GitEgg-Platform进行install,在GitEgg-Cloud中的gitegg-service引入gitegg-platform-boot

<!--?xml version="1.0" encoding="UTF-8"?-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactid>GitEgg-Cloud</artifactid>
<groupid>com.gitegg.cloud</groupid>
<version>1.0-SNAPSHOT</version>
</parent>
<modelversion>4.0.0</modelversion> <artifactid>gitegg-service</artifactid>
<packaging>pom</packaging>
<modules>
<module>gitegg-service-base</module>
<module>gitegg-service-bigdata</module>
<module>gitegg-service-system</module>
</modules> <dependencies>
<!-- gitegg Spring Boot自定义及扩展 -->
<dependency>
<groupid>com.gitegg.platform</groupid>
<artifactid>gitegg-platform-boot</artifactid>
</dependency>
<!-- gitegg数据库驱动及连接池 -->
<dependency>
<groupid>com.gitegg.platform</groupid>
<artifactid>gitegg-platform-db</artifactid>
</dependency>
<!-- gitegg mybatis-plus -->
<dependency>
<groupid>com.gitegg.platform</groupid>
<artifactid>gitegg-platform-mybatis</artifactid>
</dependency>
<!-- gitegg swagger2-knife4j -->
<dependency>
<groupid>com.gitegg.platform</groupid>
<artifactid>gitegg-platform-swagger</artifactid>
</dependency>
<!-- spring boot web核心包 -->
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-web</artifactid>
</dependency>
<!-- spring boot 健康监控 -->
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-actuator</artifactid>
</dependency>
</dependencies> </project>

7、修改SystemController.java、ISystemService.java和SystemServiceImpl.java增加异常处理的测试代码

SystemController.java:

package com.gitegg.service.system.controller;

import com.gitegg.platform.boot.common.base.Result;
import com.gitegg.platform.boot.common.exception.BusinessException;
import com.gitegg.service.system.service.ISystemService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; @RestController
@RequestMapping(value = "system")
@AllArgsConstructor
@Api(tags = "gitegg-system")
public class SystemController { private final ISystemService systemService; @GetMapping(value = "list")
@ApiOperation(value = "system list接口")
public Object list() {
return systemService.list();
} @GetMapping(value = "page")
@ApiOperation(value = "system page接口")
public Object page() {
return systemService.page();
} @GetMapping(value = "exception")
@ApiOperation(value = "自定义异常及返回测试接口")
public Result<string> exception() {
return Result.data(systemService.exception());
}
}

ISystemService.java:

package com.gitegg.service.system.service;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gitegg.service.system.entity.SystemTable; import java.util.List; public interface ISystemService { List<systemtable> list(); Page<systemtable> page(); String exception();
}

SystemServiceImpl.java:

package com.gitegg.service.system.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gitegg.platform.boot.common.exception.BusinessException;
import com.gitegg.service.system.entity.SystemTable;
import com.gitegg.service.system.mapper.SystemTableMapper;
import com.gitegg.service.system.service.ISystemService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service; import java.util.List; /**
*
*/
@Service
@AllArgsConstructor
public class SystemServiceImpl implements ISystemService { private final SystemTableMapper systemTableMapper; @Override
public List<systemtable> list() {
return systemTableMapper.list();
} @Override
public Page<systemtable> page() {
Page<systemtable> page = new Page<>(1, 10);
List<systemtable> records = systemTableMapper.page(page);
page.setRecords(records);
return page;
} @Override
public String exception() {
throw new BusinessException("自定义异常");
// return "成功获得数据";
}
}

8、运行GitEggSystemApplication,打开浏览器访问:http://127.0.0.1:8001/doc.html,然后点击左侧的异常处理接口,使用Swagger2进行测试,即可看到结果

本文源码在https://gitee.com/wmz1930/GitEgg 的chapter-07分支。

SpringCloud微服务实战——搭建企业级开发框架(七):自定义通用响应消息及统一异常处理的更多相关文章

  1. SpringCloud微服务实战——搭建企业级开发框架(二十三):Gateway+OAuth2+JWT实现微服务统一认证授权

      OAuth2是一个关于授权的开放标准,核心思路是通过各类认证手段(具体什么手段OAuth2不关心)认证用户身份,并颁发token(令牌),使得第三方应用可以使用该token(令牌)在限定时间.限定 ...

  2. SpringCloud微服务实战——搭建企业级开发框架(二):环境准备

    这里简单说明一下在Windows系统下开发SpringCloud项目所需要的的基本环境,这里只说明开发过程中基础必须的软件,其他扩展功能(Docker,k8s,MinIO,XXL-JOB,EKL,Ke ...

  3. SpringCloud微服务实战——搭建企业级开发框架(三十四):SpringCloud + Docker + k8s实现微服务集群打包部署-Maven打包配置

      SpringCloud微服务包含多个SpringBoot可运行的应用程序,在单应用程序下,版本发布时的打包部署还相对简单,当有多个应用程序的微服务发布部署时,原先的单应用程序部署方式就会显得复杂且 ...

  4. SpringCloud微服务实战——搭建企业级开发框架(四十四):【微服务监控告警实现方式一】使用Actuator + Spring Boot Admin实现简单的微服务监控告警系统

      业务系统正常运行的稳定性十分重要,作为SpringBoot的四大核心之一,Actuator让你时刻探知SpringBoot服务运行状态信息,是保障系统正常运行必不可少的组件.   spring-b ...

  5. SpringCloud微服务实战——搭建企业级开发框架(三十六):使用Spring Cloud Stream实现可灵活配置消息中间件的功能

      在以往消息队列的使用中,我们通常使用集成消息中间件开源包来实现对应功能,而消息中间件的实现又有多种,比如目前比较主流的ActiveMQ.RocketMQ.RabbitMQ.Kafka,Stream ...

  6. SpringCloud微服务实战——搭建企业级开发框架(三十七):微服务日志系统设计与实现

      针对业务开发人员通常面对的业务需求,我们将日志分为操作(请求)日志和系统运行日志,操作(请求)日志可以让管理员或者运营人员方便简单的在系统界面中查询追踪用户具体做了哪些操作,便于分析统计用户行为: ...

  7. SpringCloud微服务实战——搭建企业级开发框架(三十八):搭建ELK日志采集与分析系统

      一套好的日志分析系统可以详细记录系统的运行情况,方便我们定位分析系统性能瓶颈.查找定位系统问题.上一篇说明了日志的多种业务场景以及日志记录的实现方式,那么日志记录下来,相关人员就需要对日志数据进行 ...

  8. SpringCloud微服务实战——搭建企业级开发框架(四十):使用Spring Security OAuth2实现单点登录(SSO)系统

    一.单点登录SSO介绍   目前每家企业或者平台都存在不止一套系统,由于历史原因每套系统采购于不同厂商,所以系统间都是相互独立的,都有自己的用户鉴权认证体系,当用户进行登录系统时,不得不记住每套系统的 ...

  9. SpringCloud微服务实战——搭建企业级开发框架(四十二):集成分布式任务调度平台XXL-JOB,实现定时任务功能

      定时任务几乎是每个业务系统必不可少的功能,计算到期时间.过期时间等,定时触发某项任务操作.在使用单体应用时,基本使用Spring提供的注解即可实现定时任务,而在使用微服务集群时,这种方式就要考虑添 ...

随机推荐

  1. MySQL——MySQL多实例

    一台服务器上运行多个MySQL服务,不同的业务 多实例思路: 1. 多套配置文件 2. 多套数据 3. 多个socket 4. 多个端口 5. 多个日志文件 6. 多个启动程序

  2. Django项目中的模板继承

    1. 定义一个基础的页面HTML文件base.html <!DOCTYPE html> <html lang="en"> <head> < ...

  3. Walker

      emmm.......随机化.   好吧,我们不熟.   考虑随机选取两组数据高斯消元消除结果后带入检验,能有超过1/2正确就输出.   其实方程就四个,手动解都没问题.   只是要注意看sin与 ...

  4. 浅析mybatis中${}和#{}取值区别

    mybatis作为一个轻量级的ORM框架,应用广泛,其上手使用也比较简单:一个成熟的框架,必然有精巧的设计,值得学习. 在使用mybatis框架时,在sql语句中获取传入的参数有如下两种方式: ${p ...

  5. 生产环境部署高可用Rancher

    环境准备: IP hostname role 192.168.200.150 nginx LB 192.168.200.151 master01-151 docker-ce/rke/helm/kube ...

  6. Learning How to Learn 学习如何学习

    Introduction 这是 UCSD 开设在 Coursera 上的课程 Learning How to Learn 的课程笔记.这门课程主要基于神经科学和认知心理学的一些研究成果讲述高效学习的理 ...

  7. UVA 506 System Dependencies(模拟 烂题)

    https://vjudge.net/problem/UVA-506 题目是给出了五种指令,DEPEND.INSTALL.REMOVE.LIST.END,操作的格式及功能如下: DEPEND item ...

  8. ESP8266- ESP01之AT固件下载及其他问题

    注意: 本文基于淘宝上买的安信可原装ESP-01,文章中出现的问题在另一片ESP-01S上均未出现.由于在刷固件前没有进行完整测试,因此无法判断是固件导致的还是版本不同造成的. 问题: 1.发热严重. ...

  9. PHP的另一个高效缓存扩展:Yac

    之前的文章中我们已经学习过一个 PHP 自带的扩展缓存 Apc ,今天我们来学习另一个缓存扩展:Yac . 什么是 Yac 从名字其实就能看出,这又是鸟哥大神的作品.毕竟是 PHP 的核心开发人员,他 ...

  10. PHP中命名空间是怎样的存在?(三)

    这是与命名空间有关的最后一篇.最后还是两个比较简单的内容,是关于命名空间和全局相关的一些类.函数.常量的使用对比.当然,最后我们还会总结一下命名空间的名称解析规则做为这三篇系列文章的结束. 全局空间 ...