个人博客项目笔记_07

写文章

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

写文章需要 三个接口:

  1. 获取所有文章类别

  2. 获取所有标签

  3. 发布文章

1. 所有文章分类

1.1 接口说明

接口url:/categorys

请求方式:GET

请求参数:

参数名称参数类型说明

返回数据:

{"success":true,"code":200,"msg":"success","data":[{"id":1,"avatar":"/category/front.png","categoryName":"前端"},	{"id":2,"avatar":"/category/back.png","categoryName":"后端"},{"id":3,"avatar":"/category/lift.jpg","categoryName":"生活"},{"id":4,"avatar":"/category/database.png","categoryName":"数据库"},{"id":5,"avatar":"/category/language.png","categoryName":"编程语言"}]
}

1.2 Controller

package com.cherriesovo.blog.controller;import com.cherriesovo.blog.service.CategoryService;
import com.cherriesovo.blog.vo.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("categorys")
public class CategoryController {@Autowiredprivate CategoryService categoryService;@GetMappingpublic Result listCategory() {return categoryService.findAll();}
}

1.3 Service

public interface CategoryService {Result findAll();   //类别查询
}
@Service
public class CategoryServiceImpl implements CategoryService {public CategoryVo copy(Category category){CategoryVo categoryVo = new CategoryVo();BeanUtils.copyProperties(category,categoryVo);return categoryVo;}public List<CategoryVo> copyList(List<Category> categoryList){List<CategoryVo> categoryVoList = new ArrayList<>();for (Category category : categoryList) {categoryVoList.add(copy(category));}return categoryVoList;}@Overridepublic Result findAll() {//SELECT * FROM category;List<Category> categories = this.categoryMapper.selectList(new LambdaQueryWrapper<>());return Result.success(copyList(categories));}
}

2. 所有文章标签

2.1 接口说明

接口url:/tags

请求方式:GET

请求参数:

参数名称参数类型说明

返回数据:

{"success": true,"code": 200,"msg": "success","data": [{"id": 5,"tagName": "springboot"},{"id": 6,"tagName": "spring"},{"id": 7,"tagName": "springmvc"},{"id": 8,"tagName": "11"}]
}

2.2 Controller

@RestController
@RequestMapping("tags")
public class TagsController {@Autowiredprivate TagService tagsService;@GetMappingpublic Result findAll(){return tagsService.findAll();}}

2.3 Service

public interface TagService {Result findAll();   //查询所有的文章标签
}

TagServiceImpl:

	@Overridepublic Result findAll() {//SELECT * FROM tag;List<Tag> tags = this.tagMapper.selectList(new LambdaQueryWrapper<>());return Result.success(copyList(tags));}

3. 发布文章

3.1 接口说明

接口url:/articles/publish

请求方式:POST

请求参数:

参数名称参数类型说明
titlestring文章标题
idlong文章id(编辑有值)
bodyobject({content: “ww”, contentHtml: “

ww

↵”})
文章内容
category{id: 2, avatar: “/category/back.png”, categoryName: “后端”}文章类别
summarystring文章概述
tags[{id: 5}, {id: 6}]文章标签

返回数据:

{"success": true,"code": 200,"msg": "success","data": {"id":12232323}
}

3.2 Controller

package com.cherriesovo.blog.vo.params;import com.cherriesovo.blog.vo.CategoryVo;
import com.cherriesovo.blog.vo.TagVo;
import lombok.Data;import java.util.List;@Data
public class ArticleParam {private Long id;private ArticleBodyParam body;private CategoryVo category;private String summary;private List<TagVo> tags;private String title;
}
package com.cherriesovo.blog.vo.params;import lombok.Data;@Data
public class ArticleBodyParam {private String content;private String contentHtml;}
//json数据进行交互
@RestController
@RequestMapping("articles")
public class ArticleController {/** 发布文章* */@PostMapping("publish")public Result publish(@RequestBody ArticleParam articleParam){return articleService.publish(articleParam);}
}

3.3 Service

在这里插入图片描述

public interface ArticleService {//文章发布Result publish(ArticleParam articleParam);
}

ArticleServiceImpl:

ArticleServiceImpl共需要经历如下步骤:

  1. 创建一个 Article 对象,并设置其属性,最后将文章对象插入到数据库中。

    		Article article = new Article();article.setAuthorId(sysUser.getId());article.setCategoryId(articleParam.getCategory().getId());article.setCreateDate(System.currentTimeMillis());article.setCommentCounts(0);article.setSummary(articleParam.getSummary());	//摘要article.setTitle(articleParam.getTitle());article.setViewCounts(0);article.setWeight(Article.Article_Common);//设置了文章的 bodyId 属性为 -1L。通常情况下,-1L 通常被用作一个特殊的标记,表示某个值无效或未设置article.setBodyId(-1L);	//内容id//插入之后会自动生成一个文章idthis.articleMapper.insert(article);
    
  2. 将文章id与标签id进行关联——获取文章的标签列表,遍历标签列表,对每个标签执行以下操作:

    1. 创建一个 ArticleTag 对象,并设置其文章ID和标签ID。
    2. 将 ArticleTag 对象插入到数据库中(article_tag表)。
    List<TagVo> tags = articleParam.getTags();if (tags != null) {for (TagVo tag : tags) {ArticleTag articleTag = new ArticleTag();articleTag.setArticleId(article.getId());articleTag.setTagId(tag.getId());this.articleTagMapper.insert(articleTag);}}
    
  3. 文章内容存储(article_body表)

    		ArticleBody articleBody = new ArticleBody();articleBody.setContent(articleParam.getBody().getContent());articleBody.setContentHtml(articleParam.getBody().getContentHtml());articleBody.setArticleId(article.getId());articleBodyMapper.insert(articleBody);
    
  4. 更新article表中的body属性

    		article.setBodyId(articleBody.getId());articleMapper.updateById(article);
    
  5. 设置返回值

    		ArticleVo articleVo = new ArticleVo();articleVo.setId(article.getId());return Result.success(articleVo);
    
@Override@Transactionalpublic Result publish(ArticleParam articleParam) {/** 1、发布文章目的是构建article对象* 2、作者id——当前的登录用户* 3、要将标签加入到关联列表* 4、body 内容存储  要的是bodyId* *///此接口要加入到登录拦截中,否则会造成空指针异常SysUser sysUser = UserThreadLocal.get();Article article = new Article();article.setAuthorId(sysUser.getId());article.setCategoryId(articleParam.getCategory().getId());article.setCreateDate(System.currentTimeMillis());article.setCommentCounts(0);article.setSummary(articleParam.getSummary());	//摘要article.setTitle(articleParam.getTitle());article.setViewCounts(0);article.setWeight(Article.Article_Common);//设置了文章的 bodyId 属性为 -1L。通常情况下,-1L 通常被用作一个特殊的标记,表示某个值无效或未设置article.setBodyId(-1L);	//内容id//插入之后会自动生成一个文章idthis.articleMapper.insert(article);List<TagVo> tags = articleParam.getTags();if (tags != null) {for (TagVo tag : tags) {ArticleTag articleTag = new ArticleTag();articleTag.setArticleId(article.getId());articleTag.setTagId(tag.getId());this.articleTagMapper.insert(articleTag);}}//body内容存储(article_body表)ArticleBody articleBody = new ArticleBody();articleBody.setContent(articleParam.getBody().getContent());articleBody.setContentHtml(articleParam.getBody().getContentHtml());articleBody.setArticleId(article.getId());articleBodyMapper.insert(articleBody);//更新article表中的bodyarticle.setBodyId(articleBody.getId());articleMapper.updateById(article);//设置返回值ArticleVo articleVo = new ArticleVo();articleVo.setId(article.getId());return Result.success(articleVo);}
package com.cherriesovo.blog.dao.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.cherriesovo.blog.dao.pojo.ArticleTag;public interface ArticleTagMapper  extends BaseMapper<ArticleTag> {
}
package com.cherriesovo.blog.dao.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.cherriesovo.blog.dao.pojo.ArticleBody;public interface ArticleBodyMapper extends BaseMapper<ArticleBody> {
}
package com.cherriesovo.blog.vo;import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import java.util.List;@Data
public class ArticleVo {//一定要记得加 要不然 会出现精度损失@JsonSerialize(using = ToStringSerializer.class)private Long id;private String title;private String summary;private Integer commentCounts;private Integer viewCounts;private Integer weight;/*** 创建时间*/private String createDate;private String author;private ArticleBodyVo body;private List<TagVo> tags;private CategoryVo category;}
package com.cherriesovo.blog.dao.pojo;import lombok.Data;@Data
public class ArticleTag {private Long id;private Long articleId;private Long tagId;
}

当然登录拦截器中,需要加入发布文章的配置:

WebMVCConfig:

 @Overridepublic void addInterceptors(InterceptorRegistry registry) {//拦截test接口,后续实际遇到需要拦截的接口时,在配置为真正的拦截接口registry.addInterceptor(loginInterceptor).addPathPatterns("/test").addPathPatterns("/comments/create/change").addPathPatterns("/articles/publish");}

3.4 测试

4. AOP日志

定义一个自定义注解 LogAnnotation,用于在方法上添加日志相关的注解信息:

  • @Target(ElementType.METHOD):这个注解指定了 LogAnnotation 注解可以被应用于方法上。
  • @Retention(RetentionPolicy.RUNTIME):这个注解指定了 LogAnnotation 注解在运行时可见。
  • @Documented:这个注解指定了 LogAnnotation 注解将被包含在 Javadoc 中。
  • String module() default "";:这个注解定义了一个 module 属性,用于指定日志的模块,默认值为空字符串。
  • String operator() default "";:这个注解定义了一个 operator 属性,用于指定执行操作的操作者,默认值为空字符串。

这个自定义注解可以用于方法上,用于标记需要记录日志的方法,并且可以通过 moduleoperator 属性指定日志的模块和操作者。

Javadoc 是 Java 语言中用于生成 API 文档的工具。它能够根据源代码中的特定标记,自动生成与代码相关的文档。Javadoc 工具会扫描 Java 源代码中特定格式的注释,并根据这些注释生成 HTML 格式的 API 文档。这些注释通常以 /** 开头,以 */ 结尾,位于类、方法、字段等代码元素的前面。Javadoc 工具会解析这些注释中的标签和内容,并生成易于阅读和导航的 API 文档。)

package com.cherriesovo.blog.common.aop;import java.lang.annotation.*;/*** 日志注解*/
//TYPE代表可以放在类上面,METHOD代表可以放在方法上
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogAnnotation {String module() default "";String operator() default "";
}

LogAspect是一个使用了 Spring AOP的日志切面类:

  • @Aspect:这个注解标识了这个类是一个切面类,用于定义通知和切点的关系。

  • @Pointcut("@annotation(com.cherriesovo.blog.common.aop.LogAnnotation)"):这个注解定义了一个切点 logPointCut(),它表示当目标方法上存在 com.cherriesovo.blog.common.aop.LogAnnotation 注解时,这个切点会匹配到。

  • public void logPointCut() { }:这个方法定义了切点的具体内容,但方法体为空,因为它只是用于标识切点,实际的逻辑在通知方法中实现。

  • @Around("logPointCut()"):这个注解表示环绕通知,它表示在目标方法执行前后都会执行通知逻辑。

  • public Object around(ProceedingJoinPoint point) throws Throwable { }:这个方法是环绕通知的具体实现。在目标方法执行前记录开始时间,在执行后记录结束时间,并记录日志。

  • private void recordLog(ProceedingJoinPoint joinPoint, long time) { }:这个方法用于记录日志,它获取了目标方法的签名、注解信息、方法参数、请求信息等,并使用日志记录器将这些信息输出到日志中。

    • ProceedingJoinPoint 是 Spring AOP 中的一个接口,它提供了对连接点(Join Point)进行操作的功能。在面向切面编程中,连接点表示程序执行过程中的特定点,比如方法的调用或异常的处理等。

      ProceedingJoinPointJoinPoint 的子接口,在 Spring AOP 中,它专门用于表示可以执行的连接点,例如在环绕通知中,通过调用 proceed() 方法可以执行目标方法。

      通常,在环绕通知中,我们会将 ProceedingJoinPoint 对象作为参数传递给通知方法,在通知方法中可以通过调用 proceed() 方法来继续执行目标方法,也可以获取连接点的信息,如方法签名、参数等。

整个类的作用是,当目标方法被调用时,记录下方法的执行时间、方法的输入参数、请求的 IP 地址等信息,并将这些信息输出到日志中,以便进行日志记录和监控。

package com.cherriesovo.blog.common.aop;import com.alibaba.fastjson.JSON;
import com.cherriesovo.blog.utils.HttpContextUtils;
import com.cherriesovo.blog.utils.IpUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;/*** 日志切面*/
@Aspect //切面 定义了通知和切点的关系
@Component
@Slf4j
public class LogAspect {//切点@Pointcut("@annotation(com.cherriesovo.blog.common.aop.LogAnnotation)")public void logPointCut() {}//通知类,环绕通知@Around("logPointCut()")public Object around(ProceedingJoinPoint point) throws Throwable {long beginTime = System.currentTimeMillis();	//开始时间//执行方法Object result = point.proceed();//执行时长(毫秒)long time = System.currentTimeMillis() - beginTime;//保存日志recordLog(point, time);return result;}//记录日志private void recordLog(ProceedingJoinPoint joinPoint, long time) {//获取了目标方法的签名信息MethodSignature signature = (MethodSignature) joinPoint.getSignature();//通过签名获取目标方法Method method = signature.getMethod();//获取了目标方法上的 LogAnnotation 注解,以便获取注解中的信息LogAnnotation logAnnotation = method.getAnnotation(LogAnnotation.class);log.info("=====================log start================================");log.info("module:{}",logAnnotation.module());	//输出日志中的模块信息log.info("operation:{}",logAnnotation.operator());	//输出日志中的操作信息String className = joinPoint.getTarget().getClass().getName();	//获取目标方法所属类的类名String methodName = signature.getName();	//获取目标方法的方法名//输出请求的方法名,格式为类名.方法名()log.info("request method:{}",className + "." + methodName + "()");//请求的参数Object[] args = joinPoint.getArgs();	//获取目标方法的参数列表String params = JSON.toJSONString(args[0]);	//参数列表转换为 JSON 格式的字符串,这里只获取了第一个参数log.info("params:{}",params);	//输出请求的参数信息//获取request 设置IP地址HttpServletRequest request = HttpContextUtils.getHttpServletRequest();	获取当前的HttpServletRequest对象log.info("ip:{}", IpUtils.getIpAddr(request));	//输出请求的 IP 地址log.info("excute time : {} ms",time);	//输出方法的执行时间log.info("=====================log end================================");}}
package com.cherriesovo.blog.utils;import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;public class HttpContextUtils {/*用于获取当前线程的 HttpServletRequest 对象,通过 RequestContextHolder.getRequestAttributes() 获取到当前请求的属性对		 象,然后将其转换为 ServletRequestAttributes,再调用 getRequest() 方法获取到 HttpServletRequest 对象。*/public static HttpServletRequest getHttpServletRequest(){return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();}
}
package com.cherriesovo.blog.utils;import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;//IP 地址获取工具类 IpUtils,用于从 HTTP 请求中获取客户端的真实 IP 地址
public class IpUtils {private static Logger logger = LoggerFactory.getLogger(IpUtils.class);/*** 获取IP地址* 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址* 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址*/public static String getIpAddr(HttpServletRequest request) {String ip = null;try {ip = request.getHeader("x-forwarded-for");if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("Proxy-Client-IP");}if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("WL-Proxy-Client-IP");}if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("HTTP_CLIENT_IP");}if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("HTTP_X_FORWARDED_FOR");}if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {ip = request.getRemoteAddr();}} catch (Exception e) {logger.error("IPUtils ERROR ", e);}// 使用代理,则获取第一个IP地址if (StringUtils.isEmpty(ip) && ip.length() > 15) {if (ip.indexOf(",") > 0) {ip = ip.substring(0, ip.indexOf(","));}}return ip;}
}
      ip = request.getHeader("HTTP_CLIENT_IP");}if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("HTTP_X_FORWARDED_FOR");}if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {ip = request.getRemoteAddr();}} catch (Exception e) {logger.error("IPUtils ERROR ", e);}// 使用代理,则获取第一个IP地址if (StringUtils.isEmpty(ip) && ip.length() > 15) {if (ip.indexOf(",") > 0) {ip = ip.substring(0, ip.indexOf(","));}}return ip;
}

}


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

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

相关文章

2024Mathorcup(妈妈杯)数学建模C题python代码+数据教学

2024Mathorcup数学建模挑战赛&#xff08;妈妈杯&#xff09;C题保姆级分析完整思路代码数据教学 C题题目&#xff1a;物流网络分拣中心货量预测及人员排班 因为一些不可抗力&#xff0c;下面仅展示部分代码&#xff08;很少部分部分&#xff09;和部分分析过程&#xff0c;其…

uni-app调用苹果登录,并获取用户信息

效果 模块配置 dev中的配置 需要开启登录的权限&#xff0c;然后重新下载配置文件&#xff0c;发布打包基座&#xff0c;再运行程序 代码 <button click"appleLogin">苹果登录</button>function appleLogin() {uni.login({provider: apple,success: …

备战蓝桥杯---刷杂题2

显然我们直接看前一半&#xff0c;然后我们按照斜行看&#xff0c;我们发现斜行是递增的&#xff0c;而同一行从左向右也是递增的&#xff0c;因此我们可以直接二分&#xff0c;同时我们发现对称轴的数为Ck,2k. 我们从16斜行枚举即可 #include<bits/stdc.h> using name…

git push报错remote: Please remove the file from history and try again

原因&#xff1a;上传文件超过100M&#xff0c;找到此文件删除即可。 1、查看是哪个文件过大&#xff0c;此处对用红框里面的 a6de1336c67c3bac77757c5eff8c8001823f7c92&#xff0c;得到具体的文件名称 git rev-list --objects --all | grep a6de1336c67c3bac77757c5eff8c80…

如果你想在Nomad Web中操作Excel数据

大家好&#xff0c;才是真的好。 没有意外&#xff0c;我猜你也会想在Nomad Web中操作Excel数据&#xff0c;毕竟你在Notes客户机中就是这样操作的。 不过&#xff0c;一个运行在浏览器中&#xff0c;一个运行在Notes客户机&#xff08;操作系统&#xff09;中。因此&#xf…

host文件nginx代理 综合理解

之前一直理解得很糙 导致遇到问题很迷糊 今天经过大佬两句话讲明白了 特此记录 host文件 首先host做了代理 也就是对浏览器的DNS寻址做了拦截 具体原理可以参照当我们在地址栏输入URL的时候浏览器发生了什么 例如127.0.0.1 www.baidu.com 将 127.0.0.1 www.baidu.com 链接自…

骨传导耳机怎么选?盘点五款2024畅销热门机型推荐

作为有着多年工作经验的数码测评师&#xff0c;我最近收到很多粉丝朋友的私信&#xff0c;大部分都是想了解关于骨传导耳机怎样选择之类的问题&#xff0c;我们可以看到&#xff0c;目前市面上的骨传导耳机五花八门&#xff0c;它们的质量和性能都参差不齐&#xff0c;甚至有很…

鸿蒙开发-ArkTS语言-并发-案例

鸿蒙开发-UI-交互事件-键鼠事件 鸿蒙开发-UI-交互事件-焦点事件 鸿蒙开发-UI-交互事件-手势事件 鸿蒙开发-UI-web 鸿蒙开发-UI-web-页面 鸿蒙开发-ArkTS语言-基础类库 鸿蒙开发-ArkTS语言-并发 文章目录 前言 一、CPU密集型任务 1. 使用TaskPool进行图像直方图处理 2. 使用w…

【cocos creator】【TS】贝塞尔曲线,地图之间显示曲线,顺着曲线移动

参考&#xff1a; https://blog.csdn.net/Ctrls_/article/details/108731313 https://blog.csdn.net/qq_28299311/article/details/104009804 const { ccclass, property } cc._decorator;ccclass export default class mapPanel extends cc.Component {property(cc.Node)pla…

2024 年 3 月 Web3 游戏报告:市场趋势与投资动态

作者&#xff1a;stellafootprint.network 数据来源&#xff1a;Footprint Analytics GameFi Research 2024 年 3 月&#xff0c;比特币不断刷新纪录&#xff0c;成功跨越了月中的低谷。受益于宏观经济的积极态势&#xff0c;整个加密货币市场表现突出。与此同时&#xff0c…

宠物医院电子处方软件操作教程,兽医处方笺范例经验分享

宠物医院电子处方软件操作教程&#xff0c;兽医处方笺范例经验分享 一、前言 以下软件操作教程以&#xff0c;佳易王宠物店兽医电子处方管理系统软件为例说明 软件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 软件基本功能&#xff1a;权限管理&#xff…

Vscode设置滚轮进行字体大小的调节

Vscode设置滚轮进行字体大小的调节 正常的话按 ctrl 或者 ctrl - 进行字体的大小调节 1.打开Vscode&#xff0c;找打设置的图标&#xff0c;在点击设置&#xff0c;或者直接使用快捷键&#xff0c;【ctrl ,】 2. 在搜索框搜索Font Ligatures 3.双击进入settings.json ,找到如…

手持气象站功能介绍

TH-SQ5手持气象站是一种便携式设备&#xff0c;用于手动测量和记录气象参数&#xff0c;如温度、湿度、风速和气压。这些设备通常用于户外活动、教育和业余气象观测。以下是对机械式手持气象站的一些续写内容&#xff1a; 数据记录功能&#xff1a;虽然基本型号的机械式手持气象…

本地开发nginx代理服务器(2024-04-10)

1、nginx 解释 nginx 是一个高性能的HTTP和反向代理服务器&#xff0c;同时也是一个IMAP/POP3/SMTP 代理服务器。 在性能上&#xff0c;Nginx占用很少的系统资源&#xff0c;能支持更多的并发连接&#xff0c;达到更高的访问效率&#xff1b; 在功能上&#xff0c;Nginx是优…

密码学 | 椭圆曲线 ECC 密码学入门(二)

目录 4 椭圆曲线&#xff1a;更好的陷门函数 5 奇异的对称性 6 让我们变得奇特 ⚠️ 原文地址&#xff1a;A (Relatively Easy To Understand) Primer on Elliptic Curve Cryptography ⚠️ 写在前面&#xff1a;本文属搬运博客&#xff0c;自己留着学习。如果你和我一样…

2024妈妈杯mathorcup B题详细思路代码:甲骨文智能识别中原始拓片单字自动分割与识别研究

甲骨文智能识别中原始拓片单字自动分割与识别研究&#xff1a; 问题一&#xff1a; 图像预处理&#xff1a;这通常包括将图像转换为灰度图&#xff0c;剔除噪声&#xff0c;调整对比度&#xff0c;以及可能的二值化处理&#xff0c;使得甲骨文的特征更加突出。此外&#xff0c…

2024年第十四届 Mathorcup (B题)| 甲骨文智能识别 | 深度学习 计算机视觉 |数学建模完整代码+建模过程全解全析

当大家面临着复杂的数学建模问题时&#xff0c;你是否曾经感到茫然无措&#xff1f;作为2022年美国大学生数学建模比赛的O奖得主&#xff0c;我为大家提供了一套优秀的解题思路&#xff0c;让你轻松应对各种难题。 让我们来看看Mathorcup (B题&#xff09;&#xff01; CS团队…

【随笔】Git 高级篇 -- 整理提交记录(下)rebase -i(十六)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…

如何在Windows通过固定tcp公网地址ssh远程访问本地Kali Linux

文章目录 1. 启动kali ssh 服务2. kali 安装cpolar 内网穿透3. 配置kali ssh公网地址4. 远程连接5. 固定连接SSH公网地址6. SSH固定地址连接测试 本文主要介绍如何在Kali系统编辑SSH配置文件并结合cpolar内网穿透软件&#xff0c;实现公网环境ssh远程连接本地kali系统。 1. 启…

操作系统③ —— 文件管理

前言 操作系统对文件管理中需要对磁盘块进行管理。这其中包含对空闲磁盘块和非空闲磁盘块的管理 对空闲磁盘块的管理涉及文件存储空间的管理。对非空闲磁盘块的管理涉及文件的物理结构/文件的分配方式。 1. 文件存储空间管理 1.1 存储空间的划分与初始化 存储空间的划分&a…