swagger的简单介绍

news2024/11/25 4:42:58

 

目录

swagger是什么?

swagger有什么用?

 Swagger包含的工具集:

 swagger的使用步骤:

swagger的相关注解:

  Docket的源码


  • 了解swagger的作用和概念
  • 了解前后端分离
  • 在SpringBoot中集成Swagger 

swagger是什么?

  • swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。
  • 直接运行,可以在线测试API接口,API是前后端的重要联系纽带
  • 支持多种语言(java, php...)
  • 总体目标是使客户端和文件系统作为服务器以同样的速度来更新。
  • 文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步。

swagger有什么用?

  1. 接口文档自动在线生成。
  2. 功能测试。

 Swagger包含的工具集:

  • Swagger-tools:提供各种与Swagger进行集成和交互的工具。例如模式检验、Swagger1.2文档转换成Swagger2.0文档等功能。
  • Swagger-core:用于Java/Scala的Swagger实现。与JAX-RS(Jersey、Resteasy、CXF…)、Servlets和Play框架进行集成。
  • Swagger-js:用于JavaScript的Swagger实现。
  • Swagger-node-express:Swagger模块,用于node.js的Express web应用框架。
  • Swagger-ui:一个无依赖的HTML、JS和CSS集合,可以为Swagger兼容API动态生成优雅文档。
  • Swagger-codegen:一个模板驱动引擎,通过分析用户Swagger资源声明以各种语言生成客户端代码

 swagger的使用步骤:

  1. 引入pomm的相关依赖
  2. 在代码中加入相应的配置,新建config包,写入swaggerConfig配置类
  3. 在basePackage指定的路径下使用swagger(使用api注解)
  4. 启动项目,浏览器打开http://ip:port/swagger-ui.html

swagger 的相关依赖:

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

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

swagger配置信息:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration//设置该类为spring配置类
@EnableSwagger2//开户swagger2
public class SwaggerConfig {

    /**
     * 创建API应用
     * apiInfo() 增加API相关信息
     * 通过select()函数返回一个ApiSelectorBuilder实例,用来控制哪些接口暴露给Swagger来展现,
     * 本例采用指定扫描的包路径来定义指定要建立API的目录。
     * .apis
     *    RequestHandlerSelectors 配置swagger扫描接口的方式
     *       basePackage() 指定要扫描哪些包
     *       any() 全部都扫描
     *       none() 全部不扫描
     *       withClassAnnotation() 扫描类上的注解 参数是一个注解的反射对象
     *       withMethodAnnotation() 扫描包上的注解
     *  .paths
     *    PathSelectors 路径扫描接口
     *       ant 配置以xxx 开头的路径
     *
     * @return
     */

    @Bean //设置该方法的返回值为spring管理的bean
    public Docket restApi() {//配置了swagger的docket的bean实例
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("标准接口")
                .apiInfo(apiInfo("Spring Boot中使用Swagger2构建RESTful APIs", "1.0"))
                .useDefaultResponseMessages(true)
                .forCodeGeneration(false)
                .select()
                
                //RequestHandlerSelectors配置要扫描接口的方式
                .apis(RequestHandlerSelectors.basePackage("com.example.learning.controller"))
                .paths(PathSelectors.any())
                .build();
    }

    /**
     * 创建该API的基本信息(这些基本信息会展现在文档页面中)
     * 访问地址:http://ip:port/swagger-ui.html
     *
     * @return
     */
    private ApiInfo apiInfo(String title, String version) {//配置Swagger页面信息
        return new ApiInfoBuilder()
                .title(title)
                .description("swagger")
                .termsOfServiceUrl("https://swagger.io")
                .contact("swagger")
                .version("1.0")
                .build();//构建者模式,快速构建一个对象
    }
}

 使用swagger

import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Map;

@RestController
@RequestMapping("/api")
@Api(tags = "标准演示接口")
public class ApiController {
    @Resource
    private ObjectMapper mapper;

    @PostMapping("/ps")
    @ApiOperation(value = "接受json参数", notes = "演示json参数是否接受成功")
    public String post(@ApiParam(name = "接收json参数", defaultValue = "{}")
                           @RequestBody String json) throws IOException {
        Map map = mapper.readValue(json, Map.class);
        System.out.println(map);
        return json;
    }
}

swagger的相关注解:

  • @Configuration:表明这是一个配置类
  • @EnableSwagger2:开启Swagger2
  • @Api:放在类上,说明该类的作用。
  • @ApiOperation:放在方法上,说明该方法的作用。
  • @ApiImplicitParams:用在方法上包含一组参数说明。
    • code:数字,例如400
    • message:信息,例如“请求参数没填好”
    • response:抛出异常的类
  • @ApiImplicitParam:用来注解来给方法入参增加说明,一个请求能数。
  • @ApiResponses:用于表示一组响应。
  • @ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息
  • @ApiModel:用对象来接收参数,描述一个Model的信息(一般用于在请求参数无法使用@ApiImplicitParam注解进行描述的时候)
  • @ApiModelProperty:用对象接收参数时,描述对象的一个字段
  • @ApiIgnore:使用该注解忽略这个API
  • @ApiError :发生错误返回的信息

  Docket的源码

/*
    Docket的源码

    Docket中拥有的属性,Swagger可更改这些属性
*/
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package springfox.documentation.spring.web.plugins;

import com.fasterxml.classmate.ResolvedType;
import com.fasterxml.classmate.TypeResolver;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Ordering;
import com.google.common.collect.Sets;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.web.bind.annotation.RequestMethod;
import springfox.documentation.PathProvider;
import springfox.documentation.annotations.Incubating;
import springfox.documentation.builders.BuilderDefaults;
import springfox.documentation.schema.AlternateTypeRule;
import springfox.documentation.schema.AlternateTypeRules;
import springfox.documentation.schema.CodeGenGenericTypeNamingStrategy;
import springfox.documentation.schema.DefaultGenericTypeNamingStrategy;
import springfox.documentation.schema.WildcardType;
import springfox.documentation.service.ApiDescription;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiListingReference;
import springfox.documentation.service.Operation;
import springfox.documentation.service.Parameter;
import springfox.documentation.service.ResponseMessage;
import springfox.documentation.service.SecurityScheme;
import springfox.documentation.service.Tag;
import springfox.documentation.service.VendorExtension;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.schema.GenericTypeNamingStrategy;
import springfox.documentation.spi.service.DocumentationPlugin;
import springfox.documentation.spi.service.contexts.ApiSelector;
import springfox.documentation.spi.service.contexts.DocumentationContext;
import springfox.documentation.spi.service.contexts.DocumentationContextBuilder;
import springfox.documentation.spi.service.contexts.SecurityContext;

public class Docket implements DocumentationPlugin {
    public static final String DEFAULT_GROUP_NAME = "default";
    private final DocumentationType documentationType;
    private final List<SecurityContext> securityContexts = Lists.newArrayList();
    private final Map<RequestMethod, List<ResponseMessage>> responseMessages = Maps.newHashMap();
    private final List<Parameter> globalOperationParameters = Lists.newArrayList();
    private final List<Function<TypeResolver, AlternateTypeRule>> ruleBuilders = Lists.newArrayList();
    private final Set<Class> ignorableParameterTypes = Sets.newHashSet();
    private final Set<String> protocols = Sets.newHashSet();
    private final Set<String> produces = Sets.newHashSet();
    private final Set<String> consumes = Sets.newHashSet();
    private final Set<ResolvedType> additionalModels = Sets.newHashSet();
    private final Set<Tag> tags = Sets.newHashSet();
    private PathProvider pathProvider;
    private List<? extends SecurityScheme> securitySchemes;
    private Ordering<ApiListingReference> apiListingReferenceOrdering;
    private Ordering<ApiDescription> apiDescriptionOrdering;
    private Ordering<Operation> operationOrdering;
    private ApiInfo apiInfo;
    private String groupName;
    private boolean enabled;//是否启动swagger
    private GenericTypeNamingStrategy genericsNamingStrategy;
    private boolean applyDefaultResponseMessages;
    private String host;
    private Optional<String> pathMapping;
    private ApiSelector apiSelector;
    private boolean enableUrlTemplating;
    private List<VendorExtension> vendorExtensions;

    public Docket(DocumentationType documentationType) {
        this.apiInfo = ApiInfo.DEFAULT;
        this.groupName = "default";
        this.enabled = true;
        this.genericsNamingStrategy = new DefaultGenericTypeNamingStrategy();
        this.applyDefaultResponseMessages = true;
        this.host = "";
        this.pathMapping = Optional.absent();
        this.apiSelector = ApiSelector.DEFAULT;
        this.enableUrlTemplating = false;
        this.vendorExtensions = Lists.newArrayList();
        this.documentationType = documentationType;
    }

    public Docket extensions(List<VendorExtension> vendorExtensions) {
        this.vendorExtensions.addAll(vendorExtensions);
        return this;
    }

    public Docket apiInfo(ApiInfo apiInfo) {
        this.apiInfo = (ApiInfo)BuilderDefaults.defaultIfAbsent(apiInfo, apiInfo);
        return this;
    }

    public Docket securitySchemes(List<? extends SecurityScheme> securitySchemes) {
        this.securitySchemes = securitySchemes;
        return this;
    }

    public Docket securityContexts(List<SecurityContext> securityContexts) {
        this.securityContexts.addAll(securityContexts);
        return this;
    }

    public Docket groupName(String groupName) {
        this.groupName = (String)BuilderDefaults.defaultIfAbsent(groupName, this.groupName);
        return this;
    }

    public Docket pathProvider(PathProvider pathProvider) {
        this.pathProvider = pathProvider;
        return this;
    }

    public Docket globalResponseMessage(RequestMethod requestMethod, List<ResponseMessage> responseMessages) {
        this.responseMessages.put(requestMethod, responseMessages);
        return this;
    }

    public Docket globalOperationParameters(List<Parameter> operationParameters) {
        this.globalOperationParameters.addAll(BuilderDefaults.nullToEmptyList(operationParameters));
        return this;
    }

    public Docket ignoredParameterTypes(Class... classes) {
        this.ignorableParameterTypes.addAll(Arrays.asList(classes));
        return this;
    }

    public Docket produces(Set<String> produces) {
        this.produces.addAll(produces);
        return this;
    }

    public Docket consumes(Set<String> consumes) {
        this.consumes.addAll(consumes);
        return this;
    }

    @Incubating("2.3")
    public Docket host(String host) {
        this.host = (String)BuilderDefaults.defaultIfAbsent(host, this.host);
        return this;
    }

    public Docket protocols(Set<String> protocols) {
        this.protocols.addAll(protocols);
        return this;
    }

    public Docket alternateTypeRules(AlternateTypeRule... alternateTypeRules) {
        this.ruleBuilders.addAll(FluentIterable.from(Lists.newArrayList(alternateTypeRules)).transform(this.identityRuleBuilder()).toList());
        return this;
    }

    public Docket operationOrdering(Ordering<Operation> operationOrdering) {
        this.operationOrdering = operationOrdering;
        return this;
    }

    public Docket directModelSubstitute(Class clazz, Class with) {
        this.ruleBuilders.add(this.newSubstitutionFunction(clazz, with));
        return this;
    }

    public Docket genericModelSubstitutes(Class... genericClasses) {
        Class[] arr$ = genericClasses;
        int len$ = genericClasses.length;

        for(int i$ = 0; i$ < len$; ++i$) {
            Class clz = arr$[i$];
            this.ruleBuilders.add(this.newGenericSubstitutionFunction(clz));
        }

        return this;
    }

    public Docket useDefaultResponseMessages(boolean apply) {
        this.applyDefaultResponseMessages = apply;
        return this;
    }

    public Docket apiListingReferenceOrdering(Ordering<ApiListingReference> apiListingReferenceOrdering) {
        this.apiListingReferenceOrdering = apiListingReferenceOrdering;
        return this;
    }

    public Docket apiDescriptionOrdering(Ordering<ApiDescription> apiDescriptionOrdering) {
        this.apiDescriptionOrdering = apiDescriptionOrdering;
        return this;
    }

    public Docket enable(boolean externallyConfiguredFlag) {
        this.enabled = externallyConfiguredFlag;
        return this;
    }

    public Docket forCodeGeneration(boolean forCodeGen) {
        if (forCodeGen) {
            this.genericsNamingStrategy = new CodeGenGenericTypeNamingStrategy();
        }

        return this;
    }

    public Docket pathMapping(String path) {
        this.pathMapping = Optional.fromNullable(path);
        return this;
    }

    @Incubating("2.1.0")
    public Docket enableUrlTemplating(boolean enabled) {
        this.enableUrlTemplating = enabled;
        return this;
    }

    public Docket additionalModels(ResolvedType first, ResolvedType... remaining) {
        this.additionalModels.add(first);
        this.additionalModels.addAll(Sets.newHashSet(remaining));
        return this;
    }

    public Docket tags(Tag first, Tag... remaining) {
        this.tags.add(first);
        this.tags.addAll(Sets.newHashSet(remaining));
        return this;
    }

    public ApiSelectorBuilder select() {
        return new ApiSelectorBuilder(this);
    }

    public DocumentationContext configure(DocumentationContextBuilder builder) {
        return builder.apiInfo(this.apiInfo).selector(this.apiSelector).applyDefaultResponseMessages(this.applyDefaultResponseMessages).additionalResponseMessages(this.responseMessages).additionalOperationParameters(this.globalOperationParameters).additionalIgnorableTypes(this.ignorableParameterTypes).ruleBuilders(this.ruleBuilders).groupName(this.groupName).pathProvider(this.pathProvider).securityContexts(this.securityContexts).securitySchemes(this.securitySchemes).apiListingReferenceOrdering(this.apiListingReferenceOrdering).apiDescriptionOrdering(this.apiDescriptionOrdering).operationOrdering(this.operationOrdering).produces(this.produces).consumes(this.consumes).host(this.host).protocols(this.protocols).genericsNaming(this.genericsNamingStrategy).pathMapping(this.pathMapping).enableUrlTemplating(this.enableUrlTemplating).additionalModels(this.additionalModels).tags(this.tags).vendorExtentions(this.vendorExtensions).build();
    }

    public String getGroupName() {
        return this.groupName;
    }

    public boolean isEnabled() {
        return this.enabled;
    }

    public DocumentationType getDocumentationType() {
        return this.documentationType;
    }

    public boolean supports(DocumentationType delimiter) {
        return this.documentationType.equals(delimiter);
    }

    private Function<AlternateTypeRule, Function<TypeResolver, AlternateTypeRule>> identityRuleBuilder() {
        return new Function<AlternateTypeRule, Function<TypeResolver, AlternateTypeRule>>() {
            public Function<TypeResolver, AlternateTypeRule> apply(AlternateTypeRule rule) {
                return Docket.this.identityFunction(rule);
            }
        };
    }

    private Function<TypeResolver, AlternateTypeRule> identityFunction(final AlternateTypeRule rule) {
        return new Function<TypeResolver, AlternateTypeRule>() {
            public AlternateTypeRule apply(TypeResolver typeResolver) {
                return rule;
            }
        };
    }

    Docket selector(ApiSelector apiSelector) {
        this.apiSelector = apiSelector;
        return this;
    }

    private Function<TypeResolver, AlternateTypeRule> newSubstitutionFunction(final Class clazz, final Class with) {
        return new Function<TypeResolver, AlternateTypeRule>() {
            public AlternateTypeRule apply(TypeResolver typeResolver) {
                return AlternateTypeRules.newRule(typeResolver.resolve(clazz, new Type[0]), typeResolver.resolve(with, new Type[0]), -2147480648);
            }
        };
    }

    private Function<TypeResolver, AlternateTypeRule> newGenericSubstitutionFunction(final Class clz) {
        return new Function<TypeResolver, AlternateTypeRule>() {
            public AlternateTypeRule apply(TypeResolver typeResolver) {
                return AlternateTypeRules.newRule(typeResolver.resolve(clz, new Type[]{WildcardType.class}), typeResolver.resolve(WildcardType.class, new Type[0]), -2147481648);
            }
        };
    }
}

 

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

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

相关文章

Linux网络编程—Day11 高性能服务器程序框架

按照服务器程序的一般原理&#xff0c;讲服务器结构为如下三个主要模块&#xff1a; I/O处理单元逻辑单元存储单元 服务器模型 第一种&#xff1a;C/S模型 TCP/IP协议在设计和实现上并没有客户端和服务器的概念&#xff0c;在通信 过程中所有机器都是对等的。但由于资源&am…

【Linux】Linux开发工具vim

Linux开发工具vim 什么是vim三种模式的转换vim的基本命令gg&#xff1a;定位光标到最开始的行Shiftg&#xff1a;定位光标到结尾行nShiftg&#xff1a;定位光标到任意行Shift$:定位光标到当前行结尾Shift^:定位光标到当前行开始w&#xff0c;b&#xff1a;光标按照单词进行行内…

红黑树 C++

企业里永远是技术驱动理论发展 比起理解红黑树的原理&#xff0c;更重要的是理解红黑树的应用场景&#xff0c;因为某些应用场景的需要&#xff0c;红黑树才会应运而生。 红黑树的特点&#xff1a; 插入&#xff0c;删除&#xff0c;查找都是O(logn)的复杂度。 红黑树的应用…

大数据Doris(二十六):Broker Load基本原理和语法介绍

文章目录 Broker Load基本原理和语法介绍 一、基本原理 二、Broker Load语法 Broker Load基本原理和语法介绍 Apache Doris架构中除了有BE和FE进程之外&#xff0c;还可以部署Broker可选进程&#xff0c;主要用于支持Doris读写远端存储上的文件和目录。例如&#xff1a;Apa…

spring boot +Sa-Token优雅的实现项目鉴权!

1. 技术选型 最近在做登录、授权的功能&#xff0c;一开始考虑到的是spring boot spring security&#xff0c;但spring security太重&#xff0c;而我们是轻量级的项目&#xff0c;所以&#xff0c;spring security不适合我们。 而后考虑spring boot shiro&#xff0c;但s…

【老王读SpringMVC-5】Controller method 是如何执行的?

通过前面对 Controller method 参数绑定的分析&#xff0c;我们知道&#xff0c; 被 RequestMapping 标记 handler method 的执行是通过调用 RequestMappingHandlerAdapter#handle()。 RequestMappingHandlerAdapter#handle() 具体的调用过程如下&#xff1a; 参数解析、han…

【Java基础篇】运算符

作者简介&#xff1a; 辭七七&#xff0c;目前大一&#xff0c;正在学习C/C&#xff0c;Java&#xff0c;Python等 作者主页&#xff1a; 七七的个人主页 文章收录专栏&#xff1a;Java.SE&#xff0c;本专栏主要讲解运算符&#xff0c;程序逻辑控制&#xff0c;方法的使用&…

由浅入深Dubbo网络通信深入解析

目录 1 dubbo中数据格式2 消费方发送请求3 提供方接收请求4 提供方返回调用结果5 消费方接收调用结果6 异步转同步7 异步多线程数据一致8 心跳检查 1 dubbo中数据格式 解决socket中数据粘包拆包问题&#xff0c;一般有三种方式 定长协议&#xff08;数据包长度一致&#xff09…

5GNR——RACH随机接入流程(1):随机接入的原因

1、随机接入触发原因 1- Initial access from RRC_IDLE; 2- RRC Connection Re-establishment procedure; 3- DL or UL data arrival during RRC_CONNECTED when UL synchronisation status is “non-synchronised”; 4- UL data arrival during RRC_CONNECTED when there are …

Java之运算符

&#xff0b;加号的作用 1.表示正数 2.相加运算符 3.进行字符串的拼接 4.自增 Tips&#xff1a; 运算运算符优于 扩展赋值运算符 byte a ; int b ; ab&#xff1b; 右侧为byte&#xff0c;无需强制转换 aab; 右侧为int&#xff0c;需强制转换为byte&#xff0c;赋给左边…

解码区块链:探索去中心化世界的奥秘与潜力

&#x1f41f; 区块链技术的基本原理&#x1f41f; 区块链技术的应用场景&#x1f41f; 区块链技术的挑战与前景 区块链技术作为一项创新性的技术&#xff0c;引领着数字时代的变革。它以其去中心化、透明性和安全性的特点&#xff0c;为各行业带来了无限可能。在本篇博客中&am…

《程序员面试金典(第6版)》面试题 02.05. 链表求和(构建一个新链表)

题目解析 给定两个用链表表示的整数&#xff0c;每个节点包含一个数位。这些数位是反向存放的&#xff0c;也就是个位排在链表首部。编写函数对这两个整数求和&#xff0c;并用链表形式返回结果。 题目传送门&#xff1a;面试题 02.05. 链表求和 示例&#xff1a; 输入&#x…

漏洞管理基础知识

漏洞管理对于端点安全至关重要&#xff0c;是在安全漏洞导致漏洞之前清除安全漏洞的最主动方法之一。 什么是漏洞 漏洞是软件中的错误代码段&#xff0c;会导致软件崩溃或以程序员从未预料到的方式做出响应。黑客可以利用漏洞对计算机系统进行未经授权的访问或对计算机系统执行…

第五十天学习记录:C语言进阶:位段

位段 什么是位段 位段的声明和结构是类似的&#xff0c;有两个不同&#xff1a; 1、位段的成员可以是int,unsigned int或signed int。 2、位段的成员名后边有一个冒号和一个数字。 #define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>//位段-二进制位 struct A {int …

用脚本采集ChatGPT免翻免费镜像

新建了一个网站 ChatGPT人工智能中文站 - ChatGPT人工智能中文站 每天给大家更新可用的国内可用chatGPT免费镜像站 昨天发布了一个教程 本地安装 ChatGPT&#xff01;无需API、 免翻墙、完全免费使用纯正OpenAI的全部功能&#xff01; 支持 Windows、 Mac、NAS、Linux系统 …

led钨丝灯项目笔记

基于ESP-12E的LED钨丝灯作品 原理图&#xff1a; PCB&#xff1a; 嘉立创上面有些封装没有&#xff0c;需要自己画 画完这两个&#xff0c;此时它们还没有相关联&#xff0c;需要将它们关联起来 在封装管理器中将它们关联起来 在这里面就可以找到自己画的封装 如&#xff1a;…

MySQL数据库从入门到精通学习第5天(创建数据表,查看,修改表结构,删除表)

创建数据表&#xff0c;查看&#xff0c;修改表结构 创建数据表查看表结构修改表结构删除表 创建数据表 在对MySQL数据表进行操作之前我们需要创建数据库&#xff0c;并使用USE语句选择数据库。 创建数据库使用CREATE TABLE语句&#xff1a; 语法&#xff1a;CREATE [TEMPOR…

机试打卡 -06 异位词分组(哈希表)

最容易想到的是利用 ord( ) 函数&#xff0c;按照字母计数的特征归类&#xff0c;代码如下&#xff1a; class Solution:def groupAnagrams(self, strs: List[str]) -> List[List[str]]:ans_list[]# 哈希表 {word_count:ans_list中的索引}word_count_dictdict()# 遍历strfo…

NR RLC(三) TM and UM mode

欢迎关注同名微信公众号“modem协议笔记”。 实网下VOLTE通话时常会出现通话无声或者断续的情况&#xff0c;通常的做法是通过检查MO/MT UL发送和DL接收&#xff0c;进一步排查问题原因&#xff0c;modem就避免不了要查看RLC的收发情况&#xff0c;而voice配置一般都是RLC UM …

【Linux系统编程(文件编程)】之读、写文件、文件光标移动

文章目录 一、文件写入二、文件读取三、文件光标移动使用 lseek() 计算文件大小 一、文件写入 write() writes up to count bytes from the buffer starting at buf to the file referred to by the file descriptor fd.write() write() 函数&#xff0c;将从buf缓冲区开始&…