(Docker实战) 第六篇:建立持续集成环境03

标签: gblfy技术文档

文章目录

  • 六、 git核心概念
    • 6.1. git学习地址
    • 6.2. github和码云的介绍
    • 6.3. git常用命令和操作
      • 6.3.1. 命令行常用命令
    • 6.3. IDEA操作方法(具体看视频)
      • 6.3.1. 合并分支
      • 6.3.2. compare with
      • 6.3.3. rename
      • 6.3.4. 看历史记录(所有的和单个文件的)
      • 6.3.5. revert 6.stash
      • 6.3.7. cherry pick
      • 6.3.8. reset curent branch
    • 6.4 git技巧
      • 6.4.1. 分支用法实战
      • 6.4.2. 解决冲突
      • 6.4.3. rebase
      • 6.4.4. bug修复流程
        • 6.4.4.1. 暂存手头工作(如果有没完成的工作的话)
        • 6.4.4.2. 新建bugfix分支
        • 6.4.4.3. 测试bug是否修复完成
        • 6.4.4.4. 合并分支
        • 6.4.4.5. 继续进行之前手头上的工作
    • 6.5 maven知识点
      • 6.5.1. 仓库的概念
      • 6.5.2. pom详解
      • 6.5.3. maven命令
      • 6.5.4. 继承
      • 6.5.5. 聚合
      • 6.5.6. 依赖冲突
      • 6.5.7. SNAPSHOT
    • 6.6 maven搭建多模块项目
      • 6.6.1. 建立父模块
      • 6.6.2. 整合两个子模块
      • 6.6.3. 模块A依赖模块B
    • 6.7. spring boot核心原理
      • 6.7.1. 自动配置
      • 6.7.2. 起步依赖
    • 6.8. 简洁代码
    • 6.8.1. 规范统一的类和方法注释
    • 6.8.2. 逻辑的注释
    • 6.9. 组织包结构
      • 6.9.1. config包
      • 6.9.2. core包
      • 6.9.3. modular包
    • 6.10. 常量和枚举
      • 6.10.1. 常量
      • 6.10.2. 枚举
    • 6.11. 接口和抽象类
      • 6.11.1. 接口多用在制定规范
      • 6.11.2. 抽象类多用在封装

六、 git核心概念

6.1. git学习地址

git是开发所需要必备的非常重要的基础技能 https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000

6.2. github和码云的介绍

watch,star和fork的作用,详情见视频

6.3. git常用命令和操作

6.3.1. 命令行常用命令

# 克隆仓库
git clone xxx# 查看当前状态
git status# 新建分支
git checkout -b dev# 切换分支
git checkout dev# 拉取代码
git pull
git pull origin master:master# 提交代码
git push origin master# 打tag
git tag -a v1.0 -m "正式发布1.0"# stash
git stash# unstash
git stash pop

6.3. IDEA操作方法(具体看视频)

6.3.1. 合并分支

6.3.2. compare with

6.3.3. rename

6.3.4. 看历史记录(所有的和单个文件的)

6.3.5. revert 6.stash

6.3.7. cherry pick

6.3.8. reset curent branch

6.4 git技巧

6.4.1. 分支用法实战

master分支:上线用,跟线上代码保持一致。 dev分支:开发分支,开发人员写完提到本分支。 test分支:相对稳定的分支,供上线前的测试。 feature分支:开发部分功能用的分支。 bug分支:修复线上bug用。 分支的作用:一方面分支的建立可以让并行开发互不影响,另一方面,分支的建立可以让代码保留多种状态。

6.4.2. 解决冲突

冲突产生于合并代码,拉取远程代码的时候,会经常遇到。 产生冲突的时候建议用IDEA解决,很智能,很方便,如果你不用IDEA开发,同样的我建议你用IDEA开发,感觉比Eclipse好些。
为了解决冲突时,不会丢失你自己写的本地代码,不要先pull代码,再去提交代码,每次要先commit你的代码再去pull代码,再去解决冲突。这和svn不一样,svn是以一个文件为一个提交单位,git是以一整个commit为一个提交单位。

合并时候,重点是比对,你和别人代码冲突的部分,如果你不确定该用谁的代码,一定要询问和你代码冲突部分是谁写的,你们商量一下,或者直接请示你的项目负责人。

在idea中,出现冲突会提示如下,
在这里插入图片描述

解决冲突过程如下,

在这里插入图片描述

6.4.3. rebase

merge和rebase都可以理解为合并的意思,merge合并之后会产生新的提交记录,rebase不会产生新的记录,而是把所有两个分支的提交归并为一条线上。

在拉取代码的时候,我们一般选rebase,如下
在这里插入图片描述
但是在合并代码的时候我们选merge,为了体现合并的过程,合并代码的时候我们一般用–no-ff模式,禁用fast-forward模式,并加上注释-m

git merge dev --no-ff -m "合并dev到test,增加修改人员接口,修复多个bug,完善查看订单功能,xxxxxxx"

6.4.4. bug修复流程

如果生产环境出现bug,若不是很紧急,可以在dev分支开发,等下次上线一起发布,如果bug需要紧急修复,请按以下步骤进行:

6.4.4.1. 暂存手头工作(如果有没完成的工作的话)

如果手头有没写完的代码,并且不能提交,提交后可能影响别人开发,那么可以把这些没写完的代码进行暂存(git stash),等修复完bug之后,再恢复这些代码(git stash pop),如果用的IDEA,可以选择如下选项
在这里插入图片描述

然后填入备注信息:
在这里插入图片描述

6.4.4.2. 新建bugfix分支

stash完之后,切换到master分支(master为线上的代码),在master分支新建一个bugfix分支,例如订单详情有个bug需要修复

image_1d2puvmr714d959e1lem1chkisp13.png-25.2kB

之后,在此分支修复bug,改完后可不提交到远程仓库,如果多人协作修改这个bug,需要提交到远程分支。

6.4.4.3. 测试bug是否修复完成

代码写完之后,本地进行测试,也可以在jenkins上发布到test环境测试一下,确保bug修复完毕,并且没有影响到其他业务运行。

6.4.4.4. 合并分支

合并刚才创建的bugfix_order_detail分支到master分支,并打标签,如下

git merge bugfix_order_detail --no-ff -m "合并bugfix_order_detail到master,修复了订单详情显示的问题"

上线成功后,可删除掉本地的bugfix_order_detail分支。

6.4.4.5. 继续进行之前手头上的工作

恢复暂存的代码,如下

在这里插入图片描述
或者直接用命令

git stash pop

6.5 maven知识点

6.5.1. 仓库的概念

本地仓库: 本地存放jar包的地方,默认存放路径在路径名为

.m2/respository/

,可以再settings.xml中配置。

  • 中央仓库:
    Maven 中央仓库是由 Maven 社区提供的仓库,其中包含了大量常用的库。中央仓库包含了绝大多数流行的开源Java构件,以及源码、作者信息、SCM、信息、许可证信息等。一般来说,简单的Java项目依赖的构件都可以在这里下载到。

  • nexus私服:
    开发人员自己定制仓库,包含了所需要的代码库或者其他工程中用到的 jar 文件。一般公司都会搭建一个自己的私服,加快jar包下载速度,也可以deploy公司内部的jar包。

6.5.2. pom详解

<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.0http://maven.apache.org/maven-v4_0_0.xsd"><!-- 父项目坐标 --><parent><!--被继承的父项目的构件标识符 --><artifactId /><!--被继承的父项目的全球唯一标识符 --><groupId /><!--被继承的父项目的版本 --><version /><!-- 父项目的pom.xml文件的相对路径 --><relativePath /></parent><!--项目的全球唯一标识符,通常使用全限定的包名区分该项目和其他项目。 --><groupId>asia.banseon</groupId><!-- 构件的标识符,它和group ID一起唯一标识一个构件 --><artifactId>banseon-maven2</artifactId><!--项目产生的构件类型,jar、war、pom。 --><packaging>jar</packaging><!--项目当前版本,格式为:主版本.次版本.增量版本-限定版本号 --><version>1.0-SNAPSHOT</version><!--项目的名称, Maven产生的文档用 --><name>banseon-maven</name><!-- 项目的详细描述, Maven 产生的文档用. --><description>A maven project to study maven.</description><!-- 项目内的一些常量 --><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version><jwt.version>0.9.0</jwt.version></properties><!-- 项目的依赖管理 --><dependencyManagement><dependencies></dependencies></dependencyManagement><!-- 项目的依赖 --><dependencies><dependency><groupId>cn.stylefeng.roses</groupId><artifactId>kernel-core</artifactId><version>1.1.0</version><!-- 排除依赖 --><exclusions><exclusion><artifactId>slf4j-api</artifactId><groupId>org.slf4j</groupId></exclusion></exclusions></dependency></dependencies><!-- 项目构建配置 --><build><!-- 插件 --><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.7.0</version><configuration><source>1.8</source><target>1.8</target></configuration></plugin></plugins><!-- 资源文件夹 --><resources><resource><directory>src/main/resources</directory></resource><resource><directory>src/main/java</directory><includes><include>**/*.xml</include></includes></resource></resources></build><!-- 不同环境构建参数 --><profiles><profile><id>local</id><properties><spring.active>local</spring.active></properties><activation><activeByDefault>true</activeByDefault></activation></profile><profile><id>dev</id><properties><spring.active>dev</spring.active></properties></profile></profiles></project>

6.5.3. maven命令

# 1. 清除工作空间编译的文件
mvn clean# 2. 编译并打包
mvn package# 3. 编译打包构建到本地仓库
mvn install# 4. 发布到远程仓库
mvn deploy# 5. 跳过测试
-Dmaven.test.skip=true

6.5.4. 继承

子maven模块可以继承父maven模块的一些属性。子模块可以用如下一段配置来继承某个父模块。

<parent>  <groupId>com.xxx</groupId><artifactId>parent-project</artifactId><version>0.0.1-SNAPSHOT</version><relativePath>../pom.xml</relativePath>  
</parent>

6.5.5. 聚合

父模块可以用如下一段配置来聚合多个子模块,以便在clean和package等命令时,自动帮我们执行父子模块的操作。一般父模块的packaging属性为pom。

<modules><module>moduleA</module>  <module>moduleB</module>        <module>moduleC</module>
</modules>

6.5.6. 依赖冲突

Maven采用"最近获胜策略"的方式处理依赖冲突。如下图,resolev-web会依赖project-在这里插入图片描述

解决方法: 第一种,显式加入对project-common 2.0版本的依赖。

<dependency>       <groupId>project-common</groupId>      <artifactId>project-commmon</artifactId>  <version>2.0</version>   
</dependency>

第二种,resolve-web对project-A的dependency声明中,将project-common排除掉。

<dependency>  <groupId>project-A</groupId>  <artifactId>project-A</artifactId>  <version>1.0</version>  <exclusions>  <exclusion>  <groupId>project-common</groupId>  <artifactId>project-commmon</artifactId>  </exclusion>  </exclusions>  
</dependency>

6.5.7. SNAPSHOT

在框架持续开发期间,如果该框架被多个项目依赖,每次升级一个版本都要通知被调用的人,版本升级给调用者会带来极大的不便,采用SNAPSHOT可以避免此问题。

正式版本和快照版本的主要区别在于,本地获取这些依赖的机制有所不同。假设你依赖一个库的正式版本,构建的时候构建工具会先在本次仓库中查找是否已经有了这个依赖库,如果没有的话才会去远程仓库中去拉取。

快照版本会每隔一定时间去远程仓库拉去看有没有更新的变化。频率共有四种,分别是always、daily、interval(分钟为单位)、never(跟正式版本一样)。

<repositories><repository><id>xxx</id><url>xxx</url><snapshots><enabled>true</enabled><updatePolicy>always</updatePolicy></snapshots></repository>
</repositories>

6.6 maven搭建多模块项目

6.6.1. 建立父模块

<packing>改为pom,增加<modules>标签

6.6.2. 整合两个子模块

将子模块的parent设置为父模块的坐标信息,相关的<version>可根据继承,减少依赖。

6.6.3. 模块A依赖模块B

如果模块之间需要引用,直接加入对方模块坐标即可

6.7. spring boot核心原理

推荐一本系统讲解spring boot的书籍《Spring Boot实战》Craig Walls著

6.7.1. 自动配置

针对很多spring应用程序常见的应用功能,spring boot能自动提供相关配置。

如何覆盖自动配置?

6.7.2. 起步依赖

告诉spring boot需要什么功能,他就能引入需要的库。

6.8. 简洁代码

6.8.1. 规范统一的类和方法注释

/*** 修改用户状态,返回修改生效的行数** @param userId 用户id* @param status 用户的状态* @return 被修改的行数* @author fengshuonan* @Date 2019/2/24 21:34*/int setStatus(@Param("userId") Long userId, @Param("status") String status);/*** 跳转到角色列表页面** @author fengshuonan* @Date 2018/12/23 6:30 PM*/
@RequestMapping("")
public String index() {return PREFIX + "/role.html";
}

6.8.2. 逻辑的注释

//如果开启了记住我功能
if ("on".equals(remember)) {token.setRememberMe(true);
} else {token.setRememberMe(false);
}//执行shiro登录操作
currentUser.login(token);//登录成功,记录登录日志
ShiroUser shiroUser = ShiroKit.getUserNotNull();
LogManager.me().executeLog(LogTaskFactory.loginLog(shiroUser.getId(), getIp()));

6.9. 组织包结构

在日常开发中,业务模块的包结构划分一般划分为三个config、core、modular

6.9.1. config包

config包存放整个模块的配置类,因为项目基于spring boot开发,大部分的spring配置都换成了java bean方式的配置,所以单独分一个包来存放配置,config包中除了存放配置类,还有一些以Properties结尾的类,这些类的作用是启动应用的时候把application.yml中的配置映射到类的属性上

6.9.2. core包

core包存放当前模块所运行的一些核心机制,例如全局的异常拦截器,日志AOP,权限的AOP,项目初始化后的监听器,工具类等,还可以存放一些对某些框架的扩展,例如对beetl模板的扩展配置和工具类,对flowable的扩展类,shiro的一些拓展类等等

6.9.3. modular包

modular存放按业务划分的业务代码,若本模块中包含多个模块业务,则在modular中建立多个业务包,在具体的业务包下再建立controller、entity、service、factory、mapper、model、service、wrapper这几个包,如果当前模块中只存在一类业务,那么没有必要在modular包下再建立多个业务模块,可直接在modular模块建立controller、entity、service等等

这样拆分的好处在于把业务,配置和运行机制清晰的拆分开,提高项目的可维护性,加快项目的开发效率!

6.10. 常量和枚举

目的:更优雅的写出代码,避免出现魔法值。

6.10.1. 常量

代码中的固定值,一般用public static final标识 常用在某种标识上,比如说缓存前缀标识,系统环境常量等

表现的形势一般分两种:

public class DefaultSystem {public static final String DEFAULT_PWD = "111111";
}
public interface DefaultSystem {String DEFAULT_PWD = "111111";
}

6.10.2. 枚举

一般用在状态和类型等,这样具有可列举的项时使用。

  • //第一种
public enum Color {  RED, GREEN, BLANK, YELLOW  
}
  • //第二种
public enum ManagerStatus {OK("ENABLE", "启用"), FREEZED("LOCKED", "冻结"), DELETED("DELETED", "被删除");String code;String message;ManagerStatus(String code, String message) {this.code = code;this.message = message;}public static String getDescription(String value) {...}
}
  • //第三种
public enum BizExceptionEnum implements AbstractBaseExceptionEnum {TOKEN_EXPIRED(700, "token过期"),TOKEN_ERROR(700, "token验证失败");...@Overridepublic Integer getCode() {return code;}@Overridepublic String getMessage() {return message;}
}

6.11. 接口和抽象类

6.11.1. 接口多用在制定规范

1.Feign远程接口使用接口

@RequestMapping("/api/dict")
public interface DictApi {@RequestMapping(value = "/addDict", method = RequestMethod.POST)void addDict(@RequestBody Dict dict);@RequestMapping(value = "/updateDict", method = RequestMethod.POST)void updateDict(@RequestBody Dict dict);@RequestMapping(value = "/deleteDict", method = RequestMethod.POST)void deleteDict(@RequestParam("dictId") Long dictId);
}

2.作为方法参数,用一个接口,接收不同子类

public interface AbstractBaseExceptionEnum {/*** 获取异常的状态码*/Integer getCode();/*** 获取异常的提示信息*/String getMessage();
}

3.为了拓展,写不同的实现,切换时,减少代码修改量

public interface SmsManager {/*** 发送短信** @param phoneNumber  电话号码* @param templateCode 模板号码* @param params       模板里参数的集合* @author fengshuonan* @Date 2018/7/6 下午2:32*/void sendSms(String phoneNumber, String templateCode, Map<String, Object> params);}

有需要拓展的地方,预判是否需要接口。

6.11.2. 抽象类多用在封装

1.封装模板代码,模板方法模式里常用

public abstract class AbstractTreeBuildFactory<T> {/*** 树节点构建整体过程** @author fengshuonan* @Date 2018/7/26 上午9:45*/public List<T> doTreeBuild(List<T> nodes) {//构建之前的节点处理工作List<T> readyToBuild = beforeBuild(nodes);//具体构建的过程List<T> builded = executeBuilding(readyToBuild);//构建之后的处理工作return afterBuild(builded);}/*** 构建之前的处理工作** @author fengshuonan* @Date 2018/7/26 上午10:10*/protected abstract List<T> beforeBuild(List<T> nodes);/*** 具体的构建过程** @author fengshuonan* @Date 2018/7/26 上午10:11*/protected abstract List<T> executeBuilding(List<T> nodes);/*** 构建之后的处理工作** @author fengshuonan* @Date 2018/7/26 上午10:11*/protected abstract List<T> afterBuild(List<T> nodes);
}

2.封装核心算法到抽象类,子类只需继承,并编写一小部分逻辑实现整个类功能

public abstract class BaseControllerWrapper {...@SuppressWarnings("unchecked")public <T> T wrap() {/*** 包装结果*/if (single != null) {wrapTheMap(single);}if (multi != null) {for (Map<String, Object> map : multi) {wrapTheMap(map);}}/*** 根据请求的参数响应*/if (page != null) {return (T) page;}if (pageResult != null) {return (T) pageResult;}if (single != null) {return (T) single;}if (multi != null) {return (T) multi;}return null;}protected abstract void wrapTheMap(Map<String, Object> map);
}

5.5 业务异常

  1. 场景
    试着想象一下下面的场景

例如一个下单逻辑,首先经过Controller,之后Controller调用了AService,Aservice调用了BService,Bservice调用了CService

经过了这4层的业务逻辑后,在CService的代码里有个判断,如下

if(用户余额 < 0){
直接返回这个“用户余额”为0的消息给前端
}
常规的方法,CService返回给BService,B返回给A,A返回给控制器

那么,有没有更方便的方法?

有的,那就是用自定义异常

  1. 如何使用
    首先,创建一个属于系统的自定义异常
/*** 业务异常的封装** @author fengshuonan* @date 2016年11月12日 下午5:05:10*/
public class ServiceException extends RuntimeException {private Integer code;private String errorMessage;public ServiceException(Integer code, String errorMessage) {super(errorMessage);this.code = code;this.errorMessage = errorMessage;}public ServiceException(AbstractBaseExceptionEnum exception) {super(exception.getMessage());this.code = exception.getCode();this.errorMessage = exception.getMessage();}...
}

那么,如何使用,在程序的控制器层,service层都可以抛出异常

//判断当前用户id不是超级管理员的用户id,一言不合就抛出异常
if (userId.equals(Const.ADMIN_ID)) {
throw new ServiceException(BizExceptionEnum.CANT_CHANGE_ADMIN);
}
如果程序制定到这个逻辑,判断成立的话,看一下前端接收到内容是啥

{
“code”:600,
“data”:"",
“exceptionClazz”:"",
“message”:“不能删除超级管理员”,
“success”:false
}
疑问?在哪里拦截的异常

  1. 统一拦截异常
    全局统一拦截的异常,cn.stylefeng.guns.core.aop.GlobalExceptionHandler

@ControllerAdvice控制器加强

@ExceptionHandler(ServiceException.class)拦截制定参数的异常,拦截到之后执行方法内的逻辑

@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)返回前端的http状态码

整体写法跟spring mvc的控制器很相似

@ControllerAdvice
@Order(-1)
public class GlobalExceptionHandler {

/*** 拦截业务异常*/
@ExceptionHandler(ServiceException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public ErrorResponseData bussiness(ServiceException e) {return new ErrorResponseData(e.getCode(), e.getMessage());
}...

}
6.1 项目导入和运行
1.项目导入
登录https://gitee.com/stylefeng/roses,找到子项目地址 image.png-48.6kB

可fork之后clone,也可直接下载zip包 image.png-86kB

之后打开idea点open,选择下载的项目即可 image.png-16.5kB

2.项目的运行
导入完所有项目后,可按如下步骤启动各个组件

启动roses-config-server配置中心
启动roses-cloud-register注册中心
启动roses-spring-boot-admin监控中心
启动roses-system系统管理基础服务
启动roses-gateway网关

3.如何修改roses-kernel核心框架
如果公司业务的开发,需要涉及到框架的修改,则可以导入roses-kernel项目,然后修改,升级版本,mvn install到本地仓库或者公司的私服(推荐)即可。

6.2 快速开发微服务
1.服务提供者
在roses-system开发一个provider作为服务提供者。

1.编写api

/**

  • 示例服务

  • @author fengshuonan

  • @Date 2019/3/7 8:17 PM
    */
    @RequestMapping("/api/example")
    public interface ExampleSysApi {

    /**

    • 测试远程接口
    • @author fengshuonan
    • @Date 2019/3/7 8:17 PM
      */
      @RequestMapping(value = “/test1”, method = RequestMethod.POST)
      ResponseData test1(@RequestParam(“param”) String param);

}
2.编写provider

/*** 测试提供者** @author fengshuonan* @Date 2019/3/7 8:18 PM*/
@RestController
public class ExampleSysProvider implements ExampleSysApi {@Autowiredprivate SysUserService sysUserService;@Overridepublic ResponseData test1(String param) {List<SysUser> list = sysUserService.list();return ResponseData.success(list);}
}

2.服务消费者
1.引入openfeign包

org.springframework.cloud spring-cloud-starter-openfeign 2.启动类增加注解
@EnableFeignClients
@EnableDiscoveryClient
3.配置eureka注册地址eureka:instance:prefer-ip-address: truelease-expiration-duration-in-seconds: 20   lease-renewal-interval-in-seconds: 5      client:service-url:defaultZone: http://127.0.0.1:8761/eurekaregistry-fetch-interval-seconds: 10  

4.编写消费者接口

/*** 测试服务消费者** @author fengshuonan* @date 2018-08-07-下午3:12*/
@FeignClient("roses-system")
public interface ExampleServiceConsumer extends ExampleSysApi {}

5.注入消费者,调用接口,编写测试

/*** 网关服务** @author fengshuonan* @Date 2017/11/10 上午11:24*/
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@EnableFeignClients(basePackages = "cn.stylefeng.roses.gateway.modular.consumer")
@EnableZuulProxy
public class RosesGatewayApplication {@Autowiredprivate ExampleServiceConsumer exampleServiceConsumer;public static void main(String[] args) {SpringApplication.run(RosesGatewayApplication.class, args);}@Beanpublic CommandLineRunner commandLineRunner() {return new CommandLineRunner() {@Overridepublic void run(String... args) throws Exception {System.out.println(exampleServiceConsumer.test1("123"));}};}}

想学习更多微服务、分布式、中间件、数据库、项目快速构建等系列技术
请访问http://gblfy.com
让我们一起进步!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/520975.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

程序员:站在“自学”鄙视链顶端的王者

我在大学的时候&#xff0c;真的遇到一个神人&#xff0c;叫他小马吧。几乎没见过小马上课&#xff0c;第一节实验课就完成全学期所有实验&#xff0c;大一就自学大二课程&#xff0c;大四还没毕业就拿到了阿里offer&#xff0c;然后在我们苦兮兮找工作的时候&#xff0c;人家已…

用户需求源源不断,阿里云网络创新不止

2018杭州云栖大会&#xff0c;阿里云网络产品重点介绍了两个创新产品&#xff0c;智能接入网关和云企业网&#xff0c;以及全球领先的云网络系统&#xff0d;飞天洛神。智能接入网关是业内主要云服务商中第一家提供这样产品的&#xff0c;云企业网更是业内首创的多地域互联产品…

漫画:要跳槽?这道缓存设计题你有必要看看!

戳蓝字“CSDN云计算”关注我们哦&#xff01;作者 | 程序员吴小胖责编 | 阿秃金九银十招聘季&#xff0c;社畜跳槽&#xff0c;学生出笼&#xff0c;也是非常热闹。不过今年继续互联网寒冬&#xff0c;能苟着还是苟着吧&#xff0c;猥琐发育别浪。苟着除了写Bug&#xff0c;还…

阿里云高级技术专家赵伟:安全加速 SCDN 设计与案例

此前&#xff0c;阿里云发布了SCDN安全加速解决方案&#xff0c;在CDN加速的基础上&#xff0c;将专业的安全能力赋能 CDN&#xff0c;实现既有加速又有安全的服务。在本次杭州云栖-飞天技术汇CDN与边缘计算专场中&#xff0c;阿里云高级技术专家赵伟从业务背景、架构设计和客户…

新品发布、降价普惠、拥抱开源、出海全球化 | 杭州云栖企业数字化转型峰会上的那些关键词

9月19日&#xff0c;在杭州云栖大会 - 企业数字化转型峰会现场&#xff0c;阿里巴巴中间件产品总监赵林分享了2018 Aliware的最新产品动态。本文将为您梳理Aliware在出海全球化、开源支持、消息队列高级特性降价、链路追踪新品发布、应用高可用新品发布、CloudToolkit 新品发布…

华为获颁中国首个5G基站设备进网许可证:可支持中国规模部署;IBM推出新一代企业平台Z15;Testin最新AI产品发布……...

关注并标星星CSDN云计算极客头条&#xff1a;速递、最新、绝对有料。这里有企业新动、这里有业界要闻&#xff0c;打起十二分精神&#xff0c;紧跟fashion你可以的&#xff01;每周两次&#xff0c;打卡即read更快、更全了解泛云圈精彩newsgo go go 荣耀V30 5G手机概念图&#…

php数组 函数,PHP array_uintersect_uassoc() 函数

PHP array_uintersect_uassoc() 函数PHP Array 函数定义和用法array_uintersect_uassoc 函数带索引检查计算数组的交集&#xff0c;用回调函数来比较数据和索引。array_uintersect_uassoc() 返回一个数组&#xff0c;该数组包含了所有在 array1 中也同时出现在所有其它参数数组…

p沟道mos管导通条件_打开知识大门的捷径!MOS管基本认识

01三个极的判定G极(gate)—栅极&#xff0c;不用说比较好认 S极(source)—源极&#xff0c;不论是P沟道还是N沟道&#xff0c;两根线相交的就是 D极(drain)—漏极&#xff0c;不论是P沟道还是N沟道&#xff0c;是单独引线的那边02N沟道与P沟道判别箭头指向G极的是N沟道 箭头背向…

大繁至简,首度揭秘阿里云飞天洛神系统

“最好的网络就像神一样&#xff0c;无处不在&#xff0c;又感知不到她的存在 …… 大繁至简&#xff0c;这是我们努力的方向。” – 阿里云网络高级技术专家 孙成浩 2018杭州云栖大会的主会场上&#xff0c;阿里云产品总监何云飞介绍了阿里云自主研发的云操作系统飞天的全…

(Docker实战) 第2篇:Centos7 拉取和部署Gitlab

文章目录搭建gitlab1. 拉取并运行gitlab所需要的redis镜像2. 拉取并运行gitlab所需要的postgresql镜像3. 下载并运行gitlab搭建gitlab 参考&#xff1a;https://github.com/sameersbn/docker-gitlab 1. 拉取并运行gitlab所需要的redis镜像 docker run --name gitlab-redis -d…

redis系列:通过队列案例学习list命令

前言 这一篇文章将讲述Redis中的list类型命令&#xff0c;同样也是通过demo来讲述&#xff0c;其他部分这里就不在赘述了。 项目Github地址&#xff1a;https://github.com/rainbowda/learnWay/tree/master/learnRedis/case-list 案例 demo功能是队列&#xff0c;整个demo的…

2019年程序员薪酬报告:平均年薪超70万!40岁后,这类人不“保值”了

Hired 近日发布了《2019 年度薪酬状况报告》&#xff0c;重点结论如下&#xff1a;仅有 23% 的硕士 / 博士表示&#xff0c;高学历带来了高薪&#xff0c;大部分人表示学历不是全部76% 的技术工作者认为&#xff0c;参加编程培训机构对求职有帮助在美国&#xff0c;技术工作者在…

业务代码解构利器--SWAK

简介 业务的不断发展、商品类型的不断增多、不断添加的业务需求使得闲鱼的代码出现“bad smell”——平台代码和业务代码耦合严重难以分离&#xff1b;业务和业务之间代码交织缺少拆解。这也是行业中的通病。为解决此类问题&#xff0c;闲鱼自研了一套技术框架——SWAK。本文带…

(Docker实战) 第4篇:Centos7 拉取和部署Redis

文章目录搭建redis搭建redis docker run --name redis -di --publish 6379:6379 redis:4.0远程验证测试&#xff1a; 想学习更多微服务、分布式、中间件、数据库、项目快速构建等系列技术 请访问http://gblfy.com 让我们一起进步&#xff01;&#xff01;&#xff01;

阿里巴巴上线静态开源站点搭建工具 Docsite

近日&#xff0c;阿里巴巴在Github上线了静态开源站点搭建工具Docsite&#xff0c;这是一款集官网、文档、博客和社区为一体的静态开源站点的解决方案&#xff0c;具有简单易上手、上手不撒手的特质&#xff0c;同时支持react和静态渲染、PC端和移动端、支持中英文国际化、SEO、…

重磅 | 边缘计算核心技术辨析

戳蓝字“CSDN云计算”关注我们哦&#xff01;作者 | 中国电信广研院责编 | 阿秃边缘计算&#xff08;Edge Computing&#xff09;是云计算向边缘的延伸&#xff0c;本文对边缘计算、雾计算、MEC、Cloudlet、分布式云等边缘计算领域相关概念和技术的定义、架构、场景等进行了比…

php请求接口两次,php curl post请求执行一次curl_exce 请求的接口确执行两次

1、php curl post请求接口&#xff0c;打印日志执行了一次curl_exce&#xff0c;但是请求的接口却重复执行两次.2、代码&#xff1a;$ch curl_init();if(false $ch){writeRedisLog(create_curl, $activity_id, $mobile, $user_id, , 0, curl failed to initialize);}curl_set…

(Docker实战) 第5篇:Centos7 拉取和部署搭建 NEXUS私服

文章目录搭建nexus私服1. 安装nexus3&#xff08;admin/admin123&#xff09;2 .配置nexus32.1 新建一个maven2(proxy)仓库2.2. 新建一个maven2(hosted)仓库2.3. 配置public仓库搭建nexus私服 1. 安装nexus3&#xff08;admin/admin123&#xff09; #创建文件夹,安装过程如果…

Nacos发布 v0.2 版本,无缝支持 Spring Cloud 微服务生态及高可用集群模式

近日&#xff0c;阿里巴巴新开源项目Nacos 发布了 v0.2 版本&#xff0c;该版本开始支持完整的Spring生态技术栈&#xff0c;这包括 Spring Framework、Spring Boot和Spring Cloud。 为了让更多的Spring用户可以在生产上基于 Nacos 做微服务平台的服务发现、配置管理、服务管控…

是时候展现真正的技术了!4道程序员智力题你能对几道| IT巨能唠

程序员对很多人来说那就是个神秘组织&#xff0c;高薪、加班多都是他们的代名词。但是&#xff0c;大家好像还忘了一点&#xff0c;那就是他们也绝对聪明&#xff01;黑客、代码天才、编程老手……层出不穷&#xff0c;晦涩的计算机难题也是分分钟搞定&#xff0c;想想就令人神…