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

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

一、项目背景与需求分析

1.项目背景

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

2.需求分析

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

二、技术选型与架构设计

1.技术选型

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

2.架构设计

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

三、数据库设计

1.乘客表(passenger)

字段名类型备注
idINT主键,自增
nameVARCHAR乘客姓名
phoneVARCHAR乘客手机号
passwordVARCHAR乘客密码
addressVARCHAR乘客地址

2.司机表(driver)

字段名类型备注
idINT主键,自增
nameVARCHAR司机姓名
phoneVARCHAR司机手机号
passwordVARCHAR司机密码
statusINT司机状态(0:空闲,1:已抢单)

3.订单表(order)

字段名类型备注
idINT主键,自增
passenger_idINT乘客ID
start_addressVARCHAR起始地址
end_addressVARCHAR目的地址
statusINT订单状态(0:待抢单,1:已抢单,2:已完成)
driver_idINT抢单司机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.mzph.cn/diannao/65461.shtml

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

相关文章

brupsuite的基础用法常用模块(1)

proxy模块&#xff1a; Options: 设置代理端口&#xff0c;默认为8080端口&#xff0c;若8080端口被占用可在该界面更改代理端口. HTTP history: 拦截的历史请求&#xff0c;右键可做更多操作&#xff0c;很多操作与其他模块有关。&#xff08;清除历史的话右键选择clear p…

Kubernetes 的资源管理方式(二)

Kubernetes 的资源管理方式 命令式对象配置 命令式对象配置就是通过命令配置和配置文件去操作 Kubernetes 的资源。 命令式对象配置的方式操作资源&#xff0c;可以简单的认为&#xff1a;命令 yaml 配置文件&#xff08;里面是命令需要的各种参数&#xff09;。 ① 创建一…

Linux 笔记 SELinux 常见操作与介绍

SELinux&#xff08;Security-Enhanced Linux&#xff09;是 Linux 操作系统中的一种安全模块&#xff0c;旨在提供更细粒度的访问控制。它最初由美国国家安全局&#xff08;NSA&#xff09;开发&#xff0c;目的是增强 Linux 系统的安全性。SELinux 通过强制访问控制&#xff…

Postman接口测试03|执行接口测试、全局变量和环境变量、接口关联、动态参数、断言

目录 七、Postman 1、安装 2、postman的界面介绍 八、Postman执行接口测试 1、请求页签 3、响应页签 九、Postman的环境变量和全局变量 1、创建环境变量和全局变量可以解决的问题 2、postman中的操作-全局变量 1️⃣手动设置 2️⃣代码设置 3️⃣界面获取 4️⃣代…

旅游管理系统|Java|SSM|VUE| 前后端分离

【技术栈】 1⃣️&#xff1a;架构: B/S、MVC 2⃣️&#xff1a;系统环境&#xff1a;Windowsh/Mac 3⃣️&#xff1a;开发环境&#xff1a;IDEA、JDK1.8、Maven、Mysql5.7 4⃣️&#xff1a;技术栈&#xff1a;Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html 5⃣️数据库…

vulhub-wordpress靶场

一.主题上传漏洞 来到靶场点击主题选择add new 这里有一个上传主题的地方 我们可以去网上找到wordpress主题下载一个 wordpress模板 网页设计模板 免费 免费下载 - 爱给网 下载完成后对我们有用的东西只有这一个目录&#xff0c;把它拖出来 点开moban目录后&#xff0c;创建…

Linux 日志监控与报警系统实操

1.日志监控基础 监控文件变化&#xff1a; tail -f&#xff1a;实时查看文件末尾的变化。 tail -n&#xff1a;指定查看最近的 N 行。 结合管道过滤关键内容&#xff1a; 配合grep 提取特定关键字。 例子&#xff1a; tail -f /var/log/syslog | grep "error"2.…

【人工智能视角下的计算机系统:硬件、操作系统与进程管理基础】

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” 文章目录 电脑硬件的基本常识电脑操作系统&#xff08;软件&#xff09;的基本常识进程进程操作PCB的属性PCB…

【AI大模型系列】提示词基础技巧(三)

目录 技巧一&#xff1a;提供充分的背景信息 技巧二&#xff1a;精准用词&#xff0c;避免误解 技巧三&#xff1a;角色扮演 技巧四&#xff1a;分布提问&#xff0c;循序渐进解决问题 技巧五&#xff1a;充分利用大语言模型的知识库 技巧一&#xff1a;提供充分的背景信息…

bash 中 ${-#*i} 是什么意思?

-------------------------------------------------- author: hjjdebug date: 2024年 12月 25日 星期三 17:43:45 CST description: bash 中 ${-#*i} 是什么意思? -------------------------------------------------- 在centos 的 /etc/profile 中有这样的语句 for i in /…

Flink源码解析之:如何根据算法生成StreamGraph过程

Flink源码解析之&#xff1a;如何根据算法生成StreamGraph过程 在我们日常编写Flink应用的时候&#xff0c;会首先创建一个StreamExecutionEnvironment.getExecutionEnvironment()对象&#xff0c;在添加一些自定义处理算子后&#xff0c;会调用env.execute来执行定义好的Flin…

IntelliJ IDEA Docker集成

一、概述 Docker是一种用于在隔离和可复制环境中部署和运行可执行文件的工具。这可能很有用&#xff0c;例如&#xff0c;在与生产相同的环境中测试代码。 IntelliJ IDEA集成了Docker功能&#xff0c;并为创建Docker映像、运行Docker容器、管理Docker Compose应用程序、使用公…

【closerAI ComfyUI】快速洗图!高效快速的提示词反推节点——cliption,让洗图出图快人一步不爆显存!

添加图片注释,不超过 140 字(可选) 【closerAI ComfyUI】快速洗图!高效快速的提示词反推节点——cliption,让洗图出图快人一步不爆显存! 大家好,我是Jimmy。反推提示词的节点有很多,像Florence2 、Joycaption2、喵手等。都是非常优秀的。但是呢,就是占用设备资源,加…

Pandas-数据组合

文章目录 一. 连接数据1.简介2. 加载数据1. 添加行① 添加行-DataFrame连接② 添加行-DataFrame和Series连接③ 添加行-append函数④ 添加行-重置索引 2. 添加列① 添加列-concat函数② 添加列-通过dataframe[列名] [值]③ 添加列-通过dataframe[列名] Series对象④ 添加列-重…

第四周枝节

一. reverse函数 ###在写回文题的时候有以下函数&#xff1a; 高精度反转&#xff1a; &#xff08;在计算高精度时&#xff0c;我们输入的是从高位到低位&#xff0c;但在计算时从低位到高位&#xff0c;因此需要反转&#xff09; void turn(int a[])//反转数字 {int j 0;…

软件架构设计——数据表状态切换开关—未来之窗行业应用跨平台架构

一、样式 二、样式 /*开关示例*/.东方仙盟_灵颜妙手 {position: relative;display: inline-block;width: 60px;height: 34px;border-radius: 17px; /* 添加圆角效果&#xff0c;使开关看起来更圆润美观 */box-shadow: 0 0 5px rgba(0, 0, 0, 0.2); /* 添加淡淡的阴影效果&…

django --递归查询评论

表数据 树状结构 action(methods(GET, ), detailFalse) def get_info_pinglun(self, request, *args, **kwargs) -> Response:根据评论id查所有回复params wenxian_pinglun_id --> 评论id;wenxian_pinglun_id self.request.GET.get(wenxian_pinglun_id)results se…

向量叉积浅讲

线段交叉 前提条件有三个点o,a,b,如何判断b在线段oa何方向&#xff0c;可以使用叉积; 1、向量的叉积公式 假设 -点o的坐标是 ( o x , o y ) (o_x, o_y) (ox​,oy​) -点a的坐标是 ( a x , a y ) (a_x, a_y) (ax​,ay​) -点b的坐标是 ( b x , b y ) (b_x, b_y) (bx​,by​) …

适用于项目经理的跨团队协作实践:Atlassian Jira与Confluence集成

适用于项目经理的跨团队协作实践&#xff1a;Atlassian Jira与Confluence集成 现代项目经理的核心职责是提供可视性、保持团队一致&#xff0c;并确保团队拥有交付出色工作所需的资源。在过去几年中&#xff0c;由于分布式团队的需求不断增加&#xff0c;项目经理这一角色已迅速…

基于JAVA+SpringBoot+Vue的问卷调查系统

基于JAVASpringBootVue的问卷调查系统 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末附源码下载链接&#x1f345; 哈喽兄…