苍穹外卖项目

news2024/11/15 19:57:06

1. 苍穹外卖项目介绍

1.1 项目介绍

定位:专门为餐饮企业(餐厅、饭店)定制的一款软件产品

项目架构:体现项目中的业务功能模块

1.2 产品原型

产品原型:用于展示项目的业务功能,一般由产品经理进行设计

1.3 技术选型

技术选型:展示项目中使用到的技术框架和中间件等

2. 开发环境的搭建

2.1 前端环境搭建

vue node js axios

2.2 后端环境搭建

mysql 、 springboot 、springmvc、websocket

2.2.1 使用Git进行版本控制

使用Git进行项目代码的版本控制,具体操作:

  • 创建Git本地仓库

1.使用idea点击VCS,创建本地仓库

  • 创建Git远程仓库
  • 将本地文件推送到Git远程仓库

2.3 实现登录效果

2.3.1 前后端联调

nginx 反向代理的配置方式

server{
    listen 80;
    server_name localhost;
    
    location /api/ {
        proxy_pass http://localhost:8080/admin/;#反向代理
    }
}

nginx配置负载均衡

upstream webservers{
    server 192.168.100.128:8080;
    server 192.168.100.129:8080;
}

server{
    listen 80;
    server_name localhost;
    
    location /api/ {
        proxy_pass http://webservers/admin/;#反向代理
    }
}

2.3.2 未完成任务的注释

TODO 注释

2.3.2 完善登录效果

密码是明文存储需要加上md5加密

// md5加密
password = DigestUtils.md5DigestAsHex(password.getBytes());

3. 导入接口文档

3.1 Swagger

介绍:使用swagger你只需要按照他的规范去定义接口及接口相关的信息,就可以做到生成接口文档,以及在线接口调试页面

Knife4j是为java MVC框架集成swagger生成api文档的增强解决方案。

3.2 使用方式

      1. 导入knife4j的mavern坐标 pom.xml

<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-spring-boot-starter</artifactId>
    <version>3.0.2</version>
</dependency>

      2. 在配置类中加入 knife4j 相关配置 WebMvcConfiguration.java

@Bean
    public Docket docket() {
        ApiInfo apiInfo = new ApiInfoBuilder()
                .title("苍穹外卖项目接口文档")
                .version("2.0")
                .description("苍穹外卖项目接口文档")
                .build();
        Docket docket = new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.sky.controller"))
                .paths(PathSelectors.any())
                .build();
        return docket;
    }

     3. 设置静态资源映射,否则接口文档页面无法访问WebMvcConfiguration.java

 protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/doc.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

3.3 常用注解

通过注解可以控制生成的接口文档,使接口文档拥有更好的可读性,常用注解如下:

注解说明
@Api用在类上,例如Controller,表示对类的说明
@ApiModel用在类上,例如entity、DTO、VO
@ApiModelProperty用在属性上,描述属性信息
@ApiOpeation用在方法上,例如Controller的方法,说明方法的用途、作用

4. 员工管理

4.1 新增员工

知识点1:对象的拷贝

//对象的拷贝
BeanUtils.copyProperties(employeeDTO,employee);

知识点2:插入两个相同唯一的值,全局捕获异常 handle/GlobalExceptionHandler

    /**
     * 处理sql异常
     * @param ex
     * @return
     */
    @ExceptionHandler
    public Result exceptionHandler(SQLIntegrityConstraintViolationException ex){
        String message = ex.getMessage();
        if(message.contains("Duplicate entry")){
            String[] split = message.split(" ");
            String username = split[2];
            String msg = username + MessageConstant.ALREADY_EXISTS;
            return Result.error(msg);
        }else {
            return Result.error(MessageConstant.UNKNOWN_ERROR);
        }
    }

知识点3:动态获取用户id

ThreadLocal为每个线程提供一份存储空间,具有线程隔离效果,只有在线程内才能获取到对应的值,线程外不能访问。

controller、service、拦截器里面都是同一个。所以可以进行通信

ThreadLocal常用方法:

  • public void set(T value) 设置当前的线程局部变量的值
  • public T get()  返回当前线程所对应的线程局部变量的值
  • public void remove()  移除当前线程的局部变量值

封装一个:工具类BaseContext:

public class BaseContext {

    public static ThreadLocal<Long> threadLocal = new ThreadLocal<>();

    public static void setCurrentId(Long id) {
        threadLocal.set(id);
    }

    public static Long getCurrentId() {
        return threadLocal.get();
    }

    public static void removeCurrentId() {
        threadLocal.remove();
    }

}

存储id:

BaseContext.setCurrentId(empId);

取出id:

BaseContext.setCurrentId(empId);

4.2 员工分页查询

4.2.1 分页查询:

配置配置:

@Configuration
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return mybatisPlusInterceptor;
    }
}

 使用:

Page<Employee> employeePage = new Page<>(employeePageQueryDTO.getPage(),employeePageQueryDTO.getPageSize());
        LambdaQueryWrapper<Employee> employeeWrapper = new LambdaQueryWrapper<>();
        employeeWrapper.like(ObjectUtils.isNotEmpty(employeePageQueryDTO.getName()),Employee::getName,employeePageQueryDTO.getName());
        employeeService.page(employeePage,employeeWrapper);
        PageResult pageResult = new PageResult();
        BeanUtils.copyProperties(employeePage,pageResult);
        return Result.success(pageResult);

4.2.2 解决时间显示问题

方式一:在属性上加入注解,对日期格式化

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;")

方式二:在WebMvcConfiguration中扩展Spring MVC 的消息转换器,统一对日期类型进行格式化处理

第一步:在WebMvcConfiguration编写代码

 protected void extendMessageConverters(List<HttpMessageConverter<?>> converters){
        log.info("开始扩展消息转换器...");
        //创建一个消息转化器对象
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        //设置对象转换器,可以将java对象转为json字符串
        converter.setObjectMapper(new JacksonObjectMapper());
        //将我们自己的转化器放入spring MVC框架容器中
        converters.add(0,converter);
    }

第二步:新建JacksonObjectMapper工具类中

package com.takeaway.json;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;

/**
 * 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
 * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
 * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
 */
public class JacksonObjectMapper extends ObjectMapper {

    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
    //public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm";
    public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";

    public JacksonObjectMapper() {
        super();
        //收到未知属性时不报异常
        this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);

        //反序列化时,属性不存在的兼容处理
        this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

        SimpleModule simpleModule = new SimpleModule()
                .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
                .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
                .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))
                .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
                .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
                .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));

        //注册功能模块 例如,可以添加自定义序列化器和反序列化器
        this.registerModule(simpleModule);
    }
}

4.3 员工禁用

用户的id是17位但是前端long没有那么长,会导致精度丢失:

解决方法:配置confg

@Configuration
public class IdJsonConfig {
    @Bean
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        SimpleModule module = new SimpleModule();
        module.addSerializer(Long.class, ToStringSerializer.instance);
        module.addSerializer(Long.TYPE, ToStringSerializer.instance);
        objectMapper.registerModule(module);
        return objectMapper;
    }
}

禁用方法:

@PostMapping("/status/{status}")
    //public Result startOrStop(@PathVariable("status") Integer status,Long id){ 不一致需要写
    public Result startOrStop(@PathVariable Integer status, Long id) {

4.4  编辑员工

4.4.1 获取用户详情

    @ApiOperation("获取用户详情")
    @GetMapping("/{id}")
    public Result<Employee> getById(@PathVariable Long id){

4.4.2 编辑员工

字段设计:

    @ApiOperation("新增分类")
    @PostMapping

    @ApiOperation("分类分页查询")
    @GetMapping("/page")

    @DeleteMapping
    @ApiOperation("删除分类")

    @ApiOperation("分类禁用和启用")
    @PostMapping("/status/{status}")

    @ApiOperation("修改分类")
    @PutMapping

5. 菜品管理

5.1 公共字段填充(未实现)

业务表中的公共字段:

crate_time、update_time 自动填充

1. 自定义注解 AutoFile,用于标识需要进行公共字段自动填充的方法

2.自定义切面AutoFillAspect,统一拦截加入了AutoFil 注解的方法,通过反射为公共字段赋值

3.在mapper的方法上加入 AutoFill注解

未完成。。。

6. Redis

6.1 简介

Redis是一个基于内存的 key-value 结构数据库

  • 基于内存存储,读写性能高
  • 适合存储热点数据(热点商品,咨询,新闻)
  • 企业应用广泛

6.2 Redis下载与安装

6.2.1 Redis安装包分为 Windows 版和 Linux 版:

  • Windows版下载地址:https://github.com/microsoftarchive/redis/releases
  •  Linux版下载地址:Index of /releases/

redis属于绿色健康软件:解压就可以用:

目录结构:

redis.windows.conf      Redis配置文件

redis-cli.exe                 Redis运行文件

redis-server.exe           Redis服务端

6.3 Redis的使用

第一步:启动服务端,进入redis安装目录,执行如下命令行

D:\develop\redis>redis-server.exe redis.windows.conf

出现这个就启动成功:

第二步:启动客户端,链接redis服务端

D:\develop\redis>redis-cli.exe

出现这个则成功:

或者:可以配置端口和链接主机

D:\develop\redis>redis-cli.exe -h localhost -p 6379

6.4 Redis配置密码

打开:redis.windows.conf找到requirepass解除注释,修改值为密码,就完成了

客户端链接服务器命令:

D:\develop\redis>redis-cli.exe -h localhost -p 6379 -a 123456

6.5 Redis五种常用数据类型介绍

字符串 string、哈希 hash、列表 list、集合 set、有序集合 sorted set / zset

6.6 Redis 常用命令

6.6.1 Redis 字符串类型常用命令

  • SET key value                               设置指定key的值
  • GET key                                        获取指定key的值
  • SETEX key seconds value           设置指定key的值,并将 key 的过期时间设置为 seconds 秒
  • SETNX key value                          只有在 key 不存在时设置 key 的值

6.6.2 Redis 哈希操作命令

Redis hash 是一个string 类型的 field 和 value 的映射表,hash特别适合用于存储对象,常用命令:

  • HSET key field value     将哈希表 key 中的字段 field 的值设为 value
  • HGET key field              获取存储在哈希表中指定字段的值
  • HDEL key field               删除哈希表中所有字段
  • HKEYS key                    获取哈希表中所有字段
  • HVALS key                     获取哈希表中所有值

6.6.2 Redis 列表是简单的字符串列表,按照插入顺序排序,常用命令:

  • LPUSH key value1 [value2]         将一个或多个插入到列表头部
  • LRANGE key start stop                获取列表指定范围内的元素
  • RPOP key                                     移除并获取列表最后一个元素
  • LLEN key                                       获取列表长度

6.6.3 Redis

6.7 在Java中操作Redis

6.7.1 Spring Data Redis 使用方式

        1. 导入Spring Data Redis 的maven坐标  pom.xml

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

        2. 配置Redis数据源  application.yml

spring:
  redis:
    host: localhost
    port: 6379
    password: 123456
    database: 0 #指定数据库,不同的数据中数据是相互隔离的,默认不用配置

        3.编写配置类,创建RedisTemplate对象,在config下新建RedisConfiguration.java

@Configuration
@Slf4j
public class RedisConfiguration {

//报错是编译器的原因

    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){
        log.info("开始创建redis模块对象...");
        RedisTemplate redisTemplate = new RedisTemplate();
        //设置redis链接工厂对象
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        //设置redis key的序列化器
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        return redisTemplate;
    }
}

        4.通过RedisTemplate对象操作Redis

@SpringBootTest
public class SpringDataRedisTest {

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void testRedisTemplate(){
        System.out.println(redisTemplate);
    }
}

6.7.1 Spring Data Redis 操作字符串

6.7.2 Spring Data Redis 操作Hash

操作都是一样的。

6.8  店铺营业状态设计

最后:

小技巧:

查询:对于查询来说,Result最好写类型,但是对于增删改来说可以用泛型

使用Builder构造类:

在类上加上@

@Builder
public class Employee implements Serializable {

使用:

Employee employee = Employee.builder()
                .id(id)
                .status(status)
                .build();

设置:请求bean名称

log.info("设置店铺营业状态:{}",status == 1?"营业中":"打样中");

配置两个文档:

@Bean
    public Docket docket1() {
        ApiInfo apiInfo = new ApiInfoBuilder()
                .title("苍穹外卖项目接口文档")
                .version("2.0")
                .description("苍穹外卖项目接口文档")
                .build();
        Docket docket = new Docket(DocumentationType.SWAGGER_2)
                .groupName("管理员")
                .apiInfo(apiInfo)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.takeaway.controller.admin"))
                .paths(PathSelectors.any())
                .build();
        return docket;
    }

    @Bean
    public Docket docket2() {
        ApiInfo apiInfo = new ApiInfoBuilder()
                .title("苍穹外卖项目接口文档")
                .version("2.0")
                .description("苍穹外卖项目接口文档")
                .build();
        Docket docket = new Docket(DocumentationType.SWAGGER_2)
                .groupName("用户")
                .apiInfo(apiInfo)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.takeaway.controller.user"))
                .paths(PathSelectors.any())
                .build();
        return docket;
    }

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

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

相关文章

三十三、【进阶】索引的分类

1、索引的分类 &#xff08;1&#xff09;总分类 主键索引、唯一索引、常规索引、全文索引 &#xff08;2&#xff09;InnoDB存储引擎中的索引分类 2、 索引的选取规则(InnoDB存储引擎) 如果存在主键&#xff0c;主键索引就是聚集索引&#xff1b; 如果不存在主键&#xff…

【计算机基础】Git系列3:常用操作

&#x1f4e2;&#xff1a;如果你也对机器人、人工智能感兴趣&#xff0c;看来我们志同道合✨ &#x1f4e2;&#xff1a;不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸对你有帮助&#xff0c;可点赞 &#x1f44d;…

多路彩灯控制器led流水灯VHDL速度可调仿真图视频、源代码

名称&#xff1a;多路彩灯控制器led流水灯VHDL速度可调 软件&#xff1a;Quartus 语言&#xff1a;VHDL 代码功能&#xff1a; 使用VHDL设计彩灯控制器&#xff0c;共24个led灯&#xff0c;分为5种不同的花样&#xff0c;可以通过按键切换花样的变化速度。 代码下载&#…

【垃圾回收概述及算法】

文章目录 1. 垃圾回收概述及算法2. 垃圾回收相关算法2.1 标记阶段&#xff1a;引用计数算法2.2 标记阶段&#xff1a;可达性分析算法2.3 对象的 finalization 机制2.3.1 一个对象是否可回收的判断 2.4 清除阶段&#xff1a;标记-清除算法2.5 清除阶段&#xff1a;复制算法2.6 清…

【数据结构-字符串 三】【字符串转换】字符串解码

废话不多说&#xff0c;喊一句号子鼓励自己&#xff1a;程序员永不失业&#xff0c;程序员走向架构&#xff01;本篇Blog的主题是【字符串转换】&#xff0c;使用【字符串】这个基本的数据结构来实现&#xff0c;这个高频题的站点是&#xff1a;CodeTop&#xff0c;筛选条件为&…

028.Python面向对象_类补充_元类

我 的 个 人 主 页&#xff1a;&#x1f449;&#x1f449; 失心疯的个人主页 &#x1f448;&#x1f448; 入 门 教 程 推 荐 &#xff1a;&#x1f449;&#x1f449; Python零基础入门教程合集 &#x1f448;&#x1f448; 虚 拟 环 境 搭 建 &#xff1a;&#x1f449;&…

JavaScript 解决dayjs在周日获取当前周第一天显示下一周第一天问题

原因&#xff1a;默认情况下&#xff0c;Day.js 将星期天视为每周的第一天。 方法&#xff1a;判断当天是不是周日&#xff0c;如果是就减一周。 import dayjs from dayjs const weekday dayjs().day() const we weekday 0 ? 0 - 1 : 0 // dayjs().add(7, day)、da…

Godot2D角色导航教程(角色随鼠标移动)

文章目录 运行结果2D导航概述开始前的准备2D导航创建导航网格创建角色 其他文章 运行结果 2D导航概述 Godot为2D和3D游戏提供了多个对象、类和服务器&#xff0c;以便于基于网格或基于网格的导航和路径查找。 说到导航&#xff0c;就得说一下导航网格&#xff0c;导航网格定义…

FreeRTOS自我救赎2之基本工程建立

System Core 1.System Core >SYS 2.System Core >RCC 3.System Core >NVIC Middleware Middleware >FREERTOS Clock configuration Project Manager 在编译生成的代码前需要找一个与芯片对应的启动文件&#xff0c;启动文件添加进来&#xff0c;编译就没问题了

【C语言】字符函数和内存操作函数

大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家了解字符函数和内存操作函数&#xff0c;如果你觉得我写的还不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 目录 一.字符函数1.1 字符分类函数1.2 字符转换函数 二.内存操作函数2.1 memcpy2.2…

一个非常简单的变分量子分类器 (VQC)

一、说明 在之前的帖子&#xff08;这里和这里&#xff09;中&#xff0c;我已经开始谈论 QML&#xff0c;为什么以及如何学习&#xff0c;从现在开始&#xff0c;我将开始分享我的研究和发现&#xff0c;到目前为止&#xff0c;这些都是非常基本的。 二、实验概述 今天&#…

ASP.NET Core 开发 Web API

2. Web Api 的创建与Http类型的介绍 2.1 ASP.Net Core Web API项目的创建 1.创建ASP.NET Core Web API项目 从“文件”菜单中选择“新建”“项目”。 在搜索框中输入“Web API”。 选择“ASP.NET Core Web API”模板&#xff0c;然后选择“下一步”。 在“配置新项目”对话框中…

【苍穹外卖 | 项目日记】第一天

前言&#xff1a; 我打算用16天的时间写完黑马程序员的苍穹外卖项目&#xff0c;为了督促自己每天坚持写以及记录项目知识点&#xff0c;所以用这种项目日记的方式鞭策自己 目录 前言&#xff1a; 今日完结任务&#xff1a; 今日收获&#xff1a; 1.阅读代码框架&#xf…

回溯算法!

一、回溯思路及模板 1、如果解决一个问题有多个步骤&#xff0c;每一个步骤有多种方法&#xff0c;题目又要我们找出所有的方法&#xff0c;可以使用回溯算法&#xff1b; 回溯算法是在一棵树上的 深度优先遍历&#xff08;因为要找所有的解&#xff0c;所以需要遍历&#xff…

C++对象模型(8)-- 数据语义学:this指针

1、this指针的认识 this 是 C 中的一个关键字&#xff0c;也是一个 const 指针 &#xff0c;它指向当前对象&#xff0c;通过它可以访问当前对象的所有成员。所谓当前对象&#xff0c;是指正在使用的对象。 假如有这么一个类&#xff1a; class Base { public:int b_i;int b…

node中的crypto模块指南

node中的crypto模块指南 加密操作可能很棘手&#xff0c;以至于付费的加密服务公司的存在只是为了确保在代码库中正确实现加密操作。好消息是&#xff0c;只需学习一些知识&#xff0c;我们就可以使用 Node 的内置加密模块免费进行适当的加密。 在本指南中&#xff0c;我们将…

Kickstart:快速、可靠的Linux系统自动安装

1 kickstart介绍 由于安装多台服务器系统需要重复回答多个问题&#xff0c;我们需要一个可以记录这些答案的脚本&#xff0c;自动的去回答问题&#xff0c;该文件叫kickstart脚本 2 环境搭建 2.1 配置软件仓库 2.2 关闭防火墙&#xff0c;搭建DHCP&#xff0c;httpd服务 sy…

JavaScript进阶 第一天笔记

JavaScript 进阶 - 第1天 学习作用域、变量提升、闭包等语言特征&#xff0c;加深对 JavaScript 的理解&#xff0c;掌握变量赋值、函数声明的简洁语法&#xff0c;降低代码的冗余度。 理解作用域对程序执行的影响能够分析程序执行的作用域范围理解闭包本质&#xff0c;利用闭包…

web漏洞-xml外部实体注入(XXE)

web漏洞-xml外部实体注入&#xff08;XXE&#xff09; 目录 web漏洞-xml外部实体注入&#xff08;XXE&#xff09;概念危害检测方法利用方法漏洞利用xxe-lab有回显情况无回显情况 pikachu靶场有回显内容无回显 修复方案 概念 xml可拓展标记语言&#xff1a; xml是一种可拓展的标…

面试经典 150 题 14 —(数组 / 字符串)— 134. 加油站

134. 加油站 方法一 class Solution { public:int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {int minSpare std::numeric_limits<int>::max(); // 初始化最小剩余汽油量为整型的最大值int spare 0; // 当前剩余汽油量int len g…