苍穹外卖技术栈

重难点详解

1、定义全局异常

在这里插入图片描述

2、ThreadLocal

  • ThreadLocal 并不是一个Thread,而是Thread的一个局部变量
  • ThreadLocal 为每一个线程提供独立的存储空间,具有线程隔离的效果,只有在线程内才能取到值,线程外则不能访问
public void set(T value) 设置当前线程的线程局部变量的值public T get() 返回当前线程所对应的线程局部变量的值public void remove() 移除当前线程的线程局部变量

注意:客户端每次发送http请求,对应的服务端都会分配一个新的线程,在处理过程中涉及到系列方法属于同一个线程:
【1】LoginCheckFilter的doFilter方法
【2】EmployeeController的update方法
【3】MyMetaObjectHandler的updateFill方法

3、BaseContext上下文

BaseContext是基于ThreadLocal类封装的工具类,用于在同一线程中的封装数据和获取数据

> BaseContext工具类用于存放和取出当前登录的用户的id
> 
public class BaseContext {public static ThreadLocal<Long> threadLocal = new ThreadLocal<>();/*** 设置当前线程的线程局部变量的值* @param id*/public static void setCurrentId(Long id) {threadLocal.set(id);}public static Long getCurrentId() {return threadLocal.get();}public static void removeCurrentId() {threadLocal.remove();}

4、PageHelper分页

pagehelper是mybatis 提供的分页插件

开始分页

PageHelper.startPage(1, 10)// selectlist查询数据库的时候会自动加上limit 1,10。

在CategoryServiceImpl声明pageQuery方法,及其父类接口:

    public PageResult pageQuery(CategoryPageQueryDTO categoryPageQueryDTO) {// 分页器对象Page<Category> page = new Page<>();List<Category> categoryList  = categoryMapper.pageQuery(categoryPageQueryDTO);Long total = page.getTotal();// 分页return new PageResult(total,categoryList);}

在EmployeeServiceImpl声明pageQuery方法,及其父类接口

public PageResult pageQuery(EmployeePageQueryDTO dto) {PageHelper.startPage(dto.getPage(),dto.getPageSize());Page<Employee> page = employeeMapper.pageQuery(dto);return new PageResult(page.getTotal(),page.getResult());}

原理:

  • Mybatis内置了分页拦截器PageInterceptor,即在执行相关sql之前会拦截一些操作
  • 通过`setLocalPage()方法,将分页信息保存在当前线程中。分页查询方法与之处在同一个线程中,共享ThreadLocal中的数据
  • selectlist查询之后赋值给的List list。这个list是Page 类型
  • 再将list放到PageInfo<>中即可。

查询

List<Employee> list = employeeMapper.selectByExample(Example);  

分页结果展示

 PageInfo<Employee> pageInfo = new PageInfo<>(list);  System.out.println("总记录数:"+pageInfo.getTotal());  System.out.println("总页数:"+pageInfo.getPages());  System.out.println("一页的大小:"+pageInfo.getSize());  

5、日期按年月日显示

  • WebMvcConfiguration 中扩展Spring MVC的消息转换器,统一对日期类型进行格式化处理
    protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {log.info("Spring MVC扩展消息转化器...");// 创建消息转换器对象MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();// 设置该消息转换器使用 JacksonObjectMapper 进行转换messageConverter.setObjectMapper(new JacksonObjectMapper());// 将消息转换器对象追加到 mvc 框架的转换器集合中(加到最前面)converters.add(0,messageConverter);}

在这里插入图片描述

6、启用/禁用账号

/**
* 启用禁用员工账号
*/
@Override
public void startOrStop(Integer status, Long id) {Employee employee = Employee.builder().status(status).id(id).build();employeeMapper.update(employee);
}

Employee.builder().build()建造者模式,builder构造对象;@Builder 注解

6、公共字段填充

mybatis-plus提供了公共字段自动填充功能

// 在EmployeeMapper
@AutoFill(value = OperationType.INSERT)
void insert(Employee employee);@AutoFill(value = OperationType.UPDATE)
void update(Employee employee);// CategoryMapper
@AutoFill(value = OperationType.INSERT)
void insert(Category category);@AutoFill(value = OperationType.UPDATE)
void update(Category category);

实现步骤
【1】实体类的属性上加入注解@TableField

create_time,create_user 使用 Insert
update_time,update_user 使用 Insert/update
FieldFill.DEFAULT  //默认不自动填充@ApiModelProperty(value = "创建时间")@TableField(fill = FieldFill.INSERT)private LocalDateTime createTime;@ApiModelProperty(value = "更新时间")@TableField(fill = FieldFill.INSERT_UPDATE)private LocalDateTime updateTime;

【2】元数据对象处理器,实现MetaObjectHandler接口,

@Slf4j
@Component // 交给spring管理
public class MyMetaObjectHandler implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) {log.info("start insert fill...");metaObject.setValue("createTime", LocalDateTime.now());metaObject.setValue("updateTime",LocalDateTime.now());metaObject.setValue("createUser", BaseContext.getCurrentId());metaObject.setValue("updateUser",BaseContext.getCurrentId());}@Overridepublic void updateFill(MetaObject metaObject) {log.info("start update fill...");long id = Thread.currentThread().getId();log.info("当前线程id:{}",id);metaObject.setValue("updateTime",LocalDateTime.now());metaObject.setValue("updateUser",BaseContext.getCurrentId());}

7、文件上传

 @PostMapping("/upload")@ApiOperation("文件上传")public Result<String> upload(MultipartFile file){log.info("文件上传: {}", file);try {// 原始文件名String originalFilename = file.getOriginalFilename();// 截取原始文件名的后缀String suffix= originalFilename.substring(originalFilename.lastIndexOf("."));// 构造新文件名称String objectName = UUID.randomUUID().toString() + extension;
// 文件的请求路径File dir = new File(basePath);// 创建一个目录对象//	将临时文件转存到指定位置
file.transferTo(new File(basePath+fileName));

7、请求参数requestparam与requestbody

@ResquestBody要搭配@PostMapping使用,@ResquestParam要搭配@GetMapping使用
区别equestparam与requestbody

  • 【@RequestParam】接收的参数是来自HTTP请求体或请求url的QueryString中
public void aliReceive(@RequestParam("message") String message)

@RequestParam用来处理 Content-Type 为 application/x-www-form-urlencoded 编码的内容

@RequestParam 接受JSON的字符串

@RequestParam注解无法读取application/json格式数据

  • 【@RequestBody】一般用来处理application/json、application/xml等类型的数据。

POST请求中,通过HttpEntity传递的参数,必须要在请求头中声明数据的类型Content-Type,SpringMVC通过使用

  • 【@PathVariable】
// 参数名和url变量名不一致
@RequestMapping("/user/{id}")
public String testPathVariable(@PathVariable("id") String userId){System.out.println("路径上的占位符的值="+id);
}// 参数名和url变量名一致
@RequestMapping("/getUser/{name}")public User getUser(@PathVariable String name){return userService.selectUser(name);}通过@PathVariable,例如/blogs/1
通过@RequestParam,例如blogs?blogId=1

8、HttpClient

【发送请求步骤】

  • 创建HttpClient对象
  • 创建请求对象HttpGet、HttpPost等
  • 请求对象调用HttpClient的execute方法发送请求
/*** 测试通过httpclient发送GET方式的请求*/
@Test
public void testGET() throws Exception {// 创建httpclient对象CloseableHttpClient httpClient = HttpClients.createDefault();// 创建请求对象HttpGet httpGet = new HttpGet("http://localhost:8080/user/shop/status");// 发送请求,接收响应结果CloseableHttpResponse response = httpClient.execute(httpGet);// 获取客户端返回的状态码int statusCode = response.getStatusLine().getStatusCode();System.out.println("服务端返回的状态码为:" + statusCode);HttpEntity entity = response.getEntity();String body = EntityUtils.toString(entity);System.out.println("服务端返回的数据为:" +body);// 关闭资源response.close();httpClient.close();
}

9、微信小程序登录

在application-dev.yml中写入具体的配置属性

skywechat:appid: ${sky.wechat.appid}secret: ${sky.wechat.secret}

创建user/UserController,创建微信登录的方法

@PostMapping("/login")@ApiOperation("微信登录")public Result<UserLoginVO> login(@RequestBody UserLoginDTO userLoginDTO){log.info("微信用户登录:{}",userLoginDTO);// 微信登录User user = userService.wxLogin(userLoginDTO);// 为微信用户生成jwt令牌Map<String, Object> claims = new HashMap<>();claims.put(JwtClaimsConstant.USER_ID, user.getId());String token = JwtUtil.createJWT(jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), claims);UserLoginVO userLoginVO = UserLoginVO.builder().id(user.getId()).openid(user.getOpenid()).token(token).build();return Result.success(userLoginVO);

在UserServiceImpl中,实现wxLogin的方法,及其父类接口

 // 微信服务接口地址public static final String WX_LOGIN = "https://api.weixin.qq.com/sns/jscode2session";
public User wxLogin(UserLoginDTO userLoginDTO) {String openid = getOpenid(userLoginDTO.getCode());// 判断openid是否为空,如果为空表示登录失败,抛出业务异常if (openid == null){throw new LoginFailedException(MessageConstant.LOGIN_FAILED);}// 判断当前用户是否为新用户User user = userMapper.getByOpenId(openid);// 如果是新用户,自动完成注册if (user == null){user = User.builder().openid(openid).createTime(LocalDateTime.now()).build();userMapper.insert(user);}private String getOpenid(String code){// 调用微信接口服务,获取当前微信用户的openidMap<String, String> map = new HashMap<>();map.put("appid", weChatProperties.getAppid());map.put("secret", weChatProperties.getSecret());map.put("js_code", code);map.put("grant_type", "authorization_code");String json = HttpClientUtil.doGet(WX_LOGIN, map);JSONObject jsonObject = JSON.parseObject(json);String openid = jsonObject.getString("openid");return openid;}

编写JwtTokenUserInterceptor拦截器,校验用户端token是否是合法的

public class JwtTokenUserInterceptor implements HandlerInterceptor {...}

在WebMvcConfiguration中,注册拦截器


@Autowired
private JwtTokenUserInterceptor jwtTokenUserInterceptor;protected void addInterceptors(InterceptorRegistry registry) {log.info("开始注册自定义拦截器...");registry.addInterceptor(jwtTokenAdminInterceptor).addPathPatterns("/admin/**").excludePathPatterns("/admin/employee/login");registry.addInterceptor(jwtTokenUserInterceptor).addPathPatterns("/user/**").excludePathPatterns("/user/user/login").excludePathPatterns("/user/shop/status");

10、Redis缓存

RedisTemplate是Spring Data Redis提供给用户的最高级的抽象客户端,用户可直接通过RedisTemplate进行多种操作、异常处理、序列化、发布订阅等
————————————————————
spring-data-redis的提供了如下功能:

  1. 连接池自动管理,提供了一个高度封装的“RedisTemplate”类
  2. 进行了归类封装,将同一类型操作封装为operation接口

ValueOperations:简单K-V操作 redisTemplate.opsForValue().
SetOperations:set类型数据操作 redisTemplate.opsForSet().
ZSetOperations:zset类型数据操作 redisTemplate.opsForZSet().
HashOperations:针对map类型的数据操作 redisTemplate.opsForHash()
ListOperations:针对list类型的数据操作 redisTemplate.opsForList().

  1. 针对数据的“序列化/反序列化”,提供了多种可选择策略(RedisSerializer)
  1. JdkSerializationRedisSerializer:POJO对象的存取场景,使用JDK本身序列化机制,将pojo类通过ObjectInputStream/ObjectOutputStream进行序列化操作,最终redis-server中将存储字节序列。是目前最常用的序列化策略。
  1. StringRedisSerializer:Key或者value为字符串的场景,根据指定的charset对数据的字节序列编码成string,是“newString(bytes,charset)”和“string.getBytes(charset)”的直接封装。是最轻量级和高效的策略。
  1. JacksonJsonRedisSerializer:jackson-json工具提供了javabean与json之间的转换能力,可以将pojo实例序列化成json格式存储在redis中,也可以将json格式的数据转换成pojo实例。因为jackson工具在序列化和反序列化时,需要明确指定Class类型,因此此策略封装起来稍微复杂。
  1. OxmSerializer:提供了将javabean与xml之间的转换能力,目前可用的三方支持包括jaxb,apache-xmlbeans;redis存储的数据将是xml工具。不过使用此策略,编程将会有些难度,而且效率最低;不建议使用。【需要spring-oxm模块的支持】

11.BeanUtils

BeanUtils.copyProperties的用法

常见场景:

  • 接口中将前端请求参数xxVo,转化为xxQuery对象,查询数据库条件对象
BeanUtils.copyProperties(source,target);BeanUtils.copyProperties("要转换的类", "转换后的类");
  1. 源对象source的属性拷贝值赋给目标对象target的过程中,属性名和属性类型都相同的属性才能被成功拷贝赋值
  2. 做赋值的属性一定要有对应的setter/getter才能成功赋值
  3. 1.对于类型为Boolean/Short/Integer/Float/Double的属性,它会转换为0
  4. java.util.Date/BigDecimal/java.sql.Date/java.sql.Timestamp/java.sql.Time这几个类,如果值为null,则在copy时会抛异常,需要使用对应的Conveter:

org.springframework.beans.BeanUtils BeanUtils.copyProperties(a, b):a复制到b
org.apache.commons.beanutils.BeanUtilsBeanUtils.copyProperties(a, b):b复制到a

12、Spring Task定时处理

Spring Task 是Spring框架提供的任务调度工具

【Spring Task实现步骤】

  1. 导入maven左边
  2. 启动类添加@EnableScheduling注解,开启任务调度
  3. 自定义定时任务 @Scheduled(cron=" ")
    @Scheduled(cron = "0 * * * * ? *") // 每分钟触发一次public void processTimeoutOrder(){log.info("定时处理超时订单:{}", LocalDateTime.now());

13、WebSocket

WebSocket 是基于 TCP 的一种新的网络协议。它实现了浏览器与服务器全双工通信——浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接, 并进行双向数据传输

创建websocket/WebSocketServer,实现WebSocket服务

@Component
@ServerEndpoint("/ws/{sid}")
public class WebSocketServer {// 存放会话对象
private static Map<String, Session> sessionMap = new HashMap();//连接建立成功@OnOpenpublic void onOpen(Session session, @PathParam("sid") String sid) {System.out.println("客户端:" + sid + "建立连接");sessionMap.put(sid, session);}
//收到客户端消息@OnMessagepublic void onMessage(String message, @PathParam("sid") String sid) {System.out.println("收到来自客户端:" + sid + "的信息:" + message);}
// 关闭连接@OnClosepublic void onClose(@PathParam("sid") String sid) {System.out.println("连接断开:" + sid);sessionMap.remove(sid);}
// public void sendToAllClient(String message) {Collection<Session> sessions = sessionMap.values();for (Session session : sessions) {try {//服务器向客户端发送消息session.getBasicRemote().sendText(message);} catch (Exception e) {e.printStackTrace();}}}

创建WebSocketTask中,通过WebSocket向客户端发送消息

    public void sendMessageToClient() {webSocketServer.sendToAllClient("这是来自服务端的消息:" + DateTimeFormatter.ofPattern("HH:mm:ss").format(LocalDateTime.now()));}

14、LambdaQueryWrapper

LambdaQueryWrapper是Mybatis-Plus框架中的一个查询条件构造器

LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(User::getName, "张三") // 等于eq.ne(User::getAge, 18) // 不等于ne.gt(User::getSalary, 5000) // 大于gt.like(User::getEmail, "abc") //模糊查询.orderByDesc(User::getCreateTime);// 降序
List<User> userList = userMapper.selectList(queryWrapper);

15、Nginx

  • 反向代理:允许Nginx服务器代表客户端将请求转发给后端的多个应用服务器
    在这里插入图片描述

16、Spring Cache

Spring Cache 是一个框架,实现了基于注解的缓存功能;底层可以切换不同的缓存实现,如:Redis

    @PostMapping@ApiOperation(value = "新增套餐")@CacheEvict(cacheNames = "setmealCache",key = "#setmealDTO.categoryId")public Result save(@RequestBody SetmealDTO setmealDTO){setmealService.save(setmealDTO);}// 修改信息@CacheEvict(cacheNames = "setmealCache",allEntries = true)public Result update(@RequestBody SetmealDTO setmealDTO){setmealService.update(setmealDTO);return Result.success();}

常用注解:

@EnableCaching // 开启缓存注解功能,启动类上@Cacheable //在方法执行前查询缓存中是否有数据@CachePut //将方法的返回值加入缓存中@CacheEvict //删除缓存

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

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

相关文章

OpenCV项目开发实战--实现面部情绪识别对情绪进行识别和分类及详细讲解及完整代码实现

文末提供免费的完整代码下载链接 面部情绪识别(FER)是指根据面部表情对人类情绪进行识别和分类的过程。通过分析面部特征和模式,机器可以对一个人的情绪状态做出有根据的猜测。面部识别的这个子领域是高度跨学科的,借鉴了计算机视觉、机器学习和心理学的见解。 在这篇研究…

JavaScript基础知识09——数据类型

哈喽&#xff0c;大家好啊&#xff0c;这里是雷工笔记&#xff0c;我是雷工。 数据类型比较常见&#xff0c;无论是对程序员&#xff0c;还是电气工程师来说&#xff0c;都再熟悉不过了&#xff0c;这里跟着教程了解一下&#xff0c;主要看跟自己以往在其他PLC&#xff0c;C#&a…

Windows环境下Elasticsearch相关软件安装

Windows环境下Elasticsearch相关软件安装 本文将介绍在 windows 环境下安装 Elasticsearch 相关的软件。 1、安装Elasticsearch 1.1 安装jdk ElasticSearch是基于lucence开发的&#xff0c;也就是运行需要java jdk支持&#xff0c;所以要先安装JAVA环境。 由于ElasticSear…

基于SSM的校园美食交流系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

算法 数据结构 递归冒泡算法 java冒泡算法 优化递归冒泡 数据结构(九)

使用递归算法实现冒泡&#xff1a; package com.nami.algorithm.study.day06;import java.util.Arrays;/*** beyond u self and trust u self.** Author: lbc* Date: 2023-09-05 15:36* email: 594599620qq.com* Description: keep coding*/ public class BubbleSort2 {// p…

2023 年最新Java 毕业设计选题题目参考,500道 Java 毕业设计题目,值得收藏

大家好&#xff0c;我是程序员徐师兄&#xff0c;最近有很多同学咨询&#xff0c;说毕业设计了&#xff0c;不知道选怎么题目好&#xff0c;有哪些是想需要注意的。 确实毕设选题实际上对很多同学来说一个大坑&#xff0c; 每年挖坑给自己跳的人太多太多&#xff0c;选题选得好…

目标检测评估指标mAP:从Precision,Recall,到AP50-95

1. TP, FP, FN, TN True Positive 满足以下三个条件被看做是TP 1. 置信度大于阈值&#xff08;类别有阈值&#xff0c;IoU判断这个bouding box是否合适也有阈值&#xff09; 2. 预测类型与标签类型相匹配&#xff08;类别预测对了&#xff09; 3. 预测的Bouding Box和Ground …

支付宝沙箱调用错误

支付宝沙箱调用参数就三个APPID&#xff0c;用户私钥&#xff0c;支付宝公钥&#xff0c; 发送请求需要的配置 alipay: app_id: 2021000122636644 merchant_private_key: 用户私钥 alipay_public_key: 支付宝公钥 sign_type: RSA2 charset: utf-8 gatewayUrl: https://openap…

5分钟让你实现一个Python+Selenium的自动化测试框架(超详细~)

什么是Selenium&#xff1f; Selenium是一个基于浏览器的自动化测试工具&#xff0c;它提供了一种跨平台、跨浏览器的端到端的web自动化解决方案。Selenium主要包括三部分&#xff1a;Selenium IDE、Selenium WebDriver 和Selenium Grid。 Selenium IDE&#xff1a;Firefox的…

C# 参数名加冒号,可以打乱参数顺序

今天看到Python有这种语法&#xff0c;参数名后面跟着等号写参数&#xff0c;联想到前几天用到的Serilog&#xff0c;好像有个参数名加冒号的写法&#xff0c;搜索了一下&#xff0c;果真有这种用法。 函数特别大的时候&#xff0c;用这种方法很直观&#xff0c;而且参数可以打…

2023开学礼中国海洋大学《乡村振兴战略下传统村落文化旅游设计》许少辉新海洋图书馆

2023开学礼中国海洋大学《乡村振兴战略下传统村落文化旅游设计》许少辉新海洋图书馆

虚拟机上部署K8S集群

虚拟机上部署K8S集群 安装VM Ware安装Docker安装K8S集群安装kubeadm使用kubeadm引导集群 安装VM Ware 参考&#xff1a;http://www.taodudu.cc/news/show-2034573.html?actiononClick 安装Docker 参考&#xff1a;https://www.yuque.com/leifengyang/oncloud/mbvigg#2ASxH …

Qt CMake 中国象棋程序实现

前驱课程 C自学精简实践教程 目录(必读) C数据结构与算法实现&#xff08;目录&#xff09; Qt 入门实战教程&#xff08;目录&#xff09; 项目初衷 为学习 Qt 的人提供一个合适的有一定难度的综合型练习项目。 在学会写代码之前&#xff0c;先看别人怎么写的代码。深入…

【Spring Cloud系列】 雪花算法原理及实现

【Spring Cloud系列】 雪花算法原理及实现 文章目录 【Spring Cloud系列】 雪花算法原理及实现一、概述二、生成ID规则部分硬性要求三、ID号生成系统可用性要求四、解决分布式ID通用方案4.1 UUID4.2 数据库自增主键4.3 基于Redis生成全局id策略 五、SnowFlake&#xff08;雪花算…

合宙Air724UG LuatOS-Air LVGL API控件-二维码(Qrcode)

二维码&#xff08;Qrcode&#xff09; 示例代码 qrcodelvgl.qrcode_create(lvgl.scr_act(),nil)lvgl.qrcode_set_txt(qrcode,"https://doc.openluat.com/home")lvgl.obj_set_size(qrcode,400,400)lvgl.obj_align(qrcode, nil, lvgl.ALIGN_CENTER, 0, 0)创建 可以通…

LP(六十九)智能文档助手升级

本文在笔者之前研发的大模型智能文档问答项目中&#xff0c;开发更进一步&#xff0c;支持多种类型文档和URL链接&#xff0c;支持多种大模型接入&#xff0c;且使用更方便、高效。 项目介绍 在文章NLP&#xff08;六十一&#xff09;使用Baichuan-13B-Chat模型构建智能文档中…

【山河送书第十期】:《Python 自动化办公应用大全》参与活动,送书两本!!

【山河送书第十期】&#xff1a;《Python 自动化办公应用大全》参与活动&#xff0c;送书两本&#xff01;&#xff01; 前言一书籍亮点二作者简介三内容简介四购买链接五参与方式六往期赠书回顾 前言 在过去的 5 年里&#xff0c;Python 已经 3 次获得 TIOBE 指数年度大奖&am…

新品登场!雅特力发布AT32F402与AT32F405高速USB2.0 OTG MCU

因应高速USB市场需求&#xff0c;产品技术不断推陈出新&#xff0c;USB2.0发展带来的高速连接能力&#xff0c;优化消费者的产品使用体验&#xff0c;且由于支持即插即用和热插拔&#xff0c;提高设备易用性&#xff0c;USB接口在各项设备中成为主流通用接口。在USB2.0标准中&a…

GPT引领前沿与应用突破之GPT4科研实践技术与AI绘图教程

详情点击链接&#xff1a;GPT引领前沿与应用突破之GPT4科研实践技术与AI绘图教程 前沿 GPT对于每个科研人员已经成为不可或缺的辅助工具&#xff0c;不同的研究领域和项目具有不同的需求。如在科研编程、绘图领域&#xff1a;1、编程建议和示例代码: 无论你使用的编程语言是Py…

Spring初始化项目

1、官网用法 访问地址&#xff1a;https://start.spring.io idea配置&#xff1a;https://start.spring.io 2、阿里巴巴加速 访问地址&#xff1a;https://start.aliyun.com/bootstrap.html idea配置&#xff1a;https://start.aliyun.com 3、区别 官网阿里巴巴版本最新稍…