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

基于 Redis GEO 实现条件分页查询用户附近的场馆列表

🎯 本文档详细介绍了如何使用Redis GEO模块实现场馆位置的存储与查询,以支持“附近场馆”搜索功能。首先,通过微信小程序获取用户当前位置,并将该位置信息与场馆的经纬度数据一同存储至Redis中。利用Redis GEO高效的地理空间索引能力,文档展示了如何初始化缓存、批量处理和存储场馆位置信息,以及执行基于距离和多种条件的分页查询。此外,还提供了计算两个地理位置间距离的工具类。此方案适用于开发具备地理定位功能的应用程序,如体育场馆预订系统。
🏠️ HelloDam/场快订(场馆预定 SaaS 平台)

文章目录

  • Redis GEO 介绍
  • 流程
  • 数据库设计
  • 实体类
  • 位置缓存初始化
  • 附近场馆条件查询

Redis GEO 介绍

Redis GEO模块为Redis数据库引入了地理位置处理的功能,使得开发者能够基于地理坐标(经纬度)进行数据的操作和查询。通过使用GEO功能,可以方便地存储带有地理位置信息的数据,并执行如添加地理位置、计算两个位置之间的距离、查找指定半径内所有位置等操作。这些特性非常适合于构建需要处理地理位置的应用程序,比如附近的人或地点搜索功能。Redis GEO背后的技术基于高效的GeoHash算法,将地理位置映射到一个字符串上,从而允许对地理位置进行快速检索。这一功能极大地扩展了Redis在地理空间数据处理方面的能力,使其成为开发具有地理定位功能应用的强大工具。

流程

1、小程序前端获取位置(在小程序中获取当前位置的功能通常是通过调用微信小程序提供的API来实现的)

2、后端将位置存储到数据库

3、附近场馆查询

  • 将位置信息存储到Redis GEO中
  • 查询的时候,先根据缓存查询附近的场馆,再带着附近场馆ID和查询条件去数据库中查询

数据库设计

为了实现附近场馆功能,需要存储场馆的经纬度信息

DROP TABLE IF EXISTS `venue`;
CREATE TABLE `venue`(`id` bigint NOT NULL COMMENT 'ID',`create_time` datetime,`update_time` datetime,`is_deleted` tinyint default 0 COMMENT '逻辑删除 0:没删除 1:已删除',`organization_id` bigint NOT NULL COMMENT '所属机构ID',`name` varchar(30) NOT NULL COMMENT '场馆名称',`type` int NOT NULL COMMENT '场馆类型 1:篮球馆(场) 2:足球场 3:羽毛球馆(场) 4:排球馆(场)100:体育馆 1000:其他',`address` varchar(255) NOT NULL COMMENT '场馆地址名称',`latitude` DECIMAL(9, 6) NOT NULL COMMENT '纬度',`longitude` DECIMAL(9, 6) NOT NULL COMMENT '经度',`description` varchar(255) DEFAULT '' COMMENT '场馆描述,也可以说是否提供器材等等',`open_time` varchar(2000) NOT NULL COMMENT '场馆营业时间',`phone_number` varchar(11) NULL DEFAULT '' COMMENT '联系电话',`status` tinyint NOT NULL COMMENT '场馆状态 0:关闭 1:开放 2:维护中',`is_open` tinyint NOT NULL COMMENT '是否对外开放 0:否 1:是 如果不对外开放,需要相同机构的用户才可以预定',`advance_booking_day` int NOT NULL COMMENT '提前可预定天数,例如设置为1,即今天可预订明天的场',`start_booking_time` time NOT NULL COMMENT '开放预订时间',PRIMARY KEY (`id`) USING BTREE
)

实体类

【查询请求类】

import com.vrs.convention.page.PageRequest;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.math.BigDecimal;/*** @Author dam* @create 2024/12/7 10:51*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class VenueListReqDTO extends PageRequest {/*** 场馆名称*/private String name;/*** 场馆类型 1:篮球馆(场) 2:足球场 3:羽毛球馆(场) 4:排球馆(场)100:体育馆 1000:其他*/private Integer type;/*** 维度*/private BigDecimal latitude;/*** 经度*/private BigDecimal longitude;/*** 多少千米*/private double km;/*** 场馆状态 0:关闭 1:开放 2:维护中*/private Integer status;
}

【返回实体类】

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.vrs.domain.base.BaseEntity;
import lombok.Data;import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalTime;/*** * @TableName venue*/
@TableName(value ="venue")
@Data
public class VenueRespDTO extends BaseEntity implements Serializable {/*** 所属机构ID*/private Long organizationId;/*** 所属机构名称*/private String organizationName;/*** 场馆名称*/private String name;/*** 场馆类型 1:篮球馆(场) 2:足球场 3:羽毛球馆(场) 4:排球馆(场)100:体育馆 1000:其他*/private Integer type;private String typeName;/*** 场馆地址*/private String address;/*** 场馆描述,也可以说是否提供器材等等*/private String description;/*** 场馆营业时间*/private String openTime;/*** 联系电话*/private String phoneNumber;/*** 场馆状态 0:关闭 1:开放 2:维护中*/private Integer status;private String statusName;/*** 是否对外开放 0:否 1:是 如果不对外开放,需要相同机构的用户才可以预定*/private Integer isOpen;/*** 提前可预定天数,例如设置为1,即今天可预订明天的场*/private Integer advanceBookingDay;/*** 开放预订时间*/private LocalTime startBookingTime;/*** 维度*/private BigDecimal latitude;/*** 经度*/private BigDecimal longitude;/*** 距离多少公里*/private Double distance;@TableField(exist = false)private static final long serialVersionUID = 1L;
}

位置缓存初始化

【初始化类】

当场馆服务启动起来的时候,调用cacheVenueLocations方法

import com.vrs.service.VenueService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;/*** @Author dam* @create 2025/1/28 9:59*/
@Component
@Slf4j
@RequiredArgsConstructor
public class VenueLocationCacheInit implements CommandLineRunner {private final VenueService venueService;@Overridepublic void run(String... args) throws Exception {log.info("读取数据库中的场馆信息,将其位置存储缓存到Redis");venueService.cacheVenueLocations();log.info("场馆位置缓存成功");}
}

【位置缓存加载】

这段代码通过流式处理从数据库中查询场馆的位置信息(经度和纬度),等到缓冲区数据到达容量之后,使用 Redis 的管道技术将这些信息批量存储到 Redis 的地理空间索引中。

通过分批处理(每次处理 1000 条数据)和管道技术,代码优化了数据存储的效率,减少了与 Redis 的交互次数,从而提升了性能。优点是降低了数据库和 Redis 的负载,提高了数据写入的速度,同时避免了内存溢出风险。

/*** 将场馆的位置信息存储到 Redis 中*/
@Override
@SneakyThrows
public void cacheVenueLocations() {// 获取 dataSource Bean 的连接@Cleanup Connection conn = dataSource.getConnection();@Cleanup Statement stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);stmt.setFetchSize(Integer.MIN_VALUE);// 查询sql,只查询关键的字段String sql = "SELECT id,latitude,longitude FROM venue where is_deleted = 0";@Cleanup ResultSet rs = stmt.executeQuery(sql);// 每次获取一行数据进行处理,rs.next()如果有数据返回true,否则返回falseList<VenueDO> buffer = new ArrayList<>();int bufferSize = 1000;while (rs.next()) {// 获取数据中的属性VenueDO venueDO = new VenueDO();venueDO.setId(rs.getLong("id"));venueDO.setLongitude(rs.getBigDecimal("longitude"));venueDO.setLatitude(rs.getBigDecimal("latitude"));buffer.add(venueDO);if (buffer.size() >= bufferSize) {cacheLocations(buffer);buffer.clear();}}if (buffer.size() >= 0) {cacheLocations(buffer);buffer.clear();}
}/*** 使用 Redis 管道将场馆位置添加到 Redis 缓存中** @param buffer*/
private void cacheLocations(List<VenueDO> buffer) {// 使用 Redis 管道批量操作redisTemplate.executePipelined((RedisCallback<?>) (connection) -> {for (VenueDO venue : buffer) {// 确保经纬度信息不为空if (venue.getLongitude() != null && venue.getLatitude() != null) {// 将场馆的经纬度信息存储到 Redis 中Point point = new Point(venue.getLongitude().doubleValue(), venue.getLatitude().doubleValue());connection.geoAdd(RedisCacheConstant.VENUE_LOCATION_KEY.getBytes(), point, venue.getId().toString().getBytes());}}// 管道操作不需要返回值return null;});
}

附近场馆条件查询

这段代码实现了一个基于地理位置和多种条件的分页查询场馆信息的功能。

  • 首先根据用户提供的经纬度和半径范围,从缓存中查询出附近的场馆ID列表。
  • 然后,结合用户输入的其他条件(如场馆名称、类型、状态等),构建查询条件,从数据库中筛选出符合条件的场馆信息。注意构建查询条件的时候,需要使用 in 语句 传入 附近场馆ID列表。
  • 接着将查询结果转换为响应对象(DTO),并计算每个场馆与用户当前位置的距离,最后返回分页后的场馆信息列表。
@Override
public PageResponse<VenueRespDTO> pageVenueDO(VenueListReqDTO request) {List<Long> venueIdList = null;if (request.getLatitude() != null && request.getLongitude() != null) {// 先去缓存中,把位置靠近的场馆ID查询出来venueIdList = this.findVenuesWithinRadius(request.getLongitude(), request.getLatitude(), request.getKm());}LambdaQueryWrapper<VenueDO> queryWrapper = Wrappers.lambdaQuery(VenueDO.class);// 只查询附近的场馆if (venueIdList != null) {if (venueIdList.size() > 0) {queryWrapper.in(VenueDO::getId, venueIdList);} else {return new PageResponse(request.getCurrent(), request.getSize(), 0L, null);}}// 根据名字模糊查询if (!StringUtils.isBlank(request.getName())) {queryWrapper.like(VenueDO::getName, "%" + request.getName() + "%");}// 根据类型查询if (request.getType() != null) {queryWrapper.eq(VenueDO::getType, request.getType());}// 根据状态查询if (request.getStatus() != null) {queryWrapper.eq(VenueDO::getStatus, request.getStatus());}// 查询对方开放场馆,或者相同机构的场馆queryWrapper.eq(VenueDO::getIsOpen, 1).or().eq(VenueDO::getOrganizationId, UserContext.getOrganizationId());IPage<VenueDO> page = baseMapper.selectPage(new Page(request.getCurrent(), request.getSize()), queryWrapper);List<VenueRespDTO> venueRespDTOList = new ArrayList<>();for (VenueDO record : page.getRecords()) {VenueRespDTO venueRespDTO = new VenueRespDTO();BeanUtils.copyProperties(record, venueRespDTO);venueRespDTO.setTypeName(VenueTypeEnum.findValueByType(record.getType()));venueRespDTO.setStatusName(VenueStatusEnum.findValueByType(record.getStatus()));// 计算距离并设置到 DTO 中if (request.getLatitude() != null && request.getLongitude() != null) {double distance = DistanceUtil.calculateDistance(request.getLatitude().doubleValue(),request.getLongitude().doubleValue(),record.getLatitude().doubleValue(),record.getLongitude().doubleValue());venueRespDTO.setDistance(distance);}venueRespDTOList.add(venueRespDTO);}return new PageResponse(request.getCurrent(), request.getSize(), page.getTotal(), venueRespDTOList);
}/*** 根据经纬度和半径(公里)查询附近的场馆 ID** @param longitude 经度* @param latitude  纬度* @param radiusKm  半径(公里)* @return 附近的场馆 ID 列表*/
public List<Long> findVenuesWithinRadius(BigDecimal longitude, BigDecimal latitude, double radiusKm) {// 获取 GeoOperationsGeoOperations<String, String> geoOps = redisTemplate.opsForGeo();// 定义查询的中心点和半径Point center = new Point(longitude.doubleValue(), latitude.doubleValue());Distance distance = new Distance(radiusKm, Metrics.KILOMETERS);Circle circle = new Circle(center, distance);// 执行地理空间查询GeoResults<RedisGeoCommands.GeoLocation<String>> results = geoOps.radius(// Redis 中的 keyRedisCacheConstant.VENUE_LOCATION_KEY,circle);// 提取场馆 ID 并返回return results.getContent().stream().map(result ->{Long venueId = Long.parseLong(result.getContent().getName());
//                            double venueDistance = result.getDistance().getValue();
//                            System.out.println("场馆 ID: " + venueId + ", 距离: " + venueDistance + " 公里");return venueId;}).collect(Collectors.toList());
}

【工具类】

该工具列的作用是:给定两个经纬度,求它们之间的距离(单位:千米)

/*** 根据经纬度结算公里* @Author dam* @create 2025/1/28 19:39*/
public class DistanceUtil {/*** 地球半径,单位:公里*/private static final double EARTH_RADIUS = 6371;/*** 计算两个经纬度点之间的距离(公里)** @param lat1 纬度 1* @param lon1 经度 1* @param lat2 纬度 2* @param lon2 经度 2* @return 距离(公里)*/public static double calculateDistance(double lat1, double lon1, double lat2, double lon2) {double dLat = Math.toRadians(lat2 - lat1);double dLon = Math.toRadians(lon2 - lon1);double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)+ Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2))* Math.sin(dLon / 2) * Math.sin(dLon / 2);double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));return EARTH_RADIUS * c;}
}

相关文章:

基于 Redis GEO 实现条件分页查询用户附近的场馆列表

&#x1f3af; 本文档详细介绍了如何使用Redis GEO模块实现场馆位置的存储与查询&#xff0c;以支持“附近场馆”搜索功能。首先&#xff0c;通过微信小程序获取用户当前位置&#xff0c;并将该位置信息与场馆的经纬度数据一同存储至Redis中。利用Redis GEO高效的地理空间索引能…...

【大数据技术】案例01:词频统计样例(hadoop+mapreduce+yarn)

词频统计(hadoop+mapreduce+yarn) 搭建完全分布式高可用大数据集群(VMware+CentOS+FinalShell) 搭建完全分布式高可用大数据集群(Hadoop+MapReduce+Yarn) 在阅读本文前,请确保已经阅读过以上两篇文章,成功搭建了Hadoop+MapReduce+Yarn的大数据集群环境。 写在前面 Wo…...

Selenium 使用指南:从入门到精通

Selenium 使用指南&#xff1a;从入门到精通 Selenium 是一个用于自动化 Web 浏览器操作的强大工具&#xff0c;广泛应用于自动化测试和 Web 数据爬取中。本文将带你从入门到精通地掌握 Selenium&#xff0c;涵盖其基本操作、常用用法以及一个完整的图片爬取示例。 1. 环境配…...

笔试-排列组合

应用 一个长度为[1, 50]、元素都是字符串的非空数组&#xff0c;每个字符串的长度为[1, 30]&#xff0c;代表非负整数&#xff0c;元素可以以“0”开头。例如&#xff1a;[“13”, “045”&#xff0c;“09”&#xff0c;“56”]。 将所有字符串排列组合&#xff0c;拼起来组成…...

Java序列化详解

1 什么是序列化、反序列化 在Java编程实践中&#xff0c;当我们需要持久化Java对象&#xff0c;比如把Java对象保存到文件里&#xff0c;或是在网络中传输Java对象时&#xff0c;序列化机制就发挥着关键作用。 序列化&#xff1a;指的是把数据结构或对象转变为可存储、可传输的…...

ChatGPT与GPT的区别与联系

ChatGPT 和 GPT 都是基于 Transformer 架构的语言模型&#xff0c;但它们有不同的侧重点和应用。下面我们来探讨一下它们的区别与联系。 1. GPT&#xff08;Generative Pre-trained Transformer&#xff09; GPT 是一类由 OpenAI 开发的语言模型&#xff0c;基于 Transformer…...

MySQL入门 – CRUD基本操作

MySQL入门 – CRUD基本操作 Essential CRUD Manipulation to MySQL Database By JacksonML 本文简要介绍操作MySQL数据库的基本操作&#xff0c;即创建(Create), 读取&#xff08;Read&#xff09;, 更新(Update)和删除&#xff08;Delete&#xff09;。 基于数据表的关系型…...

Redis背景介绍

⭐️前言⭐️ 本文主要做Redis相关背景介绍&#xff0c;包括核心能力、重要特性和使用场景。 &#x1f349;欢迎点赞 &#x1f44d; 收藏 ⭐留言评论 &#x1f349;博主将持续更新学习记录收获&#xff0c;友友们有任何问题可以在评论区留言 &#x1f349;博客中涉及源码及博主…...

PPT演示设置:插入音频同步切换播放时长计算

PPT中插入音频&同步切换&放时长计算 一、 插入音频及音频设置二、设置页面切换和音频同步三、播放时长计算 一、 插入音频及音频设置 1.插入音频&#xff1a;点击菜单栏插入-音频-选择PC上的音频&#xff08;已存在的音频&#xff09;或者录制音频&#xff08;现场录制…...

DIFY源码解析

偶然发现Github上某位大佬开源的DIFY源码注释和解析&#xff0c;目前还处于陆续不断更新地更新过程中&#xff0c;为大佬的专业和开源贡献精神点赞。先收藏链接&#xff0c;后续慢慢学习。 相关链接如下&#xff1a; DIFY源码解析...

[权限提升] Wdinwos 提权 维持 — 系统错误配置提权 - Trusted Service Paths 提权

关注这个专栏的其他相关笔记&#xff1a;[内网安全] 内网渗透 - 学习手册-CSDN博客 0x01&#xff1a;Trusted Service Paths 提权原理 Windows 的服务通常都是以 System 权限运行的&#xff0c;所以系统在解析服务的可执行文件路径中的空格的时候也会以 System 权限进行解析&a…...

【算法】回溯算法专题② ——组合型回溯 + 剪枝 python

目录 前置知识进入正题小试牛刀实战演练总结 前置知识 【算法】回溯算法专题① ——子集型回溯 python 进入正题 组合https://leetcode.cn/problems/combinations/submissions/596357179/ 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以…...

LeetCode:121.买卖股票的最佳时机1

跟着carl学算法&#xff0c;本系列博客仅做个人记录&#xff0c;建议大家都去看carl本人的博客&#xff0c;写的真的很好的&#xff01; 代码随想录 LeetCode&#xff1a;121.买卖股票的最佳时机1 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票…...

pytorch生成对抗网络

人工智能例子汇总&#xff1a;AI常见的算法和例子-CSDN博客 生成对抗网络&#xff08;GAN&#xff0c;Generative Adversarial Network&#xff09;是一种深度学习模型&#xff0c;由两个神经网络组成&#xff1a;生成器&#xff08;Generator&#xff09;和判别器&#xff0…...

Visual Studio Code应用本地部署的deepseek

1.打开Visual Studio Code&#xff0c;在插件中搜索continue&#xff0c;安装插件。 2.添加新的大语言模型&#xff0c;我们选择ollama. 3.直接点connect&#xff0c;会链接本地下载好的deepseek模型。 参看上篇文章&#xff1a;deepseek本地部署-CSDN博客 4.输入需求生成可用…...

用 HTML、CSS 和 JavaScript 实现抽奖转盘效果

顺序抽奖 前言 这段代码实现了一个简单的抽奖转盘效果。页面上有一个九宫格布局的抽奖区域&#xff0c;周围八个格子分别放置了不同的奖品名称&#xff0c;中间是一个 “开始抽奖” 的按钮。点击按钮后&#xff0c;抽奖区域的格子会快速滚动&#xff0c;颜色不断变化&#xf…...

Skewer v0.2.2安装与使用-生信工具43

01 Skewer 介绍 Skewer&#xff08;来自于 SourceForge&#xff09;实现了一种基于位掩码的 k-差异匹配算法&#xff0c;专门用于接头修剪&#xff0c;特别设计用于处理下一代测序&#xff08;NGS&#xff09;双端序列。 fastp安装及使用-fastp v0.23.4&#xff08;bioinfoma…...

C语言:链表排序与插入的实现

好的!以下是一篇关于这段代码的博客文章: 从零开始:链表排序与插入的实现 在数据结构的学习中,链表是一种非常基础且重要的数据结构。今天,我们将通过一个简单的 C 语言程序,来探讨如何实现一个从小到大排序的链表,并在其中插入一个新的节点。这个过程不仅涉及链表的基…...

【Elasticsearch】doc_values 可以用于查询操作

确实&#xff0c;doc values 可以用于查询操作&#xff0c;尽管它们的主要用途是支持排序、聚合和脚本中的字段访问。在某些情况下&#xff0c;Elasticsearch 也会利用 doc values 来执行特定类型的查询。以下是关于 doc values 在查询操作中的使用及其影响的详细解释&#xff…...

深度学习深度解析:从基础到前沿

引言 深度学习作为人工智能的一个重要分支&#xff0c;通过模拟人脑的神经网络结构来进行数据分析和模式识别。它在图像识别、自然语言处理、语音识别等领域取得了显著成果。本文将深入探讨深度学习的基础知识、主要模型架构以及当前的研究热点和发展趋势。 基础概念与数学原理…...

JVM的GC详解

获取GC日志方式大抵有两种 第一种就是设定JVM参数在程序启动时查看&#xff0c;具体的命令参数为: -XX:PrintGCDetails # 打印GC日志 -XX:PrintGCTimeStamps # 打印每一次触发GC时发生的时间第二种则是在服务器上监控:使用jstat查看,如下所示&#xff0c;命令格式为jstat -gc…...

【开源免费】基于Vue和SpringBoot的校园网上店铺系统(附论文)

本文项目编号 T 187 &#xff0c;文末自助获取源码 \color{red}{T187&#xff0c;文末自助获取源码} T187&#xff0c;文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…...

测压表压力表计量表针头针尾检测数据集VOC+YOLO格式4862张4类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;4862 标注数量(xml文件个数)&#xff1a;4862 标注数量(txt文件个数)&#xff1a;4862 …...

Vue 3 30天精进之旅:Day 12 - 异步操作

在现代前端开发中&#xff0c;异步操作是一个非常常见的需求&#xff0c;例如从后端API获取数据、进行文件上传等任务。Vue 3 结合组合式API和Vuex可以方便地处理这些异步操作。今天我们将重点学习如何在Vue应用中进行异步操作&#xff0c;包括以下几个主题&#xff1a; 异步操…...

【网络】3.HTTP(讲解HTTP协议和写HTTP服务)

目录 1 认识URL1.1 URI的格式 2 HTTP协议2.1 请求报文2.2 响应报文 3 模拟HTTP3.1 Socket.hpp3.2 HttpServer.hpp3.2.1 start()3.2.2 ThreadRun()3.2.3 HandlerHttp&#xff08;&#xff09; 总结 1 认识URL 什么是URI&#xff1f; URI 是 Uniform Resource Identifier的缩写&…...

[paddle] 矩阵相关的指标

行列式 det 行列式定义参考 d e t ( A ) ∑ i 1 , i 2 , ⋯ , i n ( − 1 ) σ ( i 1 , ⋯ , i n ) a 1 , i 1 a 2 , i 2 , ⋯ , a n , i n det(A) \sum_{i_1,i_2,\cdots,i_n } (-1)^{\sigma(i_1,\cdots,i_n)} a_{1,i_1}a_{2,i_2},\cdots, a_{n,i_n} det(A)i1​,i2​,⋯,in​…...

docker部署SpringBoot项目简单流程

一、docker基础命令理解学习 1、常见命令 docker启动之前要关闭防火墙systemctl stop firewalld # 关闭防火墙systemctl disable firewalld # 禁止开机启动防火墙systemctl start docker # 启动docker服务systemctl stop docker # 停止docker服务systemctl restart docker # …...

Python学习——函数参数详解

Python中的函数参数传递机制允许多种灵活的参数类型&#xff0c;可以根据需求灵活配置参数&#xff0c;这使得函数具有更强大的扩展性和适应性。以下是对各类参数类型的详细说明&#xff1a; 1. 定义函数的不同参数类型 1.1 位置参数 定义方式&#xff1a;def func(a, b2) 特…...

Chromium132 编译指南 - Android 篇(一):编译前准备

1. 引言 欢迎来到《Chromium 132 编译指南 - Android 篇》系列的第一部分。本系列指南将引导您逐步完成在 Android 平台上编译 Chromium 132 版本的全过程。Chromium 作为一款由 Google 主导开发的开源浏览器引擎&#xff0c;为众多现代浏览器提供了核心驱动力。而 Android 作…...

.Net / C# 繁体中文 与 简体中文 互相转换, 支持地方特色词汇

版本号 Nuget 搜索 “OpenCCNET”, 注意别找错, 好多库的名字都差不多 支持 “繁,简” 的互相转换, 支持多个地区常用词汇的转换, 还支持 日文的新旧转换. OpenCC 在 .Net 中的实现 https://github.com/CosineG/OpenCC.NET <PackageReference Include"OpenCCNET"…...