【商城实战(91)】安全审计与日志管理:为电商平台筑牢安全防线
【商城实战】专栏重磅来袭!这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建,运用 uniapp、Element Plus、SpringBoot 搭建商城框架,到用户、商品、订单等核心模块开发,再到性能优化、安全加固、多端适配,乃至运营推广策略,102 章内容层层递进。无论是想深入钻研技术细节,还是探寻商城运营之道,本专栏都能提供从 0 到 1 的系统讲解,助力你打造独具竞争力的电商平台,开启电商实战之旅。
目录
- 一、建立安全审计机制
- 1.1 审计内容与范围
- 1.2 Spring Boot 实现审计
- 1.3 MyBatis-Plus 在审计中的作用
- 二、开发日志管理系统
- 2.1 日志收集
- 2.2 日志存储
- 2.3 日志查询
- 三、分析审计与日志数据
- 3.1 潜在风险分析
- 3.2 防范措施
- 四、总结
一、建立安全审计机制
1.1 审计内容与范围
在商城系统中,安全审计机制需要记录的信息广泛。对于用户操作,涵盖登录、注册、密码修改、商品浏览、添加购物车、下单、支付、评论等。例如,用户登录时,记录登录时间、登录 IP、登录账号等信息,有助于追踪用户的登录行为,及时发现异常登录情况,如异地登录、频繁登录失败等。下单操作则记录下单时间、订单金额、购买商品列表、用户 ID 等,方便后续对订单相关操作的追溯。
系统事件方面,包括服务器错误(如 500 内部服务器错误、404 页面未找到等)、资源访问(如对数据库、文件系统的访问)、系统配置变更等。当服务器出现 500 错误时,记录错误发生时间、错误堆栈信息、触发错误的请求等,能够帮助开发人员快速定位问题。资源访问记录可以监控对关键数据的读取和修改操作,确保数据的安全性和完整性。
1.2 Spring Boot 实现审计
基于 Spring AOP 实现审计功能,首先需要添加相关依赖。在pom.xml文件中添加spring-boot-starter-aop依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>
接着定义一个自定义注解,用于标识需要审计的方法。例如:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AuditAnnotation {String value() default "";
}
然后创建切面类,在切面类中定义切点和增强逻辑。示例代码如下:
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;@Aspect
@Component
public class AuditAspect {private static final Logger logger = LoggerFactory.getLogger(AuditAspect.class);@Pointcut("@annotation(com.example.demo.AuditAnnotation)")public void auditPointCut() {}@Before("auditPointCut()")public void before(JoinPoint joinPoint) {logger.info("Before method {} execution", joinPoint.getSignature().getName());}@AfterReturning(pointcut = "auditPointCut()", returning = "result")public void afterReturning(JoinPoint joinPoint, Object result) {logger.info("After method {} execution, result: {}", joinPoint.getSignature().getName(), result);}@AfterThrowing(pointcut = "auditPointCut()", throwing = "e")public void afterThrowing(JoinPoint joinPoint, Exception e) {logger.error("Method {} threw an exception: {}", joinPoint.getSignature().getName(), e.getMessage());}@Around("auditPointCut()")public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {logger.info("Around method {} execution, start", proceedingJoinPoint.getSignature().getName());Object result = proceedingJoinPoint.proceed();logger.info("Around method {} execution, end", proceedingJoinPoint.getSignature().getName());return result;}
}
在上述代码中,@Pointcut定义了切点,即被@AuditAnnotation注解标注的方法。@Before、@AfterReturning、@AfterThrowing和@Around分别表示在方法执行前、执行成功后、抛出异常后和环绕方法执行时的增强逻辑。
1.3 MyBatis-Plus 在审计中的作用
MyBatis-Plus 与 Spring Boot 配合,可以方便地记录数据库操作相关的审计信息。在实体类中,可以通过自定义字段和注解来记录审计信息。例如,创建一个AuditEntity基类,包含创建时间、创建人、修改时间、修改人等字段:
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;import java.util.Date;@Data
public class AuditEntity {@TableField(fill = FieldFill.INSERT)private Date createTime;@TableField(fill = FieldFill.INSERT)private String createUser;@TableField(fill = FieldFill.INSERT_UPDATE)private Date updateTime;@TableField(fill = FieldFill.INSERT_UPDATE)private String updateUser;
}
其他需要审计的实体类继承AuditEntity,MyBatis-Plus 在执行插入和更新操作时,会自动填充这些字段。同时,可以通过自定义插件,在 SQL 执行前后记录审计信息。例如,创建一个自定义插件类:
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;import java.util.Date;@Component
public class MyMetaObjectHandler implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) {this.setFieldValByName("createTime", new Date(), metaObject);this.setFieldValByName("updateTime", new Date(), metaObject);// 获取当前用户,这里假设通过工具类获取String currentUser = "admin";this.setFieldValByName("createUser", currentUser, metaObject);this.setFieldValByName("updateUser", currentUser, metaObject);}@Overridepublic void updateFill(MetaObject metaObject) {this.setFieldValByName("updateTime", new Date(), metaObject);// 获取当前用户,这里假设通过工具类获取String currentUser = "admin";this.setFieldValByName("updateUser", currentUser, metaObject);}
}
在上述代码中,MyMetaObjectHandler实现了MetaObjectHandler接口,重写了insertFill和updateFill方法,在插入和更新操作时自动填充审计字段。这样,通过 MyBatis-Plus 与 Spring Boot 的结合,能够有效地记录数据库操作相关的审计信息,为商城系统的安全审计提供有力支持。
二、开发日志管理系统
2.1 日志收集
在前端,无论是 uniapp(用于移动前端)还是 Element plus(用于 PC 前端),都可以通过自定义日志收集函数来捕获用户操作相关的日志。以 uniapp 为例,在utils目录下创建log.js文件,代码如下:
export function log(message) {const logData = {timestamp: new Date().getTime(),message: message,// 可以添加更多信息,如当前页面路径等pagePath: getCurrentPages().pop().route};// 这里可以使用uni.request将日志发送到后端uni.request({url: 'http://your-backend-url/log',method: 'POST',data: logData,success: (res) => {console.log('Log sent successfully', res);},fail: (err) => {console.error('Failed to send log', err);}});
}
在需要记录日志的页面,引入该函数并调用。例如:
import { log } from '@/utils/log.js';export default {methods: {addToCart() {// 模拟添加购物车操作log('User added item to cart');}}
};
在 Element plus 前端项目中,类似地可以在src/utils目录下创建log.js文件,实现日志收集和发送功能:
import axios from 'axios';export function log(message) {const logData = {timestamp: new Date().getTime(),message: message,// 可以添加更多信息,如当前路由等route: this.$router.currentRoute.path};axios.post('http://your-backend-url/log', logData).then((res) => {console.log('Log sent successfully', res);}).catch((err) => {console.error('Failed to send log', err);});
}
在后端 Spring Boot 中,创建一个日志接收的 Controller。在src/main/java/com/example/demo/controller目录下创建LogController.java文件:
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;@RestController
public class LogController {@PostMapping("/log")public String receiveLog(@RequestBody LogData logData) {// 这里可以将日志数据传递给服务层进行进一步处理System.out.println("Received log: " + logData);return "Log received successfully";}
}class LogData {private long timestamp;private String message;private String pagePath; // 移动端日志包含的页面路径// 省略getter和setter方法
}
2.2 日志存储
使用 MyBatis-Plus 将日志存储到数据库。首先,创建日志实体类LogEntity。在src/main/java/com/example/demo/entity目录下创建LogEntity.java文件:
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;import java.util.Date;@Data
@TableName("log")
public class LogEntity {private Long id;private long timestamp;private String message;private String pagePath; // 移动端日志包含的页面路径private Date createTime;
}
然后,创建日志服务层接口LogService和实现类LogServiceImpl。在src/main/java/com/example/demo/service目录下创建LogService.java文件:
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.demo.entity.LogEntity;public interface LogService extends IService<LogEntity> {
}
在src/main/java/com/example/demo/service/impl目录下创建LogServiceImpl.java文件:
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.entity.LogEntity;
import com.example.demo.mapper.LogMapper;
import com.example.demo.service.LogService;
import org.springframework.stereotype.Service;import java.util.Date;@Service
public class LogServiceImpl extends ServiceImpl<LogMapper, LogEntity> implements LogService {@Overridepublic boolean saveLog(LogEntity logEntity) {logEntity.setCreateTime(new Date());return save(logEntity);}
}
其中,LogMapper由 MyBatis-Plus 自动生成,无需手动编写。在LogController中修改receiveLog方法,调用服务层保存日志:
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;@RestController
public class LogController {private final LogService logService;public LogController(LogService logService) {this.logService = logService;}@PostMapping("/log")public String receiveLog(@RequestBody LogData logData) {LogEntity logEntity = new LogEntity();logEntity.setTimestamp(logData.getTimestamp());logEntity.setMessage(logData.getMessage());logEntity.setPagePath(logData.getPagePath());if (logService.saveLog(logEntity)) {return "Log saved successfully";} else {return "Failed to save log";}}
}
2.3 日志查询
在前端,通过界面组件触发日志查询请求。以 Element plus 为例,创建一个日志查询页面LogQuery.vue:
<template><div><el-input v-model="queryParams.message" placeholder="Search by message"></el-input><el-button @click="queryLogs">Query</el-button><el-table :data="logs"><el-table-column prop="id" label="ID"></el-table-column><el-table-column prop="timestamp" label="Timestamp"></el-table-column><el-table-column prop="message" label="Message"></el-table-column><el-table-column prop="pagePath" label="Page Path"></el-table-column><el-table-column prop="createTime" label="Create Time"></el-table-column></el-table></div>
</template><script>
import axios from 'axios';export default {data() {return {queryParams: {message: ''},logs: []};},methods: {async queryLogs() {try {const response = await axios.post('http://your-backend-url/log/query', this.queryParams);this.logs = response.data;} catch (error) {console.error('Failed to query logs', error);}}}
};
</script>
在后端 Spring Boot 中,创建日志查询的 Controller 方法。在LogController中添加如下方法:
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController
public class LogController {private final LogService logService;public LogController(LogService logService) {this.logService = logService;}@PostMapping("/log/query")public List<LogEntity> queryLogs(@RequestBody LogQueryParams queryParams) {QueryWrapper<LogEntity> wrapper = new QueryWrapper<>();if (queryParams.getMessage() != null &&!queryParams.getMessage().isEmpty()) {wrapper.like("message", queryParams.getMessage());}return logService.list(wrapper);}
}class LogQueryParams {private String message;// 省略getter和setter方法
}
通过上述步骤,实现了日志管理系统的日志收集、存储和查询功能,能够有效地记录和管理商城系统中的日志信息。
三、分析审计与日志数据
3.1 潜在风险分析
通过对审计与日志数据的深入分析,可以发现多种潜在安全风险。例如,在用户登录方面,如果在一段时间内某个账号出现大量的登录失败记录,且这些失败记录来自不同的 IP 地址,这可能表明该账号正在遭受暴力破解攻击。假设通过日志查询发现,在某一小时内,用户 “user123” 的登录失败次数达到 50 次,且登录 IP 地址有 10 个不同的地址,这就明显超出了正常的登录行为范围,存在极大的安全风险。
在订单操作方面,若出现异常的订单修改或取消操作,也需要重点关注。比如,一个订单在短时间内被多次修改收货地址,且修改后的地址毫无规律,或者突然出现大量的订单在支付成功后立即被取消,这些都可能是恶意行为。例如,在某一天的订单日志中,发现有 100 个订单在支付成功后的 1 分钟内被取消,进一步调查发现这些订单的操作 IP 地址相同,这就很可能是有人在进行恶意刷单或其他欺诈行为。
3.2 防范措施
针对上述潜在风险,需要采取相应的防范措施。对于频繁登录失败的情况,可以限制登录次数。在 Spring Boot 中,可以通过配置过滤器来实现。在src/main/java/com/example/demo/config目录下创建LoginLimitFilter.java文件:
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;@WebFilter(filterName = "loginLimitFilter", urlPatterns = "/login")
public class LoginLimitFilter implements Filter {private static final int MAX_LOGIN_ATTEMPTS = 5;private static final Map<String, Integer> loginAttempts = new HashMap<>();@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;String username = request.getParameter("username");if (username != null) {Integer attempts = loginAttempts.getOrDefault(username, 0);if (attempts >= MAX_LOGIN_ATTEMPTS) {response.setStatus(HttpServletResponse.SC_FORBIDDEN);response.getWriter().println("Too many login attempts, please try again later.");return;}loginAttempts.put(username, attempts + 1);}filterChain.doFilter(request, response);}@Overridepublic void init(FilterConfig filterConfig) throws ServletException {// 初始化操作}@Overridepublic void destroy() {// 销毁操作}
}
同时,在src/main/java/com/example/demo/DemoApplication.java中添加过滤器注册:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}@Beanpublic FilterRegistrationBean<LoginLimitFilter> loginLimitFilterRegistrationBean() {FilterRegistrationBean<LoginLimitFilter> registrationBean = new FilterRegistrationBean<>();registrationBean.setFilter(new LoginLimitFilter());registrationBean.addUrlPatterns("/login");return registrationBean;}
}
对于异常订单操作,加强订单验证是关键。在订单处理的 Service 层方法中添加验证逻辑。例如,在src/main/java/com/example/demo/service/impl/OrderServiceImpl.java中:
import com.example.demo.entity.Order;
import com.example.demo.mapper.OrderMapper;
import com.example.demo.service.OrderService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;@Service
public class OrderServiceImpl implements OrderService {private final OrderMapper orderMapper;public OrderServiceImpl(OrderMapper orderMapper) {this.orderMapper = orderMapper;}@Override@Transactionalpublic boolean updateOrder(Order order) {// 验证订单修改的合法性Order originalOrder = orderMapper.selectById(order.getId());if (originalOrder == null) {return false;}// 检查收货地址是否合理,这里假设合理地址的判断逻辑if (!isValidAddress(order.getShippingAddress())) {return false;}// 其他验证逻辑return orderMapper.updateById(order) > 0;}private boolean isValidAddress(String address) {// 简单示例,实际应根据业务需求实现更复杂的验证return address != null &&!address.isEmpty();}
}
通过上述限制登录次数和加强订单验证等防范措施,可以有效地降低商城系统的安全风险,保障系统的稳定运行和用户数据的安全。
四、总结
安全审计与日志管理是商城系统中至关重要的环节,它们就像系统的 “安全卫士” 和 “记录员”。通过建立完善的安全审计机制,能够全面记录用户操作和系统事件,为系统的安全运行提供了有力的监控和追溯依据。而开发功能完备的日志管理系统,实现了日志的收集、存储和查询,使得系统运行过程中的各种信息能够被有效地管理和利用。通过对审计与日志数据的深入分析,能够及时发现潜在的安全风险,并采取针对性的防范措施,保障了商城系统的稳定运行和用户数据的安全。
未来,随着技术的不断发展和业务的日益复杂,安全审计与日志管理还需要不断优化和完善。在技术方面,可以引入人工智能和机器学习技术,实现对审计与日志数据的自动化分析和智能预警,提高发现潜在安全风险的效率和准确性。同时,进一步加强日志管理系统的性能优化,确保在高并发场景下也能稳定运行。在业务方面,要紧密结合商城的业务特点和发展需求,不断调整和完善审计内容和范围,使安全审计与日志管理更好地服务于商城的运营和发展。
相关文章:
【商城实战(91)】安全审计与日志管理:为电商平台筑牢安全防线
【商城实战】专栏重磅来袭!这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建,运用 uniapp、Element Plus、SpringBoot 搭建商城框架,到用户、商品、订单等核心模块开发,再到性能优化、安全加固、多端适配…...
Windows 10更新失败解决方法
在我们使用 Windows 时的时候,很多时候遇到系统更新 重启之后却一直提示“我们无法完成更新,正在撤销更改” 这种情况非常烦人,但其实可以通过修改文件的方法解决,并且正常更新到最新版操作系统 01修改注册表 管理员身份运行注…...
【安当产品应用案例100集】042-基于安当KADP实现机密文件安全流转
一、客户需求 某集团公司客户,在系统业务流中,存在大量的内部文件流转的需求。内部业务文件有不同的安全密级,最初在文件流转时,公司内部规定点对点的文件传输,要使用加密工具加密后再发给需要的一方。这种方式虽然能…...
【网络】Socket套接字
目录 一、端口号 二、初识TCP/UDP协议 三、网络字节序 3.1 概念 3.2 常用API 四、Socket套接字 4.1 概念 4.2 常用API (1)socket (2)bind sockaddr结构 (3)listen (4)a…...
蓝桥杯[每日一题] 真题:连连看
题目描述 小蓝正在和朋友们玩一种新的连连看游戏。在一个 n m 的矩形网格中,每个格子中都有一个整数,第 i 行第 j 列上的整数为 Ai, j 。玩家需要在这个网格中寻找一对格子 (a, b) − (c, d) 使得这两个格子中的整数 Aa,b 和 Ac,d 相等,且它…...
新手SEO优化实战快速入门
内容概要 对于SEO新手而言,系统化掌握基础逻辑与实操路径是快速入门的关键。本指南以站内优化为切入点,从网站结构、URL设计到内链布局,逐层拆解搜索引擎友好的技术框架;同时聚焦关键词挖掘与内容策略,结合工具使用与…...
Android面试总结之Glide源码级理解
当你的图片列表在低端机上白屏3秒、高端机因内存浪费导致FPS腰斩时,根源往往藏在Glide的内存分配僵化、磁盘混存、网络加载无优先级三大致命缺陷中。 本文从阿里P8级缓存改造方案出发,结合Glide源码实现动态内存扩容、磁盘冷热分区、智能预加载等黑科技&…...
基于类型属性的重载
算法重载 在一个泛型算法中引入更为特化的变体,这种设计和优化方式称为算法特化。之所以需要算法特化,原因有二: 针对特定类型使用更加合理的实现,对于const char *,less的第二个实现更加合理 template <typename…...
对称加密算法和非对称加密算法
在这个互联网普及的时代,在不同终端对敏感甚至机密数据进行传输是非常常见的场景,但是如何保证数据传输过程的安全性和高效性是一个值得深入探讨的问题。 为此,伟大的人类研究出了多种加密算法,我们可以大致将其分为两类…...
工程数字建造管理系统平台有哪些?好的数字建造管理系统推荐
一、什么是工程数字建造管理系统平台? 工程数字建造管理系统平台是一种集成了先进信息技术(如云计算、大数据、物联网等)的综合性管理工具,它旨在通过数字化手段提升工程建造全过程的管理效率和决策水平。这一平台不仅覆盖了工程…...
CMake ERROR: arm-none-eabi-gcc is not able to compile a simple test program.
用 cmake 构建 STM32 工程问题【已解决】 环境信息 os: ubuntu22.04gcc: arm-none-eabi-gcc (Arm GNU Toolchain 13.2.rel1 (Build arm-13.7)) 13.2.1 20231009cmake: cmake version 3.22.1ninja: 1.10.1 问题 log [main] 正在配置项目: Olidy [driver] 删除 /home/pomegr…...
容器主机CPU使用率突增问题一则
关键词 LINUX、文件系统crontab 、mlocate根目录使用率 There are many things that can not be broken! 如果觉得本文对你有帮助,欢迎点赞、收藏、评论! 一、问题现象 业务一台容器服务器,近期经常收到cpu不定期抖动告警&#x…...
CTFshow【命令执行】web29-web40 做题笔记
web29----过滤关键字 正则匹配,过滤flag,可以使用通配符绕过 先查看目录 使用通配符?查看flag 点击查看源代码 web30---过滤函数和关键字 看到过滤了system执行系统命令和flag,php关键字 找一个与其功能差不多的执行函数passthr…...
L2正则化:优化模型的平滑之道
常见的正则化方法1. **L1正则化(Lasso)**1.1基本原理1.2特点1.3数学推导1.4参数更新1.5选择合适的正则化系数1.6优点1.7缺点1.8实际应用中的注意事项1.9示例 2. **L2正则化(Ridge)**L2正则化的定义L2正则化如何防止过拟合1. **限制…...
Golang 的 GMP 调度机制常见问题及解答
文章目录 Golang GMP 调度模型详解常见问题基础概念1. GMP 各组件的作用是什么?2. 为什么 Go 需要自己的调度器?3. GOMAXPROCS 的作用是什么? 调度流程4. Goroutine 如何被调度到 M 上执行?5. 系统调用会阻塞整个线程吗࿱…...
使用VSCODE导致CPU占用率过高的处理方法
1:cpptools 原因:原因是C/C会在全局搜索文件,可以快速进行跳转;当打开的文件过大,全局搜索文件会占用大量CPU; 处理方法: 1:每次只打开小文件夹; 2:打开大文…...
17--华为防火墙智能选路全解:网络世界的智能导航系统
华为防火墙智能选路全解:网络世界的智能导航系统 开篇故事:快递小哥的烦恼与网络世界的相似性 想象你是个快递站站长,每天要处理来自全国各地的包裹。突然某天遇到: 🚚 双11爆仓:如何把包裹最快送到客户手…...
CSS-BFC(块级格式化上下文)
一、BFC 的本质理解(快递仓库比喻) 想象一个快递分拣仓库(BFC容器),这个仓库有特殊的规则: 仓库内的包裹(内部元素)摆放不影响其他仓库包裹必须整齐堆叠,不能越界不同仓…...
Java 大视界 -- Java 大数据在智慧港口集装箱调度与物流效率提升中的应用创新(159)
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...
ZygoPlanner:一种基于图形的三阶段框架,用于颧骨种植体植入的最佳术前规划|文献速递-医学影像人工智能进展
Title 题目 ZygoPlanner: A three-stage graphics-based framework for optimal preoperative planning of zygomatic implant placement ZygoPlanner:一种基于图形的三阶段框架,用于颧骨种植体植入的最佳术前规划 01 文献速递介绍 1.1 研究背景 颧…...
【2.项目管理】2.4 Gannt图【甘特图】
甘特图(Gantt)深度解析与实践指南 📊 一、甘特图基础模板 项目进度表示例 工作编号工作名称持续时间(月)项目进度(周)1需求分析3▓▓▓░░░░░░░2设计建模3░▓▓▓░░░░░░3编码开发3.5░░░▓▓▓▓░░…...
python学习笔记(1)
为什么要学python 目前在研究网站的搭建,想通过python搭建一个我的世界资源买卖的平台,然后就开始研究python了,其实这不是我第一次研究python了,之前学的都不咋样,现在温故而知新,好好研究一下python。 Python的变量 在此之前先简单的介绍一下变量,给第一次接触的小…...
刚刚整理实测可用的股票数据API接口集合推荐:同花顺、雅虎API、智兔数服、聚合数据等Python量化分析各项数据全面丰富
在金融科技高速发展的今天,股票API接口已成为开发者、量化交易者和金融从业者的核心工具之一。它通过标准化的数据接口,帮助用户快速获取实时或历史市场数据,为投资决策、策略回测和金融应用开发提供支持。本文将深入解析股票API的核心功能、…...
2025 年吉林省燃气企业从业人员考试:实用备考攻略与考试提分要点
2025 年吉林省燃气企业从业人员考试报名通过吉林燃气行业管理系统。报名资料包含企业的环保达标证明(燃气行业涉及环保要求)、个人的岗位任职证明等。实用备考攻略是,关注吉林在燃气分布式能源系统建设方面的进展,结合《燃气冷热电…...
dubbo http流量接入dubbo后端服务
简介 dubbo协议是基于TCP的二进制私有协议,更适合作为后端微服务间的高效RPC通信协议,也导致dubbo协议对于前端流量接入不是很友好。在dubo框架中,有两种方式可以解决这个问题: 多协议发布【推荐】,为dubbo协议服务暴…...
自动驾驶04:点云预处理03
点云组帧 感知算法人员在完成点云的运动畸变补偿后,会发现一个问题:激光雷达发送的点云数据包中的点云数量其实非常少,完全无法用来进行后续感知和定位层面的处理工作。 此时,感知算法人员就需要对这些数据包进行点云组帧的处理…...
小程序中过滤苹果设备中的表情(即 emoji)
在小程序中过滤苹果设备中的表情(即 emoji),通常需要考虑以下几个方面:识别 emoji、处理用户输入、以及在显示或存储时进行过滤。以下是具体的实现思路和步骤: 1. 理解苹果中的表情(Emoji) 苹果…...
软件性能测试中的“假阳性”陷阱
软件性能测试中的“假阳性”陷阱主要表现为错误警报频繁、资源浪费严重、测试可信度降低。其中,错误警报频繁是最常见且最严重的问题之一,“假阳性”现象会导致开发团队在解决不存在的问题上花费大量时间。据行业调查显示,超过30%的性能优化成…...
现代优雅品牌杂志包装徽标设计衬线英文字体安装包 Relish – Aesthetic Font
CS Relish – 美学字体:优雅与现代简约的结合 永恒的现代 Serif 字体 CS Relish 是一种现代衬线字体,将极简主义美学与精致精致融为一体。凭借其时尚、干净的字体和平衡的结构,它给人一种优雅和现代的印象。这款字体专为那些欣赏微妙和优雅的…...
《Oracle服务进程精准管控指南:23c/11g双版本内存优化实战》 ——附自动化脚本开发全攻略
正在学习或者是使用 Oracle 数据库的小伙伴,是不是对于那个一直启动且及其占用内存的后台进程感到烦躁呢?而且即使是手动去开关也显得即为麻烦,所以基于我之前所学习到的方法,我在此重新整理,让大家动动手指就能完成开…...
《寒门枭雄传》章回目录与核心故事设计(36回)
《寒门枭雄传》章回目录与核心故事设计(36回) 主线:寒门崛起→权力异化→制度轮回 核心冲突:个人奋斗 vs 制度性压迫 第一卷京口草鞋摊的野望(第1-12回) 主题:寒门之困始于生存,终…...
C语言学习笔记(抱佛脚版)
毕业一年,发现记性是真的差,每次想起之前的知识总是想不全,看别人写的资料也懵懵懂懂。于是我索性自己再学一遍,并且记录一下。希望对你们也有所帮助。 正片开始! 前面的什么if for都不难理解,嵌套的话也…...
DeepSeek-V3-0324 模型发布:开源 AI 性能再攀高峰,推理与编码能力逼近顶级闭源模型
2025 年 3 月 24 日,国内 AI 公司深度求索(DeepSeek)悄然推出 V3 模型的升级版本 DeepSeek-V3-0324。尽管此次更新并非市场期待的 V4 或 R2 版本,但其在推理速度、编码能力、数学推理及开源生态上的突破,仍迅速引发全球…...
清晰易懂的Cursor实现AI编程从安装到实战TodoList开发
一、Cursor简介与安装部署 什么是Cursor? Cursor是一款基于AI的智能代码编辑器,它集成了强大的AI编程助手功能,能够通过自然语言交互帮助开发者生成、优化和调试代码。与传统的代码编辑器不同,Cursor可以理解你的编程意图&#…...
(二) 深入了解AVFoundation - 播放:AVFoundation 播放基础入门
引言 AVFoundation 是 Apple 提供的强大多媒体框架,支持音视频播放、录制、处理等功能。在 iOS 开发中,AVFoundation 是实现视频播放的核心技术之一。 本篇文章将简单介绍如何使用 AVPlayer、AVPlayerItem 和 AVPlayerLayer 进行视频播放,并…...
重磅推出稳联技术Profinet转CANopen网关智能工厂解决方案!
重磅推出稳联技术Profinet转CANopen网关智能工厂解决方案! 稳联技术Profinet转CANopen网关应运而生——它如同一座智能桥梁☺,打通两大主流工业协议,让异构网络无缝互联,助您释放设备潜力,实现真正的“万物互联”&…...
【问题解决】Linux安装conda修改~/.bashrc配置文件后,root 用户下显示 -bash-4.2#
问题描述 在Linux安装conda下的python环境时候,修改了~/.bashrc文件,修改完成后,再次进入服务器后,登录时候显示的不是正常的[rootlocalhost ~]#,而是-bash-4.2# 原因分析: 网上原因有:/root下…...
关于deepseek
DeepSeek:领先的人工智能研究与创新公司 公司简介 DeepSeek(深度求索)是一家专注于人工智能(AI)技术研发的创新公司,致力于推动大模型、自然语言处理(NLP)、机器学习(M…...
EtherCAT转ProfiNet协议转换网关构建西门子PLC与海克斯康机器人的冗余通信链路
一、案例背景 某电子制造企业的5G通信模块组装线,采用西门子S7-1200PLC(ProfiNet主站)进行产线调度,而精密组装工序由3台海克斯康工业机器人(EtherCAT从站)完成。由于协议差异,机器人动作与PLC…...
李宏毅机器学习笔记(1)—机器学习基本概念+深度学习基本概念
机器学习基本概念 1、获取模型 步骤 1.1、假定未知函数 带未知参数的函数 1.2、定义损失函数 真实值:label MAE MSE 几率分布,cross-entropy? 1.3、优化 单独考虑一个参数 让损失函数最小,找导数为零的点 单独考虑w,w…...
RAG生成中的多文档动态融合及去重加权策略探讨
目录 RAG生成中的多文档动态融合及去重加权策略探讨 一、RAG生成概述 二、多文档动态融合策略 1. 拼接与分段编码 2. 独立编码与后续融合 3. 基于查询的动态加权 三、检索结果的去重与加权策略 1. 去重策略 2. 加权策略 四、实践中的挑战与思考 五、结语 RAG生成中的…...
对匿名认证的理解
概述:在 Spring Security 中,** 匿名认证(Anonymous Authentication)** 是一种特殊的认证机制,用于处理未提供有效凭证的请求。 匿名认证的本质 目的:允许未认证用户访问特定资源。原理: 当请求…...
leetcoed0044. 通配符匹配 hard
1 题目:通配符匹配 官方难度:难 给你一个输入字符串 (s) 和一个字符模式 ( p ) ,请你实现一个支持 ‘?’ 和 ‘*’ 匹配规则的通配符匹配: ‘?’ 可以匹配任何单个字符。 ‘*’ 可以匹配任意字符序列(包括空字符序…...
航拍数据集汇总,覆盖车辆/船舶检测/物体评估/城市景观……
随着无人机的普及化和计算机视觉技术的迅猛发展,无人机航拍作为一种创新的摄影方式,正以前所未有的速度走进大众视野。它打破了传统拍摄的局限,为我们开启了「上帝视角」。航拍硬件性能逐渐逼近物理极限,算法优化的难度也日益增大…...
【SECS】初识SECS协议
【SECS】初识SECS协议 基本知识流和功能函数数量官方文件中缩写标注正常是不是都是主机向设备端?对数据信息中第1字节第1-2位官网介绍 S1F1双向指令说明测试H发起端E发起端 参考资料 基本知识 SECS(SEMI Equipment Communications Standard)即半导体设…...
RL基础以及AlphaGo、AlphaGo Zero原理
RL基础 Q价值函数和状态价值函数 Action-Value function: Q ( s , a ) Q(s, a) Q(s,a)是agent在状态s下执行某一个动作(如向上走),所获得的及时奖励和未来折扣的累计奖励 State-Value function: V ( s ) V(s) V(s)是…...
Android R adb remount 调用流程
目的:调查adb remount 与adb shell进去后执行remount的差异 调试方法:添加log编译adbd,替换system\apex\com.android.adbd\bin\adbd 一、调查adb remount实现 关键代码:system\core\adb\daemon\services.cpp unique_fd daemon_service_to…...
uvm sequence
UVM Sequence 是验证环境中生成和控制事务(Transaction)流的核心机制,它通过动态生成、随机化和调度事务,实现灵活多样的测试场景。以下是Sequence的详细解析: Sequence 的核心作用 事务流生成:通过 uvm_s…...
Java 代理(一) 静态代理
学习代理的设计模式的时候,经常碰到的一个经典场景就是想统计某个方法的执行时间。 1 静态代理模式的产生 需求1. 统计方法执行时间 统计方法执行时间,在很多API/性能监控中都有这个需求。 下面以简单的计算器为例子,计算加法耗时。代码如下…...
《初级社会工作者》考试题,附答案解析
一、单项选择题(共 60 题,每题 1 分) 1. 社会工作者在社区中开展针对留守儿童的支持小组活动,发现一名儿童因父母长期外出务工而产生严重的分离焦虑。此时,社会工作者应首先采取的介入策略是( )…...