A063_后端搭建_Lombok_Restful_postman_swagger

项目搭建

内容介绍

1. 项目介绍; (了解)
2. 需求分析; (了解)
3. 项目架构; (掌握)
4. 后端项目搭建; (掌握)
5. swagger (掌握)
6. postman测试 (掌握)

需求分析 需求设计(项目架构)开发 测试 上线

1.项目介绍

  • 本项目是一个(Online To Offline)以宠物为核心打造的宠物乐园o2o项目。随着生活质量提供,人们不再满足简单物质生活,还追求更高层次精神生活。很多人愿意有养宠物意愿,愿意为宠物消费,正是基于这种场景,我们才开发了这个项目。首先让用户领养宠物,然后针对用户的宠物提供上门洗澡,美容,寄养,购买商品,宠物百科等综合服务平台。由用户下单,平台统一分派给线下门店上门服务。平台除了提供针对普通用户的基本需求功能,支持商家入驻,合作加盟,扩展线下门店渠道。

  • O2o:通过互联网手段挖掘机会,最终要到线下消费。

    汽车之家 房屋之家 育儿 婚恋等

2.需求分析

在这里插入图片描述

3.项目架构

3.1.项目技术架构

在这里插入图片描述

后端架构:		springboot+ ssm+ 
				echart+ quartz+
				Javaemail+ 
				Easypoi+redis

前端架构:        vue技术栈:nodejs npm webpack vue vue-cli elementui

服务器:        linux+nginx+docker
数据存储:        mysql +redis+fastdfs
第三方登录      微信 微博 QQ
第三方支付      支付宝扫描支付
第三方短信接口  中国网建

今天:后端项目搭建
明天:前后端整合

3.2.前后端分离

3.2.1. 什么是前后端分离

在传统的web应用开发中,大多数的程序员会将浏览器作为前后端的分界线。将浏览器中为用户进行页面展示的部分称之为前端,而将运行在服务器,为前端提供业务逻辑和数据准备的所有代码统称为后端。
很多人误以为前后端分离只是一种web应用开发模式,只要在web应用的开发期进行了前后端开发工作的分工就是前后端分离。 前后端分工
其实前后端分离并不只是开发模式,而是web应用的一种架构模式。在开发阶段,前后端工程师约定好数据交互接口,实现并行架构,开发和测试;在运行阶段前后端分离模式需要对web应用进行分别部署,前后端之前使用HTTP或者其他协议进行交互请求。然而作为一种架构模式,我们在实施的过程中主要对以下四个方面来进行比较和重新认识。

前后端分离大概可以从以下方面来理解:

3.2.2.交互形式

在这里插入图片描述
在前后端分离架构中,后端只需要负责按照约定的数据格式向前端提供可调用的API服务即可。前后端之间通过HTTP请求进行交互,前端获取到数据后,进行页面的组装和渲染,页面跳转,最终返回给浏览器。

3.2.3.代码组织方式

在这里插入图片描述
在传统架构模式中,前后端代码存放于同一个代码库中,甚至是同一工程目录下。页面中还夹杂着后端代码。前后端工程师进行开发时,都必须把整个项目导入到开发工具中。而前后端分离模式在代码组织形式上有以下两种:

半分离
前后端共用一个代码库,但是代码分别存放在两个工程中。后端不关心或很少 关心前端元素的输出情况,前端不能独立进行开发和测试,项目中缺乏前后端 交互的测试用例。

真分离
前后端代码库分离,前端代码中有可以进行Mock测试(通过构造虚拟测试对 象以简化测试环境的方法)的伪后端,能支持前端的独立开发和测试。而后端 代码中除了功能实现外,还有着详细的测试用例,以保证API的可用性,降低 集成风险。

3.3.前后端分离开发模式

3.3.1.真正前后端分离

在这里插入图片描述
能力要求高,大公司

3.3.2.后端先行

在这里插入图片描述
能力要求低,小公司,刚转型前后端分离的公司

前后端分离全栈项目

3.4.前后端分离优缺点

优点:
分工明确,专业的人做专业的事情。
专业可以做出炫丽优美界面
人员培养更加专业化,精确化
缺点:
成本提高,人员多。
项目管理难度也提高,前后端都要管,协调他们之间交流。

它是趋势,移动互联要求必须有移动端,需要专业前端人员,好多公司都做前后端分离。

4.后端项目搭建

4.1.项目规划

在这里插入图片描述

项目端口规划
后台接口服务8080
后台管理前端8081
门户网站前端80

所有的人都不能用cn.itsource的包名,org/cn.姓名英文

4.2.Idea配置maven

在这里插入图片描述

4.3.整合springboot环境

在这里插入图片描述

1)创建maven项目-用自己的包名
2)Pom 配置父亲

	<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.5.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
    </dependencies>

3)application.yml

server:
  port: 8080

4)入口类

package cn.itsource;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class PetHomeApplication {
    public static void main(String[] args) {
        SpringApplication.run(PetHomeApplication.class,args);
    }
}

5)启动测试
启动测试

4.4.Ssm Crud

Pom.xml 配置文件 入口列 domain maper.java mapper.xml service/impl test controller

4.4.1.pom.xml
<!-- spring-boot整合mybatis -->
		<dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.1.1</version>
        </dependency>
        <!-- mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
        </dependency>
4.4.2.配置文件

application.yml

server:
  port: 8081
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: 0731javaroot
    url: jdbc:mysql://localhost:3306/pethome?useUnicode=true&characterEncoding=UTF-8
mybatis:
  type-aliases-package: cn.itsource.org.domain,cn.itsource.org.query,

准备库和表
入口类打扫描Mapper的标签
@MapperScan(“cn.itsource.*.mapper”)

4.4.3.创建部门domain
public class Department {
    /*主键*/
    private Long id;
    /*部门编号*/
    private String sn;
    /*部门名称*/
    private String name;
    /*暂时不用*/
    private String dirPath;
    /*部门状态 0 正常 ,-1 停用*/
    private int state;
    /*部门经理 和员工关联*/
    //private String manager;
    /*上级部门
    private Department parent;
    private List<Department> children = new ArrayList<>();
*/
}
4.4.4. Lombok

在开发中每个类都需要写getter与setter方法,以及覆写toString。Lombok插件可以让开发中省略这部分重复的工作。

4.4.4.1. 引入相关jar包
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok 
   导入这个jar后,编译后会自动生成相关方法
-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.8</version>
    <scope>provided</scope>
</dependency>

4.4.4.2.IDEA添加插件对于Lombok的支持-编码时也支持

在这里插入图片描述
安装完成以后需要重启idea。

4.4.4.3.常用注解

官方文档:https://projectlombok.org/features/all
在这里插入图片描述

其中@Data注解最常用,标注于类之上,是@ToString,@EqualsAndHashCode、@Getter、@Setter、@RequiredArgsConstructor的综合体。

4.4.5.Mapper接口
public interface DepartmentMapper {
    //基础查询
    void save(Department d);

    void remove(Long id);

    void update(Department d);

    Department loadById(Long id );

    List<Department> loadAll();

    /**
     * 分页查询
     *
     */
    //查询总条数
    Long queryCount(DepartmentQuery query);
    //查询当前的页数
    List<Department> queryData(DepartmentQuery query);
    
}

注意:DepartmentQuery 为Department的查询查询类,其中包括分页数据,以及关键字查询。

4.4.6.DepartmentMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="cn.itsource.org.mapper.DepartmentMapper">
    <!--//保存对象-->
    <!--void save(Department department);-->
    <insert id="save" parameterType="Department">
        insert into t_department(
            sn,
            name,
            dirPath,
            state,
            manager_id,
            parent_id

        )values(
            #{sn},
            #{name},
            #{dirPath},
            #{state},
            #{manager.id},
            #{parent.id}

        )


    </insert>

    <!--//移除一个对象-->
    <!--void remove(Long id);-->
    <delete id="remove" parameterType="long">
        delete from t_department where id = #{id}
    </delete>

    <!--//更新一个对象-->
    <!--void update(Department department);-->
    <update id="update" parameterType="Department">
        update t_department set
            sn=#{sn},
            name=#{name},
            dirPath=#{dirPath},
            state=#{state},
            manager_id=#{manager.id},
            parent_id=#{parent.id}
        where id = #{id}

    </update>

    <!--//加载一个对象-->
    <!--Department loadById(Long id);-->
    <select id="loadById" parameterType="long" resultType="Department">
          select * from t_department where id = #{id}
    </select>
    <!--//加载所有对象-->
    <!--List<Department> loadAll();-->
    <select id="loadAll" resultType="Department">
        select * from t_department
    </select>

    <!--//分页相关的,查询总数,查询当前页数据-->
    <!--Long queryCount(DepartmentQuery query);-->
    <select id="queryCount" parameterType="DepartmentQuery" resultType="long">
        select count(*) from t_department
    </select>
    <!--List<Department> queryData(DepartmentQuery query);-->
    <select id="queryData" parameterType="DepartmentQuery" resultType="Department">
        select * from t_department
        limit #{start},#{pageSize}
    </select>

</mapper>
4.4.7.Service
public interface IDepartmentService {
    void add(Department d);

    void upadte(Department d);

    void del(Long id );

    Department getById(Long id );

    List<Department> getAll();

    /*
     分页查询
     */
    PageList<Department> queryData(DepartmentQuery query);
}

PageList 页面返回的数据:

/**
 * 分页以后给页面返回的数据
 * @param <T>
 */
public class PageList<T> {
    //总条数
    private Long tatal=0L;
    //页面展示的数据
    private List<T> rows = new ArrayList<>();

    public PageList() {
    }

    public PageList(Long tatal, List<T> rows) {
        this.tatal = tatal;
        this.rows = rows;
    }
}

实现类代码:

@Service
//类级别事务为读事务,分别在增删改的方法上面加写事务
@Transactional(readOnly = true,propagation = Propagation.SUPPORTS)
public class DepartmentServiceImpl implements IDepartmentService {
    @Autowired
    private DepartmentMapper departmentMapper;
    @Override
    @Transactional
    public void add(Department d) {
        departmentMapper.save(d);

    }

    @Override
    @Transactional
    public void upadte(Department d) {
        departmentMapper.update(d);

    }

    @Override
    @Transactional
    public void del(Long id) {
        departmentMapper.remove(id);

    }

    @Override
    public Department getById(Long id) {
        return departmentMapper.loadById(id);
    }

    @Override
    public List<Department> getAll() {
        return departmentMapper.loadAll();
    }

    @Override
    public PageList<Department> queryData(DepartmentQuery query) {
        Long total = departmentMapper.queryCount(query);
        if (total==null || total.intValue()<1){
            return new PageList<>();
        }
        List<Department> list = departmentMapper.queryData(query);

        return new PageList<>(total,list);
    }
}
4.4.8.测试

在这里插入图片描述
在这里插入图片描述

4.4.9.Controller
 见4.5

4.5.Controller

4.5.1.什么是Restful风格

Restful是一种面向资源的架构风格,可以简单理解为:使用URL定位资源,用HTTP动词(GET,POST,DELETE,PUT,PATCH(批量操作))描述操作。

get 	http://127.0.0.1:8080/user/1 	获取用户
delete 	http://127.0.0.1:8080/user/1 	删除用户
put 	http://127.0.0.1:8080/user/  	修改用户
{
   Id:1
    Name:zs
}
Post	 http://127.0.0.1:8080/user/ 	添加用户
{
   Name:zs
}
4.5.2.Restful好处
  1. 拥有http的优点
    本身就是http,无状态,不用关心两次访问上下文.
  2. 透明性,暴露资源存在
    看到命令就知道要做什么了
  3. 充分利用 HTTP 协议本身语义。
    原来只用get,post,现在连delete和put
4.5.3.特征
  1. 资源使用名词表示
    资源是通过url描述,也就是在url不要出现动词

  2. 使用http动词来描述操作
    get 获取 post新增 put修改 delete删除 patch批量操作

    json:数据传输方式之一
    对象:{}
    数组:[{},{}]

4.5.4.Controller实现
@GetMapping("xx")
@PostMapping("xx")
@DeleteMapping
@PutMapping
@RequestMapping(value = "xx",method = RequestMethod.POST)
package cn.itsource.org.controller;
import cn.itsource.basic.util.AjaxResult;
import cn.itsource.basic.util.PageList;
import cn.itsource.org.domain.Department;
import cn.itsource.org.query.DepartmentQuery;
import cn.itsource.org.service.IDepartmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.util.List;

@RestController //@Controller+@ResponseBody(转换json)
@RequestMapping("/department")
public class DepartmentController {

    @Autowired
    private IDepartmentService departmentService;

    //传对象就用@RequestBody
    @PutMapping //添加或修改
    public AjaxResult addOrUpdate(@RequestBody Department department) {

        try {
            if (department.getId() != null) {
                departmentService.update(department);
            } else {
                departmentService.add(department);
            }

            return AjaxResult.me();
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.me().setSuccess(false).setMessage("保存失败!" + e.getMessage());
        }

    }


    @DeleteMapping("/{id}") // /department/1
    public AjaxResult delete(@PathVariable("id") Long id) {
        try {
            departmentService.delete(id);
            return AjaxResult.me();
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.me().setSuccess(false).setMessage("删除失败!" + e.getMessage());
        }
    }


    @GetMapping("/{id}")
    public Department get(@PathVariable("id") Long id){
        return departmentService.getById(id);
    }


    @GetMapping
    public List<Department> getAll(){
        return departmentService.getAll();
    }

    //axios get不支持传对象
    @PostMapping
    public PageList<Department> list(@RequestBody DepartmentQuery query){

        return departmentService.queryPage(query);
    }



}

AjaxResult :前台调用返回的数据

**
 * 有些controller的操作以后的返回,只关心成功与否,以及失败了的原因
 *  而且应该返回值是json数据。 {success:true/false,message:"系统错误“,resultObj:{}}
 *  方案1; 后台拼接字符串返回 太麻烦,代码可读性差
 *  方案2: 其实可以使用spirngmvc的自动转换json的功能
 *        第一步:封装对象
 *       封装一个对象,里面有两个属性 success ,message
 *       到时候我构造一个对象返回,spirngmvc会自动帮我转换。
 *       第二步:默认构造函数
 *
     *  //成功的时候调用
     public AjaxResult() {
     }

     //失败的时候调用
     public AjaxResult(String message) {
     this.success = false;
     this.message = message;

       //第三步:配置链式编程

      //第四步:除了成功与否,还需要带一些额外数据到前台
 }
 */
@Data
public class AjaxResult {

    private boolean success = true;
    private String message = "操作成功!";

    private Object resultObj;
    private Serializable sessionId;

    public boolean isSuccess() {
        return success;
    }

    //链式编程,可以继续. 设置完成后自己对象返回
    public AjaxResult setSuccess(boolean success) {
        this.success = success;
        return this;
}

    public AjaxResult setResultObj(Object resultObj){
        this.resultObj = resultObj;
        return  this;
    }

    public String getMessage() {
        return message;
    }

    public AjaxResult setMessage(String message) {
        this.message = message;
        return this;
    }

    //默认成功
    public AjaxResult() {
    }

    //失败调用
    public AjaxResult(String message) {
        this.success = false;
        this.message = message;
    }

    //不要让我创建太多对象
    public static AjaxResult me(){
        return new AjaxResult();
    }

    public static void main(String[] args) {
        AjaxResult.me().setMessage("xxx").setSuccess(false);
    }
}

如果是get请求还可以通过浏览器测试,但是其他请求就不行了。

4.6.Postman接口测试

我们基于springmvc写的controller对于前端来说就是接口,而且都是通过http协议访问,那后台写完后怎么测试呢?浏览器,只支持get。 要使用一些能够发送http各种请求的工具,其中postman就是很重要的一个。

4.6.1.什么是postman

就是一个工具,可以来发送各种http请求,可以用它来测试http协议接口.
postman就是httm协议接口测试工具

4.6.2.入门
4.6.2.1.下载安装

略过

4.6.2.2.注册和登录

略过

64009120@qq.com / hmtest123/hmtest123

4.6.2.3.测试crud接口

在这里插入图片描述

查询所有
在这里插入图片描述

添加
在这里插入图片描述

删除
略过

修改
在这里插入图片描述

4.7.接口规范swagger

4.7.1.为什么需要

1)接口测试人员要通过接口描述测试接口 --黑盒测试
2)前端开发人员要通过接口描述使用接口.

测试 怎么测试接口
前端人员 后端人员

怎么描述???
1)写接口doc文档
直接罗列所有接口,每个接口有访问地址(访问方式),参数及返回值.
2)可以直接通过后端代码产生能够让前台开发或测试人员能够看懂就ok—swagger文档 json,yml,页面展示 采纳

4.7.2.实现

添加swagger的jar包:

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>

添加配置类:

@Configuration
@EnableSwagger2
public class SwaggerConfig {
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                //对外暴露服务的包,以controller的方式暴露,所以就是controller的包.
                .apis(RequestHandlerSelectors.basePackage("cn.itsource"))
                .paths(PathSelectors.any())
                .build();
    }


    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("系统中心api")
                .description("系统中心服务接口文档说明")
                .contact(new Contact("hmtest", "", "hm@itsource.cn"))
                .version("1.0")
                .build();
    }
}

4.7.3.访问接口规范

地址:http://localhost:8080/swagger-ui.html
在这里插入图片描述

@RestController //@Controller+@ResponseBody(转换json)
@RequestMapping("/department")
@Api(tags = "部门接口",description = "部门接口详细描述")
public class DepartmentController {

    @Autowired
    private IDepartmentService departmentService;

    @ApiOperation(value = "部门添加或修改",notes = "如果有id就是修改否则就是添加")
    //传对象就用@RequestBody
    @PutMapping //添加或修改

4.8.小结

按照restfull规范写一个一个crud接口,通过postman来做接口测试,通过swagger来描述接口.

5.课程总结

5.1.重点

1.Mybatis的基本CRUD
2.Restful风格

5.2.难点

1.抽取

5.3.如何掌握

5.4.排错技巧(技巧)

6.常见问题

7.课后练习

1.完成当日代码

8.面试题

9.扩展知识或课外阅读推荐(可选)

9.1.扩展知识

9.2.课外阅读

热门文章

暂无图片
编程学习 ·

C语言二分查找详解

二分查找是一种知名度很高的查找算法&#xff0c;在对有序数列进行查找时效率远高于传统的顺序查找。 下面这张动图对比了二者的效率差距。 二分查找的基本思想就是通过把目标数和当前数列的中间数进行比较&#xff0c;从而确定目标数是在中间数的左边还是右边&#xff0c;将查…
暂无图片
编程学习 ·

GMX 命令分类列表

建模和计算操作命令&#xff1a; 1.1 . 创建拓扑与坐标文件 gmx editconf - 编辑模拟盒子以及写入子组(subgroups) gmx protonate - 结构质子化 gmx x2top - 根据坐标生成原始拓扑文件 gmx solvate - 体系溶剂化 gmx insert-molecules - 将分子插入已有空位 gmx genconf - 增加…
暂无图片
编程学习 ·

一文高效回顾研究生课程《数值分析》重点

数值分析这门课的本质就是用离散的已知点去估计整体&#xff0c;就是由黑盒子产生的结果去估计这个黑盒子。在数学里这个黑盒子就是一个函数嘛&#xff0c;这门课会介绍许多方法去利用离散点最大化地逼近这个函数&#xff0c;甚至它的导数、积分&#xff0c;甚至微分方程的解。…
暂无图片
编程学习 ·

在职阿里5年,一个28岁女软测工程师的心声

简单的先说一下&#xff0c;坐标杭州&#xff0c;14届本科毕业&#xff0c;算上年前在阿里巴巴的面试&#xff0c;一共有面试了有6家公司&#xff08;因为不想请假&#xff0c;因此只是每个晚上去其他公司面试&#xff0c;所以面试的公司比较少&#xff09; ​ 编辑切换为居中…
暂无图片
编程学习 ·

字符串左旋c语言

目录 题目&#xff1a; 解题思路&#xff1a; 第一步&#xff1a; 第二步&#xff1a; 第三步&#xff1a; 总代码&#xff1a; 题目&#xff1a; 实现一个函数&#xff0c;可以左旋字符串中的k个字符。 例如&#xff1a; ABCD左旋一个字符得到BCDA ABCD左旋两个字符…
暂无图片
编程学习 ·

设计模式--观察者模式笔记

模式的定义与特点 观察者&#xff08;Observer&#xff09;模式的定义&#xff1a;指多个对象间存在一对多的依赖关系&#xff0c;当一个对象的状态发生改变时&#xff0c;所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式、模型-视图模式&#xf…
暂无图片
编程学习 ·

睡觉突然身体动不了,什么是睡眠痽痪症

很多朋友可能有这样的体验&#xff0c;睡觉过程中突然意识清醒&#xff0c;身体却动弹不了。这时候感觉非常恐怖&#xff0c;希望旁边有一个人推自己一下。阳光以前也经常会碰到这样的情况&#xff0c;一年有一百多次&#xff0c;那时候很害怕晚上到来&#xff0c;睡觉了就会出…
暂无图片
编程学习 ·

深入理解C++智能指针——浅析MSVC源码

文章目录unique_ptrshared_ptr 与 weak_ptrstd::bad_weak_ptr 异常std::enable_shared_from_thisunique_ptr unique_ptr 是一个只移型别&#xff08;move-only type&#xff0c;只移型别还有std::mutex等&#xff09;。 结合一下工厂模式&#xff0c;看看其基本用法&#xff…
暂无图片
编程学习 ·

@TableField(exist = false)

TableField(exist false) //申明此字段不在数据库存在&#xff0c;但代码中需要用到它&#xff0c;通知Mybatis-plus在做写库操作是忽略它。,.
暂无图片
编程学习 ·

Java Web day15

第十二章文件上传和下载 一、如何实现文件上传 要实现Web开发中的文件上传功能&#xff0c;通常需要完成两步操作&#xff1a;一.是在Web页面中添加上传输入项&#xff1b;二是在Servlet中读取上传文件的数据&#xff0c;并保存到本地硬盘中。 需要使用一个Apache组织提供一个…
暂无图片
编程学习 ·

【51nod 2478】【单调栈】【前缀和】小b接水

小b接水题目解题思路Code51nod 2478 小b接水 题目 输入样例 12 0 1 0 2 1 0 1 3 2 1 2 1输出样例 6解题思路 可以发现最后能拦住水的都是向两边递减高度&#xff08;&#xff1f;&#xff09; 不管两个高积木之间的的积木是怎样乱七八糟的高度&#xff0c;最后能用来装水的…
暂无图片
编程学习 ·

花了大半天写了一个UVC扩展单元调试工具

基于DIRECTSHOW 实现的&#xff0c;用的是MFC VS2019. 详见&#xff1a;http://www.usbzh.com/article/detail-761.html 获取方法 加QQ群:952873936&#xff0c;然后在群文件\USB调试工具&测试软件\UVCXU-V1.0(UVC扩展单元调试工具-USB中文网官方版).exe USB中文网 USB中文…
暂无图片
编程学习 ·

贪心(一):区间问题、Huffman树

区间问题 例题一&#xff1a;区间选点 给定 N 个闭区间 [ai,bi]请你在数轴上选择尽量少的点&#xff0c;使得每个区间内至少包含一个选出的点。 输出选择的点的最小数量。 位于区间端点上的点也算作区间内。 输入格式 第一行包含整数 N&#xff0c;表示区间数。 接下来 …
暂无图片
编程学习 ·

C语言练习实例——费氏数列

目录 题目 解法 输出结果 题目 Fibonacci为1200年代的欧洲数学家&#xff0c;在他的着作中曾经提到&#xff1a;「若有一只免子每个月生一只小免子&#xff0c;一个月后小免子也开始生产。起初只有一只免子&#xff0c;一个月后就有两只免子&#xff0c;二个月后有三只免子…
暂无图片
编程学习 ·

Android开发(2): Android 资源

个人笔记整理 Android 资源 Android中的资源&#xff0c;一般分为两类&#xff1a; 系统内置资源&#xff1a;Android SDK中所提供的已经定义好的资源&#xff0c;用户可以直接拿来使用。 用户自定义资源&#xff1a;用户自己定义或引入的&#xff0c;只适用于当前应用的资源…
暂无图片
编程学习 ·

零基础如何在短时间内拿到算法offer

​算法工程师是利用算法处理事物的职业 算法&#xff08;Algorithm&#xff09;是一系列解决问题的清晰指令&#xff0c;也就是说&#xff0c;能够对一定规范的输入&#xff0c;在有限时间内获得所要求的输出。 如果一个算法有缺陷&#xff0c;或不适合于某个问题&#xff0c;执…
暂无图片
编程学习 ·

人工智能:知识图谱实战总结

人工智能python&#xff0c;NLP&#xff0c;知识图谱&#xff0c;机器学习&#xff0c;深度学习人工智能&#xff1a;知识图谱实战前言一、实体建模工具Protegepython&#xff0c;NLP&#xff0c;知识图谱&#xff0c;机器学习&#xff0c;深度学习 人工智能&#xff1a;知识图…
暂无图片
编程学习 ·

【无标题】

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注…