Java网约车项目实战:实现抢单功能详解

news/2024/12/28 21:16:56/文章来源:https://www.cnblogs.com/TS86/p/18637963

在网约车项目中,抢单功能是非常关键的一部分,它决定了司机能否及时响应乘客的订单,提高整个平台的运营效率。本文将详细介绍如何使用Java来实现网约车项目的抢单功能,并提供一个完整的代码示例,以便读者能够直接运行和参考。

一、项目背景与需求分析

1.项目背景

随着移动互联网的快速发展,网约车已成为人们日常出行的重要选择。一个高效的网约车平台,除了需要提供良好的用户注册、登录、下单等功能外,还需要确保司机能够迅速响应乘客的订单,即实现抢单功能。

2.需求分析

  • 乘客端:乘客可以发布订单,并查看订单状态(如待抢单、已抢单、已完成等)。
  • 司机端:司机可以查看当前附近的订单,并选择抢单。抢单成功后,司机需前往乘客指定的地点接乘客。
  • 后台管理:管理员可以查看所有订单和司机的状态,进行必要的调度和管理。

二、技术选型与架构设计

1.技术选型

  • 后端:Java(Spring Boot框架)
  • 数据库:MySQL
  • 缓存:Redis(用于实现分布式锁,确保抢单操作的原子性)
  • 前端:Vue.js(乘客端和司机端界面)
  • 通信协议:HTTP/HTTPS(使用RESTful API进行前后端通信)

2.架构设计

  • 乘客端:负责接收乘客的输入,将订单信息发送到后端服务器。
  • 司机端:显示附近的订单列表,提供抢单功能,将抢单请求发送到后端服务器。
  • 后端服务器:处理乘客和司机的请求,存储订单信息,管理司机状态,实现抢单逻辑。
  • 数据库:存储乘客、司机、订单等信息。
  • Redis:用于实现分布式锁,确保在并发情况下只有一个司机能够成功抢单。

三、数据库设计

1.乘客表(passenger)

字段名 类型 备注
id INT 主键,自增
name VARCHAR 乘客姓名
phone VARCHAR 乘客手机号
password VARCHAR 乘客密码
address VARCHAR 乘客地址

2.司机表(driver)

字段名 类型 备注
id INT 主键,自增
name VARCHAR 司机姓名
phone VARCHAR 司机手机号
password VARCHAR 司机密码
status INT 司机状态(0:空闲,1:已抢单)

3.订单表(order)

字段名 类型 备注
id INT 主键,自增
passenger_id INT 乘客ID
start_address VARCHAR 起始地址
end_address VARCHAR 目的地址
status INT 订单状态(0:待抢单,1:已抢单,2:已完成)
driver_id INT 抢单司机ID(为空表示待抢单)

四、后端实现

1.创建Spring Boot项目

使用Spring Initializr创建一个Spring Boot项目,选择所需的依赖(如Spring Web、Spring Data JPA、MySQL Driver等)。

2.配置数据库连接

application.properties文件中配置数据库连接信息:

spring.datasource.url=jdbc:mysql://localhost:3306/ride_sharing?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

3.创建实体类

// Passenger.java
@Entity
public class Passenger {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String name;private String phone;private String password;private String address;// Getters and Setters
}// Driver.java
@Entity
public class Driver {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String name;private String phone;private String password;private Integer status = 0; // 0: 空闲, 1: 已抢单// Getters and Setters
}// Order.java
@Entity
public class Order {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private Long passengerId;private String startAddress;private String endAddress;private Integer status = 0; // 0: 待抢单, 1: 已抢单, 2: 已完成private Long driverId; // 为空表示待抢单// Getters and Setters
}

4.创建Repository接口

// PassengerRepository.java
public interface PassengerRepository extends JpaRepository<Passenger, Long> {}// DriverRepository.java
public interface DriverRepository extends JpaRepository<Driver, Long> {}// OrderRepository.java
public interface OrderRepository extends JpaRepository<Order, Long> {}

5.实现抢单逻辑

为了实现抢单功能的原子性,我们需要使用Redis来实现分布式锁。以下是实现抢单逻辑的Service类:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;@Service
public class OrderService {@Autowiredprivate OrderRepository orderRepository;@Autowiredprivate DriverRepository driverRepository;@Autowiredprivate StringRedisTemplate redisTemplate;private static final String LOCK_KEY = "order_lock:";private static final int LOCK_EXPIRE_TIME = 10; // 锁过期时间(秒)@Transactionalpublic String grabOrder(Long driverId, Long orderId) {// 使用Redis实现分布式锁String lockKey = LOCK_KEY + orderId;Boolean lock = redisTemplate.opsForValue().setIfAbsent(lockKey, "1", LOCK_EXPIRE_TIME, TimeUnit.SECONDS);if (lock == null || !lock) {return "抢单失败,订单已被其他司机抢单";}try {// 查询订单信息Optional<Order> optionalOrder = orderRepository.findById(orderId);if (!optionalOrder.isPresent()) {return "订单不存在";}Order order = optionalOrder.get();if (order.getStatus() != 0) {return "抢单失败,订单状态异常";}// 更新订单状态和司机IDorder.setStatus(1);order.setDriverId(driverId);orderRepository.save(order);// 更新司机状态Optional<Driver> optionalDriver = driverRepository.findById(driverId);if (optionalDriver.isPresent()) {Driver driver = optionalDriver.get();driver.setStatus(1);driverRepository.save(driver);}return "抢单成功";} finally {// 释放锁redisTemplate.delete(lockKey);}}public List<Order> getNearbyOrders(Double latitude, Double longitude) {// 根据经纬度查询附近的订单(这里简化处理,只返回所有待抢单订单)return orderRepository.findAllByStatus(0);}
}

6.创建Controller类

OrderController类的getNearbyOrders方法补充完整,并确保其逻辑与抢单功能相匹配。此外,为了更贴近实际需求,getNearbyOrders方法应当能够基于司机的位置(纬度和经度)来筛选附近的订单,尽管在实际应用中这通常涉及更复杂的地理空间查询。但在此示例中,为了简化,我们将仅返回所有待抢单的订单,并在注释中指出应如何实现更复杂的逻辑。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.List;@RestController
@RequestMapping("/api/orders")
public class OrderController {@Autowiredprivate OrderService orderService;@PostMapping("/grab")public String grabOrder(@RequestParam Long driverId, @RequestParam Long orderId) {return orderService.grabOrder(driverId, orderId);}@GetMapping("/nearby")public List<Order> getNearbyOrders(@RequestParam Double latitude, @RequestParam Double longitude) {// 在实际应用中,这里应该包含基于地理位置的查询逻辑,// 例如使用数据库中的地理空间索引或第三方地理空间搜索服务。// 但为了简化示例,我们仅返回所有待抢单的订单。// 注意:在生产环境中,直接返回所有待抢单订单可能不是最佳实践,// 因为这可能会暴露过多信息给司机,并增加后端服务器的负载。// 假设我们有一个方法来根据司机的位置计算附近订单的半径(例如5公里)// 但由于我们简化了地理空间查询,所以这里不实现这个方法。// 返回一个筛选后的订单列表,仅包含状态为“待抢单”的订单// 在实际应用中,这里应该有一个更复杂的查询,基于司机的位置和订单的位置return orderService.getNearbyOrders(0); // 0 表示待抢单状态// 注意:上面的调用中我们传递了状态码0作为参数,但在OrderService的getNearbyOrders方法中// 我们实际上并没有使用这个参数来进行筛选(因为我们的示例简化了地理空间查询)。// 在实际的OrderService实现中,你应该修改这个方法以接受状态码作为参数,并据此来筛选订单。// 例如:return orderRepository.findAllByStatusAndWithinRadius(0, latitude, longitude, radius);// 这里的withinRadius方法是一个假设的方法,用于执行地理空间查询。}
}

OrderController类的getNearbyOrders方法补充完整,并确保其逻辑与抢单功能相匹配。此外,为了更贴近实际需求,getNearbyOrders方法应当能够基于司机的位置(纬度和经度)来筛选附近的订单,尽管在实际应用中这通常涉及更复杂的地理空间查询。但在此示例中,为了简化,我们将仅返回所有待抢单的订单,并在注释中指出应如何实现更复杂的逻辑。

7. 配置安全性(如Spring Security)

为了保障系统的安全性,通常需要配置用户认证和授权。

配置类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/orders/grab/**").authenticated() // 需要认证才能访问抢单接口.anyRequest().permitAll().and().formLogin().permitAll().and().logout().permitAll();}@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}
}

8. 创建Service类

Service类用于处理业务逻辑,比如验证司机资格、更新订单状态等。

OrderService.java:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.util.Optional;@Service
public class OrderService {@Autowiredprivate OrderRepository orderRepository;@Autowiredprivate DriverRepository driverRepository;@Transactionalpublic boolean grabOrder(Long orderId, Long driverId) {Optional<Order> optionalOrder = orderRepository.findById(orderId);if (!optionalOrder.isPresent() || optionalOrder.get().getStatus() != OrderStatus.AVAILABLE) {return false;}Optional<Driver> optionalDriver = driverRepository.findById(driverId);if (!optionalDriver.isPresent()) {return false;}Order order = optionalOrder.get();order.setDriver(optionalDriver.get());order.setStatus(OrderStatus.GRABBED);orderRepository.save(order);return true;}
}

9. 配置消息队列(如RabbitMQ或Kafka)

对于抢单功能,使用消息队列可以提高系统的并发处理能力和响应速度。

RabbitMQ配置类:

import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class RabbitMQConfig {public static final String QUEUE_NAME = "orderQueue";@BeanQueue queue() {return new Queue(QUEUE_NAME, true);}@BeanSimpleMessageListenerContainer container(ConnectionFactory connectionFactory,MessageListenerAdapter listenerAdapter) {SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();container.setConnectionFactory(connectionFactory);container.setQueueNames(QUEUE_NAME);container.setMessageListener(listenerAdapter);return container;}@BeanMessageListenerAdapter listenerAdapter(OrderService orderService) {return new MessageListenerAdapter(orderService, "processOrder");}@BeanRabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {return new RabbitTemplate(connectionFactory);}
}

OrderService中添加处理消息的方法:

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class OrderService {// 之前的代码...@Autowiredprivate RabbitTemplate rabbitTemplate;public void publishOrder(Order order) {rabbitTemplate.convertAndSend(RabbitMQConfig.QUEUE_NAME, order);}public void processOrder(Order order) {// 逻辑处理,比如将订单状态更新为已分配等// 这里可以调用grabOrder方法或其他逻辑}
}

10. 单元测试

编写单元测试来验证你的抢单逻辑。

OrderServiceTest.java:

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;@ExtendWith(MockitoExtension.class)
public class OrderServiceTest {@Mockprivate OrderRepository orderRepository;@Mockprivate DriverRepository driverRepository;@InjectMocksprivate OrderService orderService;@Testpublic void testGrabOrderSuccess() {Order order = new Order();order.setId(1L);order.setStatus(OrderStatus.AVAILABLE);Driver driver = new Driver();driver.setId(1L);when(orderRepository.findById(1L)).thenReturn(Optional.of(order));when(driverRepository.findById(1L)).thenReturn(Optional.of(driver));boolean result = orderService.grabOrder(1L, 1L);assertTrue(result);verify(orderRepository, times(1)).save(any(Order.class));}@Testpublic void testGrabOrderOrderNotFound() {when(orderRepository.findById(1L)).thenReturn(Optional.empty());boolean result = orderService.grabOrder(1L, 1L);assertFalse(result);verify(orderRepository, never()).save(any(Order.class));}// 更多测试...
}

11. 日志记录

使用日志记录库(如SLF4J和Logback)来记录关键操作。

在application.properties中配置Logback:

properties复制代码logging.level.com.example.ridesharing=DEBUG

在Service类中记录日志:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;@Service
public class OrderService {private static final Logger logger = LoggerFactory.getLogger(OrderService.class);// 之前的代码...@Transactionalpublic boolean grabOrder(Long orderId, Long driverId) {logger.debug("Attempting to grab order {} by driver {}", orderId, driverId);Optional<Order> optionalOrder = orderRepository.findById(orderId);if (!optionalOrder.isPresent() || optionalOrder.get().getStatus() != OrderStatus.AVAILABLE) {logger.debug("Order {} is not available or does not exist", orderId);return false;}Optional<Driver> optionalDriver = driverRepository.findById(driverId);if (!optionalDriver.isPresent()) {logger.debug("Driver {} does not exist", driverId);return false;}Order order = optionalOrder.get();order.setDriver(optionalDriver.get());order.setStatus(OrderStatus.GRABBED);orderRepository.save(order);logger.debug("Order {} successfully grabbed by driver {}", orderId, driverId);return true;}
}

12. 部署和运维

最后,考虑如何部署和运维你的应用,包括使用Docker进行容器化、配置CI/CD管道等。

这些步骤和代码示例提供了一个完整的框架,用于实现一个包含抢单功能的网约车项目。当然,根据具体需求,你可能需要调整或添加更多的功能。

五、前端实现

在Java网约车项目实战中实现抢单功能的前端部分,通常可以使用前端框架如React、Vue.js或Angular来构建用户界面。为了简单起见,这里我们使用React和Redux来实现一个基本的前端应用,该应用允许司机查看订单并抢单。

1.项目结构

假设项目结构如下:

my-ridesharing-app/
├── public/
│   ├── index.html
│   └── ...
├── src/
│   ├── actions/
│   │   └── orderActions.js
│   ├── components/
│   │   ├── OrderList.js
│   │   ├── OrderItem.js
│   │   └── App.js
│   ├── reducers/
│   │   └── orderReducer.js
│   ├── store/
│   │   └── index.js
│   ├── index.js
│   └── ...
├── package.json
└── ...

2.安装依赖

首先,确保你已经安装了Node.js和npm,然后在项目根目录下运行以下命令来初始化React项目并安装必要的依赖:

npx create-react-app my-ridesharing-app
cd my-ridesharing-app
npm install redux react-redux redux-thunk axios

3.实现前端代码

(1) src/store/index.js - 配置Redux Store

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from '../reducers';const store = createStore(rootReducer, applyMiddleware(thunk));export default store;

(2)src/reducers/orderReducer.js - 定义Reducer

const initialState = {orders: [],loading: false,error: null,
};const fetchOrdersSuccess = (state, action) => ({...state,orders: action.payload,loading: false,error: null,
});const fetchOrdersFailure = (state, action) => ({...state,loading: false,error: action.payload,
});const grabOrderSuccess = (state, action) => {const updatedOrders = state.orders.map(order =>order.id === action.payload.id ? { ...order, grabbed: true } : order);return {...state,orders: updatedOrders,};
};const orderReducer = (state = initialState, action) => {switch (action.type) {case 'FETCH_ORDERS_REQUEST':return {...state,loading: true,};case 'FETCH_ORDERS_SUCCESS':return fetchOrdersSuccess(state, action);case 'FETCH_ORDERS_FAILURE':return fetchOrdersFailure(state, action);case 'GRAB_ORDER_SUCCESS':return grabOrderSuccess(state, action);default:return state;}
};export default orderReducer;

(3)src/actions/orderActions.js - 定义Action Creators

import axios from 'axios';export const fetchOrders = () => async dispatch => {dispatch({ type: 'FETCH_ORDERS_REQUEST' });try {const response = await axios.get('/api/orders'); // 假设后端API地址dispatch({ type: 'FETCH_ORDERS_SUCCESS', payload: response.data });} catch (error) {dispatch({ type: 'FETCH_ORDERS_FAILURE', payload: error.message });}
};export const grabOrder = orderId => async dispatch => {try {const response = await axios.post(`/api/orders/${orderId}/grab`); // 假设后端API地址dispatch({ type: 'GRAB_ORDER_SUCCESS', payload: response.data });} catch (error) {console.error('Grab order failed:', error.message);}
};

(4)src/components/OrderItem.js - 订单项组件

import React from 'react';
import { useDispatch } from 'react-redux';
import { grabOrder } from '../actions/orderActions';const OrderItem = ({ order }) => {const dispatch = useDispatch();const handleGrab = () => {dispatch(grabOrder(order.id));};return (<div><h3>{order.passengerName}</h3><p>Pickup: {order.pickupLocation}</p><p>Dropoff: {order.dropoffLocation}</p><button onClick={handleGrab} disabled={order.grabbed}>{order.grabbed ? 'Grabbed' : 'Grab Order'}</button></div>);
};export default OrderItem;

(5) src/components/OrderList.js - 订单列表组件

import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { fetchOrders } from '../actions/orderActions';
import OrderItem from './OrderItem';const OrderList = () => {const dispatch = useDispatch();const { orders, loading, error } = useSelector(state => state.orders);useEffect(() => {dispatch(fetchOrders());}, [dispatch]);if (loading) return <div>Loading...</div>;if (error) return <div>Error: {error}</div>;return (<div><h2>Orders</h2>{orders.map(order => (<OrderItem key={order.id} order={order} />))}</div>);
};export default OrderList;

(6)src/components/App.js - 主应用组件

import React from 'react';
import OrderList from './OrderList';
import { Provider } from 'react-redux';
import store from '../store';const App = () => (<Provider store={store}><div className="App"><h1>Ridesharing App</h1><OrderList /></div></Provider>
);export default App;

(7) src/index.js - 入口文件

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './components/App';
import reportWebVitals from './reportWebVitals';ReactDOM.render(<React.StrictMode><App /></React.StrictMode>,document.getElementById('root')
);reportWebVitals();

4.后端API

注意,上面的代码假设后端API存在,并且提供了以下两个端点:

(1)GET /api/orders - 获取所有未被抓取的订单。

(2)POST /api/orders/:orderId/grab - 抓取指定订单。

你需要在后端实现这些API端点,并确保它们能够返回正确的数据。

5.运行应用

在项目根目录下运行以下命令来启动React应用:

bash复制代码npm start

这将启动开发服务器,并在浏览器中打开你的应用。你应该能看到一个订单列表,并且可以点击“Grab Order”按钮来抓取订单。

以上就是一个简单的React前端实现,用于在网约车项目中实现抢单功能。你可以根据实际需求进一步扩展和优化这个应用。

在Java网约车项目实战中,实现抢单功能是一个核心且复杂的部分。除了你提到的几个主要部分(项目背景与需求分析、技术选型与架构设计、数据库设计、后端实现、前端实现)外,通常还需要包含以下关键内容,以确保项目的完整性和健壮性:

六、系统测试

  1. 单元测试:针对后端实现的各个模块,编写单元测试代码,确保每个模块的功能正常。
  2. 集成测试:将各个模块集成在一起后,进行整体测试,确保系统整体功能正常。
  3. 压力测试:模拟高并发场景,测试系统在抢单等高并发操作下的性能和稳定性。
  4. 安全测试:测试系统的安全性,确保用户数据和订单信息不会被泄露或篡改。

七、性能优化

  1. 代码优化:对后端代码进行优化,提高代码的执行效率和可读性。
  2. 数据库优化:对数据库进行查询优化、索引优化等,提高数据库的查询速度和响应能力。
  3. 缓存策略:使用Redis等缓存技术,减少对数据库的访问压力,提高系统的响应速度。

八、部署与运维

  1. 系统部署:将系统部署到服务器或云平台上,确保系统能够正常运行。
  2. 运维监控:对系统进行监控,及时发现并处理系统异常和故障。
  3. 日志管理:对系统日志进行管理,确保日志的完整性和可读性,方便后续的问题排查和性能分析。

九、文档编写

  1. 技术文档:编写详细的技术文档,包括系统的架构设计、数据库设计、接口文档等,方便后续的开发和维护。
  2. 用户手册:编写用户手册,指导用户如何使用系统,包括系统的功能介绍、操作流程等。

十、项目总结与反思

  1. 项目总结:对整个项目进行总结,包括项目的完成情况、遇到的问题及解决方案等。
  2. 经验反思:对项目的经验进行反思,总结在项目开发过程中的得失,为后续的项目开发提供参考。

综上所述,一个完整的Java网约车项目实战,除了实现抢单功能的核心部分外,还需要考虑系统测试、性能优化、部署与运维、文档编写以及项目总结与反思等关键内容。这些内容对于确保项目的成功交付和后续维护具有重要意义。

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

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

相关文章

windows与虚拟机linux通过ssh进行连接并上传文件

windows与虚拟机linux通过ssh进行连接并上传文件 windows配置 以管理员打开powershell下载和启动安装ssh客服端 Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0 Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0 Start-Service sshd Set-Servi…

[Java/网络/HTTP(S)] 基于`Http(s)URLConnection`的网络请求工具(HttpRequestUtils)

1 序轻量级HTTP网络请求工具,接续:[Java SE/JDK/网络] 核心源码精讲:java.net.HttpURLConnection - 博客园/千千寰宇 [身份认证/JWT] 身份认证方案与HTTP请求中Authorization Header - 博客园/千千寰宇 【推荐】 [网络/HTTPS/Java] PKI公钥基础设施体系:数字证书(X.509)、C…

2024/12/17 【字符串】LeetCode 459.重复的子字符串 【❌】

https://programmercarl.com/0459.%E9%87%8D%E5%A4%8D%E7%9A%84%E5%AD%90%E5%AD%97%E7%AC%A6%E4%B8%B2.html#%E6%80%9D%E8%B7%AF https://leetcode.cn/problems/repeated-substring-pattern/ 子串结束位置大于中间位置的话,一定不能重复组成字符串。 如果 next[len - 1] != -1…

一起鸿蒙吧,现在到了「绝佳时刻」

摘要:它已经不止于可用和好用,而是迈向“必用”的新阶段了。 10月22日,原生鸿蒙操作系统如约而至。 作为一个全新的操作系统,原生鸿蒙拥有流畅、安全、智能、互联、精致五大原生特性,为无数用户开启了一个全新的数字生活方式。 如果你正在犹豫是否要升级原生鸿蒙系统,那么…

题目集7~8总结性博客

前言 在本学期的学习过程中,我们共完成了三次题目集的练习,其中第七题和第八题集在知识点、题量和难度上具有一定的代表性。总体而言,这两次题目集涵盖了面向对象编程(OOP)、设计模式、数据结构与算法、软件工程等多个核心知识点。 知识点总结: 面向对象编程(OOP): 类…

Python 中使用 Matplotlib 进行多图绘制

Python 中使用 Matplotlib 进行多图绘制 Matplotlib 是 Python 中非常强大的数据可视化工具,它可以用来生成简单到复杂的各种图形。无论是处理单张图表还是多图并列展示,Matplotlib 都能提供高效的支持。在本篇文章中,我们将介绍如何使用 Matplotlib 绘制多图,以便在同一画…

fping 的使用方法

fping简介 fping是一个小型命令行工具,用于向网络主机发送ICMP回应请求,类似于ping,但在ping多个主机时性能要高得多。 fping完全不同于ping,因为可以在命令行上定义任意数量的主机,或者指定包含要ping的IP地址或主机列表的文件。 与ping要等待某一主机连接超时或发回反馈…

.NET Bioss相关数据读写

本文我们介绍针对Bios如何读取、写入数据,比如最常见的SN读取以及烧录 WMI查询 先看看WMI方式,可以用于查询和管理Windows系统的各种信息,包括读取BIOS信息 WMI-Win32_BIOS,可以查看Bios版本、制造商以及Bios Sn等:1 var searcher = new ManagementObjectSear…

家居强电电路模拟程序总结

一、前言:这两次的PTA作业第一次是以前两次家居强电电路模拟程序为基础所扩展的,在上一次作业的基础上增加了一个新的互斥开关,互斥开关的电路符号为H,其12引脚之间电阻为5欧,13引脚之间电阻为10欧,还增加了一个新的受控窗帘,受控窗帘的电路符号为S,窗帘电阻为15欧,其…

Python 正则表达式进阶用法:字符集与字符范围详解

Python 正则表达式进阶用法:字符集与字符范围详解 正则表达式是文本处理和数据清洗中不可或缺的工具。在前面的学习中,我们已经了解了基本的正则表达式匹配,如匹配单个字符、字符串开始和结束的位置等。今天,我们将进入正则表达式的一个进阶主题:字符集(Character Set)和…

如何免费使用 Termius Pro 版?Termius 工具下载与破解教程

今天想和大家聊聊 Termius 工具,Termius的下载与Termius破解教程,一款跨平台的 SSH/SFTP 终端工具。它不仅功能强大,还特别适合需要频繁上传文件夹和进行远程管理的小伙伴。无论你是程序员、运维工程师,还是需要远程管理服务器的爱好者,这款工具都能成为你的得力助手!今天…

Python 正则表达式进阶用法:边界匹配

Python 正则表达式进阶用法:边界匹配 正则表达式是一种强大的工具,用于处理文本中的模式匹配。它广泛应用于文本查找、替换、数据清洗等任务。在学习了正则表达式的基础知识后,掌握更高级的用法将使得正则表达式的应用更加灵活。边界匹配(Boundary Matching)是正则表达式中…