当前位置: 首页 > news >正文

Java单体架构项目_云霄外卖-特殊点

项目介绍:

定位:

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

分为:

        管理端:外卖商家使用

        用户端(微信小程序):点餐用户使用。

功能架构:

(体现项目中的业务功能模块)

技术选型:

(展示项目中使用到的技术框架和中间件等)

环境搭建

整体架构:

前端:

        管理端使用nginx,使用已经打包好的前端代码,并且Nginx的配置文件中已经配置了反向代理,通过此配置可以将前端请求转发到后端服务。

        用户端之后再做介绍

后端:

后端框架:

  

1.sky-common子模块中存放的是一些工具类,可以供其他模块使用

2.sky-pojo子模块中存放的是一些entity(实体类),DTO,VO

3.sky-server子模块中存放的是配置文件、配置类、拦截器、controller、service、mapper、启动类等

版本控制

        使用Git进行版本控制

数据库:

前后端联调:

        使用nginx反向代理:

nginx反向代理:

好处:

使用方法:

接口文档:

前后端分离开发流程:

设计阶段:

Apifox:

        Apifox是设计阶段使用的工具,管理和维护接口。

开发阶段:

Swagger:

        Swagger是在开发阶段使用的框架,帮助后端开发人员做后端的接口测试

介绍:

使用方式:

1.

2.

3.

常用注解:

管理端业务功能编写:

登录功能:

        完善登录功能使用MD5对数据加密

员工管理:

添加员工:

        添加员工时通过ThreadLocal获取执行人id和创建人id

ThreadLocal介绍:

        并且客户端发起的每一次请求都是一个单独的线程,这样就满足使用ThreadLocal的条件。

ThreadLocal常用方法:

员工分页查询:

        调整LocalDataTime类型数据响应回去的格式

        推荐第二种,只需要一次编码就可以调整全部指定内容

操作过程:

1.新建一个对象映射器:

/*** 对象映射器:基于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);}
}

2.在配置类中添加如下代码:

    /*** 扩展MVC框架的消息转换器* @param converters*/@Overrideprotected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {log.info("开始扩展消息转换器");//创建一个消息转换器对象MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();//设置对象转换器,可以将java对象转为json对象converter.setObjectMapper(new JacksonObjectMapper());//将自己的转换器放入spring MVC框架的容器中,并放到0索引位置,排到第一个,这样一定会使用它converters.add(0, converter);}

公共字段自动填充:

枚举类:

/*** 数据库操作类型*/
public enum OperationType {/*** 更新操作*/UPDATE,/*** 插入操作*/INSERT}

自定义注解:

/*** 自定义注解,用于标识需要进行公共字段自动填充的方法*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {/*** 枚举类 自定义数据库操作类型insert和update操作* @return*/OperationType value();}

自定义切面类:

/*** 自定义切面,实现公共字段自动填充处理逻辑*/
@Aspect
@Component
@Slf4j
public class AutoFillAspect {/*** 切入点*/@Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")public void autoFillPointCut() {}/*** 前置通知,为公共字段赋值*/@Before("autoFillPointCut()")public void autoFill(JoinPoint joinPoint) {log.info("开始进行公共字段填充...");//获取到当前被拦截方法上的数据库操作类型MethodSignature signature = (MethodSignature) joinPoint.getSignature();//方法签名对象AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);//获得方法上的注解OperationType operationType = autoFill.value();//获得数据库操作类型//获取到当前被拦截方法的参数--实体对象Object[] args = joinPoint.getArgs();Object entity = args[0];//准备赋值的数据LocalDateTime now = LocalDateTime.now();Long currentId = BaseContext.getCurrentId();//根据当前不同的操作类型,为对应的属性通过反射来赋值if(operationType == OperationType.INSERT) {try {Method setCreateTime = entity.getClass().getMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);Method setCreateUser = entity.getClass().getMethod(AutoFillConstant.SET_CREATE_USER, Long.class);Method setUpdateTime = entity.getClass().getMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);Method setUpdateUser = entity.getClass().getMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);setCreateTime.invoke(entity,now);setCreateUser.invoke(entity,currentId);setUpdateTime.invoke(entity,now);setUpdateUser.invoke(entity,currentId);} catch (Exception e) {e.printStackTrace();}} else if(operationType == OperationType.UPDATE) {try {Method setUpdateTime = entity.getClass().getMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);Method setUpdateUser = entity.getClass().getMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);setUpdateTime.invoke(entity,now);setUpdateUser.invoke(entity,currentId);} catch (Exception e) {e.printStackTrace();}}}}

给mapper层的insert和update数据库操作类型添加自定义的注解:

        @AutoFill(OperationType.UPDATE)或@AutoFill(OperationType.INSERT)

注意点:

        ·在菜品分页查询部分,可能传来的参数:status状态在动态SQL里只能判断其为null,不能加上and status = '',这样会一直读取不到它,具体原因不清楚。

        ·<set>标签下的<if>标签中的内容记得加逗号

操作Redis:

        想要了解Redis的基础知识及使用方法可以参考作者另一边文章《Java_中间件——Redis》

Redis的Java客户端:

        下面我们使用Spring Data Redis来操作Redis

Spring Data Redis使用方式:

配置类RedisTemplate:

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

代码演示:

    @Autowiredprivate RedisTemplate redisTemplate;@Testpublic void testRedisTemplate() {System.out.println(redisTemplate);//操作字符串ValueOperations valueOperations = redisTemplate.opsForValue();//操作HashHashOperations hashOperations = redisTemplate.opsForHash();//操作ListListOperations listOperations = redisTemplate.opsForList();//操作setSetOperations setOperations = redisTemplate.opsForSet();//操作有序集合ZSetOperations zSetOperations = redisTemplate.opsForZSet();}/*** 操作字符串类型的数据*/@Testpublic void testStirng() {// set get setex setnxredisTemplate.opsForValue().set("city","北京");String city = (String) redisTemplate.opsForValue().get("city");System.out.println(city);redisTemplate.opsForValue().set("code","6562",60, TimeUnit.SECONDS);redisTemplate.opsForValue().setIfAbsent("lock","1");redisTemplate.opsForValue().setIfAbsent("lock","2");}/*** 操作哈希类型的数据*/@Testpublic void testHash() {//hset hget hdel hkeys hvalsHashOperations hashOperations = redisTemplate.opsForHash();hashOperations.put("100","name","xiaobai");hashOperations.put("100","age","20");String name = (String) hashOperations.get("100", "name");System.out.println(name);Set keys = hashOperations.keys("100");System.out.println(keys);List values = hashOperations.values("100");System.out.println(values);hashOperations.delete("100","age");}/*** 操作列表类型的数据*/@Testpublic void testList() {// lpush lrange rpop llenListOperations listOperations = redisTemplate.opsForList();listOperations.leftPushAll("mylist","a","b","c");listOperations.leftPush("mylist","d");List mylist = listOperations.range("mylist", 0, -1);System.out.println(mylist);listOperations.rightPop("mylist");Long size = listOperations.size("mylist");System.out.println(size);}/*** 操作集合类型的数据*/@Testpublic void testSet() {// sadd smembers scard sinter sunion sremSetOperations setOperations = redisTemplate.opsForSet();setOperations.add("set1","a","b","c");setOperations.add("set2","b","c","d");Set set1 = setOperations.members("set1");System.out.println(set1);Long size = setOperations.size("set1");System.out.println(size);Set intersect = setOperations.intersect("set1", "set2");System.out.println(intersect);Set union = setOperations.union("set1", "set2");System.out.println(union);setOperations.remove("set1","a","b");}/*** 操作有序集合类型的数据*/@Testpublic void testZSet() {// zadd zrange zincrby zremZSetOperations zSetOperations = redisTemplate.opsForZSet();zSetOperations.add("zset1","a",10);zSetOperations.add("zset1","b",11);zSetOperations.add("zset1","c",9);Set zset1 = zSetOperations.range("zset1", 0, -1);System.out.println(zset1);zSetOperations.incrementScore("zset1","c",10);zSetOperations.remove("zset1","a","b");}/*** 通用命令操作*/@Testpublic void testCommon() {// keys exists type delSet keys = redisTemplate.keys("*");System.out.println(keys);Boolean name = redisTemplate.hasKey("name");Boolean set1 = redisTemplate.hasKey("set1");for (Object key : keys) {DataType type = redisTemplate.type(key);System.out.println(type.name());}redisTemplate.delete("mylist");}

店铺营业状态设置:

        基于Redis的字符串来进行存储

        

        1表示营业,0表示打样

代码演示:

管理端设置营业状态、获取营业状态

@RequestMapping("/admin/shop")
@RestController("adminShopController")
@Slf4j
@Api(tags = "店铺相关接口")
public class ShopController {public static final String KEY = "SHOP_STATUS";@Autowiredprivate RedisTemplate redisTemplate;/*** 设置店铺的营业状态* @param status* @return*/@PutMapping("/{status}")@ApiOperation("设置营业状态")public Result setStatus(@PathVariable Integer status) {redisTemplate.opsForValue().set(KEY,status);log.info("设置当前营业状态为:{}",status == 1 ? "营业中" : "打烊中");return Result.success();}@GetMapping("/status")@ApiOperation("管理端获取营业状态")public Result<Integer> getStatus() {Integer status = (Integer) redisTemplate.opsForValue().get(KEY);log.info("当前的营业状态为:{}",status == 1 ? "营业中":"打烊中");return Result.success(status);}}

用户端获取营业状态

@RequestMapping("/user/shop")
@RestController("userShopController")
@Slf4j
@Api(tags = "店铺相关接口")
public class ShopController {public static final String KEY = "SHOP_STATUS";@Autowiredprivate RedisTemplate redisTemplate;@GetMapping("/status")@ApiOperation("用户端获取营业状态")public Result<Integer> getStatus() {Integer status = (Integer) redisTemplate.opsForValue().get(KEY);log.info("当前的营业状态为:{}",status == 1 ? "营业中":"打烊中");return Result.success(status);}}

HttpClient

使用HttpCilent需要导入依赖:

(如果导入了阿里云OSS的依赖就不需要导入了,因为这个依赖中已经包含了这个依赖)

核心API:

发送请求步骤:

代码演示:

    /*** 测试通过HttpClient发送GET方式的请求*/@Testpublic 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();}/*** 测试通过HttpClient发送GET方式的请求*/@Testpublic void testPOST() throws Exception {//创建HttpClient对象CloseableHttpClient httpClient = HttpClients.createDefault();//创建请求对象HttpPost httpPost = new HttpPost("http://localhost:8080/admin/employee/login");JSONObject jsonObject = new JSONObject();jsonObject.put("username", "admin");jsonObject.put("password", "123456");StringEntity entity = new StringEntity(jsonObject.toString());//指定请求编码方式entity.setContentEncoding("UTF-8");//指定数据格式entity.setContentType("application/json");httpPost.setEntity(entity);//发送请求CloseableHttpResponse response = httpClient.execute(httpPost);//解析返回结果int statusCode = response.getStatusLine().getStatusCode();System.out.println("响应码为:" + statusCode);HttpEntity entity1 = response.getEntity();String body = EntityUtils.toString(entity1);System.out.println("响应数据为:" + body);//关闭资源response.close();httpClient.close();}

用户端微信小程序开发:

小程序目录结构:

主体:

页面:

微信登录过程:

Redis缓存菜品、套餐

原因:

        使用数据库一直查找会导致系统响应慢、用户体验差。所以使用Redis缓存。

缓存菜品:

实现思路:

Spring Cache:

常用注解:

                                                                                                                     (cacheName::key)↑

@Cacheable注解在方法执行前会通过动态代理,代理出一个Controller对象,然后判断缓存中是否有数据,如果有,则直接返回缓存数据,不再执行方法,如果没有,就会通过反射来调用方法。

删除全部:

Spring Task

定位:

        定时任务框架

cron表达式:

        注意:日和周只能一个填数值一个填?

        使用Spring Task对超时订单和一直配送中的订单进行处理

WebSocket

介绍:

应用场景:

        ·视频弹幕

        ·网页聊天

        ·体育实况更新

        ·股票基金报价实时更新

实现步骤:

       

         使用WebSocket来完成来单提醒和客户催单功能。

设计:

Apache POI

介绍:

应用场景:

创新点:

        1.用户端根据分类id查看菜品:通过在service、mapper层添加获取在售(status=1)商品/套餐方法,替代通过创建实体类对象进行list方法查找,将查询时间由5~17ms变为4~7ms。

        2.将工作台订单数据使用redis存储,实时更新。

相关文章:

Java单体架构项目_云霄外卖-特殊点

项目介绍&#xff1a; 定位&#xff1a; 专门为餐饮企业&#xff08;餐厅、饭店&#xff09;定制的一款软件商品 分为&#xff1a; 管理端&#xff1a;外卖商家使用 用户端&#xff08;微信小程序&#xff09;&#xff1a;点餐用户使用。 功能架构&#xff1a; &#xff08…...

一文搞懂 java 线程池:ScheduledThreadPool 和 WorkStealingPool 原理

你好&#xff0c;我是 shengjk1&#xff0c;多年大厂经验&#xff0c;努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注&#xff01;你会有如下收益&#xff1a; 了解大厂经验拥有和大厂相匹配的技术等 希望看什么&#xff0c;评论或者私信告诉我&#xff01; 文章目录 一…...

轮换IP是什么?——深入了解轮换IP的特点

大家在日常上网时&#xff0c;可能听说过“轮换IP”这个词。那么&#xff0c;轮换IP到底是什么&#xff1f;它有哪些特点&#xff1f;今天&#xff0c;我们就来揭开轮换IP的神秘面纱。 什么是轮换IP&#xff1f; 简单来说&#xff0c;轮换IP是指定期更换上网时使用的IP地址。…...

中英双语介绍美国的州:华盛顿州(Washington)

中文版 华盛顿州简介 华盛顿州&#xff08;Washington&#xff09;位于美国太平洋西北地区&#xff0c;以其壮丽的自然景观和蓬勃发展的经济闻名。以下是对华盛顿州的详细介绍&#xff0c;包括其地理位置、人口、经济、教育、文化和主要城市。 地理位置 华盛顿州北接加拿大…...

美工画师必看!AI绘画Stable Diffusion 一键生成 B 端图标教程,轻松制作商业可用的设计图标,从此告别加班!(附安装包)

大家好&#xff0c;我是画画的小强 在日常工作中&#xff0c;设计师在应对运营和UI设计的B端图标时&#xff0c;常常面临大量的构思、制作和渲染等工作&#xff0c;耗时耗力。我们可以利用Stable Diffusion(以下简称SD)结合AI的方式&#xff0c;帮助设计师优化图标的设计流程&…...

使用表单系统快速搭建邀请和签到系统

在组织活动时&#xff0c;邀请和签到环节往往是活动成败的关键之一。传统的纸质邀请和签到方式不仅费时费力&#xff0c;还容易出现各种问题&#xff0c;例如名单遗漏、签到混乱等。而使用TDuckX“搭建邀请和签到系统”将彻底改变这一现状&#xff0c;为活动组织者提供了一种高…...

Vue 3 入门与精通:为初学者打造的全面学习指南

引言&#xff1a; Vue.js&#xff0c;这款由尤雨溪创建的轻量级前端框架&#xff0c;以其简洁的API、双向数据绑定和组件化的开发模式&#xff0c;深受广大开发者喜爱。Vue 3 的发布&#xff0c;带来了更多的性能优化和功能增强&#xff0c;为开发者提供了更广阔的空间。本文旨…...

React+TS前台项目实战(二十四)-- 全局常用绘制组件Qrcode封装

文章目录 前言Qrcode组件1. 功能分析2. 代码详细注释3. 使用方式4. 效果展示(pc端 / 移动端) 总结 前言 今天要封装的Qrcode 组件&#xff0c;是通过传入的信息&#xff0c;绘制在二维码上&#xff0c;可用于很多场景&#xff0c;如区块链项目中的区块显示交易地址时就可以用到…...

寄5公斤哪个快递便宜?寄10多斤的物品怎么寄最划算?

作为一个频繁需要寄东西的大学生&#xff0c;每次选择快递公司都是一件头疼的事。尤其是寄5公斤左右的包裹&#xff0c;既要考虑价格&#xff0c;又要看服务质量。今天&#xff0c;我就来分享一些寄5公斤包裹省钱的干货&#xff0c;希望能帮到大家。云木寄快递首先要推荐的就是…...

【postgresql】索引

见的索引类型&#xff1a; B-tree 索引&#xff1a;这是最常用的索引类型&#xff0c;适用于大多数查询。B-tree索引可以高效地处理范围查询。 Hash 索引&#xff1a;适用于等值查询&#xff0c;但不支持范围查询。 GiST 索引&#xff1a;通用搜索树&#xff08;GiST&#xf…...

2D Game Kit在unity的使用

本文参考&#xff1a; 如何制作游戏&#xff1f;【不需要编程 __】新手30分钟 学会制作2D游戏&#xff01;_ 如何制作游戏 _ unity教学 _ 制作游戏 _ 2d游戏_哔哩哔哩_bilibili 1、下载2d game kit 新建一个unity工程&#xff0c;进入该工程后&#xff0c;在Window -> Ass…...

使用中国大陆镜像源安装最新版的 docker Deamon

在一个智算项目交付过程中&#xff0c;出现了新建集群中的全部 docker server V19 进程消失、仅剩 docker server 的 unix-socket 存活的现象。 为了验证是否是BD产品研发提供的产品deploy语句缺陷&#xff0c;需要在本地环境上部署一个简单的 docker Deamon 环境。尴尬的是&a…...

机器学习原理之 -- 支持向量机分类:由来及原理详解

支持向量机&#xff08;Support Vector Machine, SVM&#xff09;是统计学习理论的一个重要成果&#xff0c;广泛应用于分类和回归问题。SVM以其高效的分类性能和良好的泛化能力在机器学习领域中占据重要地位。本文将详细介绍支持向量机的由来、基本原理、构建过程及其优缺点。…...

华为机试HJ8合并表记录

华为机试HJ8合并表记录 题目&#xff1a; 数据表记录包含表索引index和数值value&#xff08;int范围的正整数&#xff09;&#xff0c;请对表索引相同的记录进行合并&#xff0c;即将相同索引的数值进行求和运算&#xff0c;输出按照index值升序进行输出。 想法&#xff1a…...

Leetcode 2043简易银行交易系统

题目描述 简易银行系统 尝试过 中等 相关标签 相关企业 提示 你的任务是为一个很受欢迎的银行设计一款程序&#xff0c;以自动化执行所有传入的交易&#xff08;转账&#xff0c;存款和取款&#xff09;。银行共有 n 个账户&#xff0c;编号从 1 到 n 。每个账号的初始余额存储…...

适合职场小白的待办事项管理方法和工具

刚入职场那会儿&#xff0c;我每天都像只无头苍蝇&#xff0c;忙得团团转却效率低下。待办事项像潮水般涌来&#xff0c;会议、报告、客户跟进……每一项都像是悬在头顶的利剑&#xff0c;让我焦虑不堪。我深知&#xff0c;管理好待办事项是职场生存的必修课&#xff0c;但该如…...

相机参数与图像处理技术解析

01. 相机内参和外参的含义&#xff1f;如果将图像放大两倍&#xff0c;内外参如何变化&#xff1f; 相机有两个最基础的数据&#xff1a;内参(Instrinsics)和外参(Extrinsics)&#xff0c;内参主要描述的是相机的CCD/CMOS感光片尺寸/分辨率以及光学镜头的系数&#xff0c;外参主…...

Ubuntu20.04安装Prometheus监控系统

环境准备&#xff1a; 服务器名称内网IP公网IPPrometheus服务器192.168.0.23047.119.21.167Grafana服务器192.168.0.23147.119.22.8被监控服务器192.168.0.23247.119.22.82 更改主机名方便辨认 hostnamectl set-hostname prometheus hostnamectl set-hostname grafana hostn…...

kafka consumer客户端消费逻辑解析

kafka consumer客户端消费逻辑解析 一、主要步骤二、提交策略【步骤2代码解析】【提交策略总结】 三、拉取策略四、消费策略【代码解析】【消费策略总结】 一、主要步骤 这是kafka客户端拉取消息的入口&#xff0c;有4个主要部分 1、启动后的准备 consumer线程启动后&#xff…...

打印机出现多个副本无法删除

打印机出现多个副本很烦人&#xff0c;尤其是在打印机在局域网内被多个主机共享的时候&#xff0c;一旦出现新的副本&#xff0c;原有副本全都变成脱机状态&#xff0c;其他电脑连接的共享打印机是原来的副本&#xff0c;所以要重新设置打印机共享&#xff0c;很烦人。 想要删…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码&#xff0c;专为学校招生场景量身打造&#xff0c;功能实用且操作便捷。 从技术架构来看&#xff0c;ThinkPHP提供稳定可靠的后台服务&#xff0c;FastAdmin加速开发流程&#xff0c;UniApp则保障小程序在多端有良好的兼…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)

参考官方文档&#xff1a;https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java&#xff08;供 Kotlin 使用&#xff09; 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

通过MicroSip配置自己的freeswitch服务器进行调试记录

之前用docker安装的freeswitch的&#xff0c;启动是正常的&#xff0c; 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...

Leetcode33( 搜索旋转排序数组)

题目表述 整数数组 nums 按升序排列&#xff0c;数组中的值 互不相同 。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 < k < nums.length&#xff09;上进行了 旋转&#xff0c;使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...

《Docker》架构

文章目录 架构模式单机架构应用数据分离架构应用服务器集群架构读写分离/主从分离架构冷热分离架构垂直分库架构微服务架构容器编排架构什么是容器&#xff0c;docker&#xff0c;镜像&#xff0c;k8s 架构模式 单机架构 单机架构其实就是应用服务器和单机服务器都部署在同一…...