6.显示评论 + 添加评论

1.显示评论

  • 数据层:根据实体查询一页评论数据、根据实体查询评论的数量
  • 业务层:处理查询评论的业务、处理查询评论数量的业务
  • 表现层:显示帖子详情数据时,同时显示该帖子所有的评论数据

1.1 数据访问层

  • entity_type:实体类型(评论目标类别,例如 1 代表帖子、2 代表评论、3代表用户)
  • entity_id:类型目标(id 为 1、id为 2 的帖子)
  • target_id:指向某个评论的回复目标

创建表的实体类型,在 entity 包下创建 Comment 的实体类:

package com.example.demo.entity;import java.util.Date;public class Comment {private int id;private int userId;private int entityType;private int entityId;private int targetId;private String content;private int status;private Date createTime;public int getId() {return id;}public void setId(int id) {this.id = id;}public int getUserId() {return userId;}public void setUserId(int userId) {this.userId = userId;}public int getEntityType() {return entityType;}public void setEntityType(int entityType) {this.entityType = entityType;}public int getEntityId() {return entityId;}public void setEntityId(int entityId) {this.entityId = entityId;}public int getTargetId() {return targetId;}public void setTargetId(int targetId) {this.targetId = targetId;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}public int getStatus() {return status;}public void setStatus(int status) {this.status = status;}public Date getCreateTime() {return createTime;}public void setCreateTime(Date createTime) {this.createTime = createTime;}@Overridepublic String toString() {return "Comment{" +"id=" + id +", userId=" + userId +", entityType=" + entityType +", entityId=" + entityId +", targetId=" + targetId +", content='" + content + '\'' +", status=" + status +", createTime=" + createTime +'}';}
}

开发实体组件:在 dao 包下新建一个接口 CommentMapper :

  •  查询评论需要支持分页查询,需要提供两个方法:查询某一页有多少个数据、一共有多少数据(知道总页数)
package com.example.demo.dao;import com.example.demo.entity.Comment;
import org.apache.ibatis.annotations.Mapper;import java.util.List;@Mapper
public interface CommentMapper {List<Comment> selectCommentsByEntity(int entityType, int entityId, int offset, int limit);int selectCountByEntity(int entityType, int entityId);}

在 resources 资源文件下 mapper 包下创建 discusspost-mapper.xml 写实现方法 :

  • 定义查询字段
  • 实现上述两个方法的语句
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.dao.CommentMapper"><!--定义查询字段--><sql id="selectFields">id, user_id, entity_type, entity_id, target_id, content, status, create_time</sql><select id="selectCommentsByEntity" resultType="Comment">select <include refid="selectFields"></include>from commentwhere status = 0and entity_type = #{entityType}and entity_id = #{entityId}order by create_time asclimit #{offset}, #{limit}</select><select id="selectCountByEntity" resultType="int">select count(id)from commentwhere status = 0and entity_type = #{entityType}and entity_id = #{entityId}</select></mapper>

1.2 业务层

在 service 包下新建业务组件 CommentService 类:

  • 注入 CommentMapper
  • 提供两个业务方法
  • 1.查询某一页数据,返回集合:实体类型、类型目标、分页、每一页数量
  • 2.一共有多少数据
package com.example.demo.service;import com.example.demo.dao.CommentMapper;
import com.example.demo.entity.Comment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class CommentService {@Autowiredprivate CommentMapper commentMapper;public List<Comment> findCommentsByEntity(int entityType, int entityId, int offset, int limit) {return commentMapper.selectCommentsByEntity(entityType, entityId, offset, limit);}public int findCommentCount(int entityType, int entityId) {return commentMapper.selectCountByEntity(entityType, entityId);}}

1.3 表现层

在 controller 包下的 DiscussPostController 类( 查询帖子详情数据的方法)中 查询请求方法 补充:

  • 注入 CommentService
  • 查询不单是查询帖子数据,还要查询评论(支持分页,需要传入分页相关信息的 Page)
  • 补充评论分页信息:显示分页条数、显示路径、总的数据
  • 分页查询,调用 commentService,首先查询帖子数据(帖子实体类型、id、分页条件)得到一个集合(得到当前帖子的所有评论)
  • 将帖子实体类型写到 常量接口中(util 包下的 CommunityConstant 类中)
    /*** 实体类型: 帖子*/int ENTITY_TYPE_POST = 1;/*** 实体类型: 评论*/int ENTITY_TYPE_COMMENT = 2;
  • 此时 DiscussPostService 类中实现常量接口(implements CommunityConstant)

  • 补充帖子内容(将评论id、tardet_id 等信息转化为 User 对象得到 UserName,头像等内容):创建一个集合,对展示的数据进行统一封装
  • VoList——显示对象
  • 判断集合,如果集合非空,遍历集合,每次遍历得到一个评论,创建一个 Map,用来封装呈现给页面数据(也就是一个评论,将遍历的评论存入、将评论的作者存入),上述是关于帖子的评论
  • 但是评论也有评论,也就是回复:遍历的同时也要将 “回复列表” 查询到返回给页面(从评论中查找评论,目标是评论的评论)
  • 同理回复列表也需要创建一个集合对数据封装,然后对这个集合进行判断
  • 每次遍历得到一个回复,创建一个 Map,用来封装呈现给页面数据(也就是一个回复,将遍历的回复存入、将回复的作者存入) 
  • 评论是没有回复目标的,但是评论的评论也就是回复,才会有回复目标(给那个帖子回复),所以给回复添加回复目标
  • 最后将回复 Map 装入集合中
  • 跳到 “回复” 外的循环,将回复集合装入评论map中
  • 还要补充回复数量,存入评论中
  • 将评论装入评论集合中
  • 整个循环外,将最终结果放入 Model 中
    @Autowiredprivate CommentService commentService;、//查询请求方法@RequestMapping(path = "/detail/{discussPostId}", method = RequestMethod.GET)public String getDiscussPost(@PathVariable("discussPostId") int discussPostId, Model model, Page page) {// 帖子DiscussPost post = discussPostService.findDiscussPostById(discussPostId);model.addAttribute("post", post);//第一种方法:在查询的时候使用关联查询 。优点:查询快;缺点:可能存在冗余、耦合//第二种方法:先查出帖子数据,根据 id 调用 Userservice 查询 User,再通过 Model 将 User 发送给 模板,// 这样模板得到了帖子,也得到了模板。优点:查询两次,没有冗余;缺点:查询慢//在这里使用第二种情况,查询慢可以使用 Redis 来优化// 作者User user = userService.findUserById(post.getUserId());// 把作者传给模板model.addAttribute("user", user);//评论分页信息page.setLimit(5);//每页5个评论page.setPath("/discuss/detail/" + discussPostId);//访问路径page.setRows(post.getCommentCount());//总数// 评论: 给帖子的评论// 回复: 给评论的评论// 评论列表——发布帖子的评论列表//分页查询,调用 commentService,首先查询帖子数据(帖子实体类型、id、分页条件)得到一个集合(得到当前帖子的所有评论)List<Comment> commentList = commentService.findCommentsByEntity(ENTITY_TYPE_POST, post.getId(), page.getOffset(), page.getLimit());//评论VO列表——创建一个集合,对展示的数据进行统一封装List<Map<String, Object>> commentVoList = new ArrayList<>();//判断集合,如果集合非空,遍历集合,每次遍历得到一个评论if (commentList != null) {for (Comment comment : commentList) {// 评论VO:创建一个 Map,用来封装呈现给页面数据(也就是一个评论,将遍历的评论存入、将评论的作者存入)Map<String, Object> commentVo = new HashMap<>();// 评论存入commentVo.put("comment", comment);// 作者存入commentVo.put("user", userService.findUserById(comment.getUserId()));//但是评论也有评论,也就是回复:遍历的同时也要将 “回复列表” 查询到返回给页面(从评论中查找评论,目标是评论的评论)//回复列表List<Comment> replyList = commentService.findCommentsByEntity(ENTITY_TYPE_COMMENT, comment.getId(),0, Integer.MAX_VALUE);//回复Vo列表:创建一个集合对数据封装List<Map<String, Object>> replyVoList = new ArrayList<>();//每次遍历得到一个回复,创建一个 Map,用来封装呈现给页面数据(也就是一个回复,将遍历的回复存入、将回复的作者存入)if (replyList != null) {for (Comment reply: replyList) {Map<String, Object> replyVo = new HashMap<>();// 回复replyVo.put("reply", reply);// 作者replyVo.put("user", userService.findUserById(reply.getUserId()));//评论是没有回复目标的,但是评论的评论也就是回复,才会有回复目标(给那个帖子回复),所以给回复添加回复目标// 回复目标User target = reply.getTargetId() == 0 ? null : userService.findUserById(reply.getTargetId());replyVo.put("target", target);//最后将回复 Map 装入集合中replyVoList.add(replyVo);}}//将回复集合装入评论map中commentVo.put("replys", replyVoList);// 回复数量int replyCount = commentService.findCommentCount(ENTITY_TYPE_COMMENT, comment.getId());//存入评论中commentVo.put("replyCount", replyCount);//将评论装入评论集合中commentVoList.add(commentVo);}}//将最终结果放入 Model 中model.addAttribute("comments", commentVoList);return "/site/discuss-detail";}

2.添加评论

  • 数据层:增加评论数量、修改帖子的评论数量
  • 业务层:处理添加评论的业务、先增加评论、再更新帖子的评论数量
  • 表现层:处理添加评论数量的请求、设置添加评论的表单

2.1 数据层

在 dao 包下的 CommentMapper 中新增 添加评论 的方法:

    //添加评论int insertComment(Comment comment);

在 配置文件 comment-mapper.xml 中实现 sql:

  • 列出新增字段
  • 添加 insert 标签
    <!--添加评论查询字段--><sql id="insertFields">user_id, entity_type, entity_id, target_id, content, status, create_time</sql><!--添加评论sql--><insert id="insertComment" parameterType="Comment">insert into comment(<include refid="insertFields"></include>)values(#{userId},#{entityType},#{entityId},#{targetId},#{content},#{status},#{createTime})</insert>

增加评论之后更新帖子数量,在 DiscussPostMapper.java 中新增方法

  • 根据 id 更新帖子数量
    //更新帖子数量int updateCommentCount(int id, int commentCount);

打开接口的配置文件 discusspost-mapper.xml 实现 sql: 

    <!--更新帖子数量--><update id="updateCommentCount">update discuss_post set comment_count = #{commentCount} where id = #{id}</update>

2.2 业务层

在 service 包下的 DiscussPostService(帖子业务组件)中增加更新评论数量:

    //更新评论数量public int updateCommentCount(int id, int commentCount) {return discussPostMapper.updateCommentCount(id, commentCount);}

在 CommentService(显示评论的业务方法) 中处理增加评论业务:

  • 增加评论返回 int,参数为实体 Comment
  • 添加注解 @Transactional (声明隔离级别、传播机制):因为在增加评论方法中有两次 DMA 操作,进行事务管理,要么一起成功,要么一起失败
  • 增加评论的时候,需要过滤内容(标签、敏感词等),注入 SensitiveFilter(敏感词)
  • 调用 增加评论的方法
  • 在更新帖子评论数量:判断实体类型是否是帖子,实现 CommunityConstant 接口,在查找评论数量;最后更新到帖子表中(根据帖子 id更新),需要注入 DiscussPostService
    @Autowiredprivate SensitiveFilter sensitiveFilter;@Autowiredprivate DiscussPostService discussPostService;//增加评论的方法@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)public int addComment(Comment comment) {if (comment == null) {throw new IllegalArgumentException("参数不能为空");}//添加评论:过滤标签和敏感词comment.setContent(HtmlUtils.htmlEscape(comment.getContent()));comment.setContent(sensitiveFilter.filter(comment.getContent()));int rows = commentMapper.insertComment(comment);//更新帖子评论数量//判断实体类型是否是帖子,实现 CommunityConstant 接口,在查找评论数量;//最后更新到帖子表中(根据帖子 id更新),需要注入 DiscussPostServiceif (comment.getEntityType() == ENTITY_TYPE_POST) {int count = commentMapper.selectCountByEntity(comment.getEntityType(), comment.getEntityId());discussPostService.updateCommentCount(comment.getEntityId(), count);}return rows;}

2.3 表现层

在 controller 包下新建 CommentController (处理增加评论的请求)类

  • 声明 controller 访问路径
  • 增加请求路径(添加帖子 id 路径),增加是POST 请求
  • 通过 @PathVariable 得到帖子 id 参数,(传入提交内容、id、评论类型,声明实体类 Comment)
  • 注入 CommentService,HostHolder(增加评论为当前用户增加);
  • 补充实体类:UserId、状态、当前时间
  • 添加评论
  • 最终重定向帖子详情页
package com.example.demo.controller;import com.example.demo.entity.Comment;
import com.example.demo.service.CommentService;
import com.example.demo.util.HostHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;import java.util.Date;/*** 处理增加评论的请求*/
@Controller
@RequestMapping("/comment")
public class CommentController {@Autowiredprivate CommentService commentService;@Autowiredprivate HostHolder hostHolder;@RequestMapping(path = "/add/{discussPostId}", method = RequestMethod.POST)//通过 @PathVariable 得到帖子 id 参数,(传入提交内容、id、评论类型,声明实体类 Comment)public String addComment(@PathVariable("discussPostId") int discussPostId, Comment comment) {comment.setUserId(hostHolder.getUser().getId());comment.setStatus(0);comment.setCreateTime(new Date());commentService.addComment(comment);return "redirect:/discuss/detail/" + discussPostId;}
}

前端页面 discuss-detail.html 中的回帖:

<!-- 回帖 --><div class="container mt-3"><!-- 回帖数量 --><div class="row"><div class="col-8"><h6><b class="square"></b> <i th:text="${post.commentCount}">30</i>条回帖</h6></div><div class="col-4 text-right"><a href="#replyform" class="btn btn-primary btn-sm">&nbsp;&nbsp;回&nbsp;&nbsp;帖&nbsp;&nbsp;</a></div></div><!-- 回帖列表 --><ul class="list-unstyled mt-4"><li class="media pb-3 pt-3 mb-3 border-bottom" th:each="cvo:${comments}"><a href="profile.html"><img th:src="${cvo.user.headerUrl}" class="align-self-start mr-4 rounded-circle user-header" alt="用户头像" ></a><div class="media-body"><div class="mt-0"><span class="font-size-12 text-success" th:utext="${cvo.user.username}">掉脑袋切切</span><span class="badge badge-secondary float-right floor"><i th:text="${page.offset + cvoStat.count}">1</i>#</span></div><div class="mt-2" th:utext="${cvo.comment.content}">这开课时间是不是有点晚啊。。。</div><div class="mt-4 text-muted font-size-12"><span>发布于 <b th:text="${#dates.format(cvo.comment.createTime,'yyyy-MM-dd HH:mm:ss')}">2019-04-15 15:32:18</b></span><ul class="d-inline float-right"><li class="d-inline ml-2"><a href="#" class="text-primary">赞(1)</a></li><li class="d-inline ml-2">|</li><li class="d-inline ml-2"><a href="#" class="text-primary">回复(<i th:text="${cvo.replyCount}">2</i>)</a></li></ul></div><!-- 回复列表 --><ul class="list-unstyled mt-4 bg-gray p-3 font-size-12 text-muted"><li class="pb-3 pt-3 mb-3 border-bottom" th:each="rvo:${cvo.replys}"><div><span th:if="${rvo.target==null}"><b class="text-info" th:text="${rvo.user.username}">寒江雪</b>:&nbsp;&nbsp;</span><span th:if="${rvo.target!=null}"><i class="text-info" th:text="${rvo.user.username}">Sissi</i> 回复<b class="text-info" th:text="${rvo.target.username}">寒江雪</b>:&nbsp;&nbsp;</span><span th:utext="${rvo.reply.content}">这个是直播时间哈,觉得晚的话可以直接看之前的完整录播的~</span></div><div class="mt-3"><span th:text="${#dates.format(rvo.reply.createTime,'yyyy-MM-dd HH:mm:ss')}">2019-04-15 15:32:18</span><ul class="d-inline float-right"><li class="d-inline ml-2"><a href="#" class="text-primary">赞(1)</a></li><li class="d-inline ml-2">|</li><li class="d-inline ml-2"><a th:href="|#huifu-${rvoStat.count}|" data-toggle="collapse" class="text-primary">回复</a></li></ul><div th:id="|huifu-${rvoStat.count}|" class="mt-4 collapse"><form method="post" th:action="@{|/comment/add/${post.id}|}"><div><input type="text" class="input-size" name="content" th:placeholder="|回复${rvo.user.username}|"/><input type="hidden" name="entityType" value="2"><input type="hidden" name="entityId" th:value="${cvo.comment.id}"><input type="hidden" name="targetId" th:value="${rvo.user.id}"></div><div class="text-right mt-2"><button type="submit" class="btn btn-primary btn-sm" onclick="#">&nbsp;&nbsp;回&nbsp;&nbsp;复&nbsp;&nbsp;</button></div></form></div></div>								</li><!-- 回复输入框 --><li class="pb-3 pt-3"><form method="post" th:action="@{|/comment/add/${post.id}|}"><div><input type="text" class="input-size" name="content" placeholder="请输入你的观点"/><input type="hidden" name="entityType" value="2"><input type="hidden" name="entityId" th:value="${cvo.comment.id}"></div><div class="text-right mt-2"><button type="submit" class="btn btn-primary btn-sm" onclick="#">&nbsp;&nbsp;回&nbsp;&nbsp;复&nbsp;&nbsp;</button></div></form></li></ul></div></li></ul><!-- 分页 --><nav class="mt-5" th:replace="index::pagination"><ul class="pagination justify-content-center"><li class="page-item"><a class="page-link" href="#">首页</a></li><li class="page-item disabled"><a class="page-link" href="#">上一页</a></li><li class="page-item active"><a class="page-link" href="#">1</a></li><li class="page-item"><a class="page-link" href="#">2</a></li><li class="page-item"><a class="page-link" href="#">3</a></li><li class="page-item"><a class="page-link" href="#">4</a></li><li class="page-item"><a class="page-link" href="#">5</a></li><li class="page-item"><a class="page-link" href="#">下一页</a></li><li class="page-item"><a class="page-link" href="#">末页</a></li></ul></nav>			</div><!-- 回帖输入 --><div class="container mt-3"><form class="replyform" method="post" th:action="@{|/comment/add/${post.id}|}"><p class="mt-3"><a name="replyform"></a><textarea placeholder="在这里畅所欲言你的看法吧!" name="content"></textarea><input type="hidden" name="entityType" value="1"><input type="hidden" name="entityId" th:value="${post.id}"></p><p class="text-right"><button type="submit" class="btn btn-primary btn-sm">&nbsp;&nbsp;回&nbsp;&nbsp;帖&nbsp;&nbsp;</button></p></form></div></div>

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

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

相关文章

DV、OV、EV证书

在保护您的网站并建立用户信任时&#xff0c;SSL证书起着关键作用。不同的SSL认证级别提供了不同的安全性和验证程度。在选择SSL证书时&#xff0c;了解DV&#xff08;域名验证&#xff09;、OV&#xff08;组织验证&#xff09;和EV&#xff08;扩展验证&#xff09;证书的差异…

<Linux>(极简关键、省时省力)《Linux操作系统原理分析之存储管理(3)》(16)

《Linux操作系统原理分析之存储管理&#xff08;3&#xff09;》&#xff08;16&#xff09; 5 存储管理5.6 分段存储管理&#xff08;1&#xff09; 地址结构&#xff08;2&#xff09; 段表&#xff08;3&#xff09; 地址变换机构&#xff08;4&#xff09; 存储共享&#x…

【JMeter】菜单栏介绍

【菜单栏】 1. Tools 导入curl接口信息 作用&#xff1a;快速导入接口信息&#xff0c;响应头和缓存信息等 Log level临时修改日志等级 作用&#xff1a; 从勾选的level开始往更高等级level抓取log日志等级优先级&#xff1a; ALL < TRACE < DEBUG <INFO<WA…

RT_Thread_msh_系统msh命令、使用msh时过滤ulog日志、添加msh命令(不带/带参)

1、msh配置 msh功能是自动开启的&#xff0c;配置如下&#xff0c;可以在“RT-Thread Settings”里去修改。 调试过程中遇到msh不能使用&#xff0c;理解msh也是一个线程&#xff0c;有自己的优先级20&#xff0c;高优先级的线程&#xff08;比如main是10&#xff09;如果一直…

软件测试 —— 冒烟测试(Smoke Test,ST)

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

Android帝国之进程杀手--lmkd

本文概要 这是Android系统启动的第三篇文章&#xff0c;本文以自述的方式来讲解lmkd进程&#xff0c;通过本文您将了解到lmkd进程在安卓系统中存在的意义&#xff0c;以及它是如何杀进程的。&#xff08;文中的代码是基于android13&#xff09; 我是谁 init&#xff1a;“大…

SpringCloudAlibaba微服务 【实用篇】| Nacos配置管理

目录 一&#xff1a;Nacos配置管理 1. 统一配置管理 2. 配置热更新 3. 配置共享 4. 搭建Nacos集群 tips&#xff1a;前些天突然发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff0c;感兴趣的同学可以进…

Zemax光学设计——单透镜设计

单透镜系统参数&#xff1a; 入瞳直径&#xff1a;20mm F/#&#xff08;F数&#xff09;&#xff1a;10 全视场&#xff1a;10 波长&#xff1a;587nm 材料&#xff1a;BK7 优化方向&#xff1a;最佳均方根光斑直径 设计步骤 一、单透镜系统参数 步骤一&#xff1a;入…

【Spring系列】DeferredResult异步处理

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

PDF文件如何限制打印?限制打印清晰度?

想要限制PDF文件的打印功能&#xff0c;想要限制PDF文件打印清晰度&#xff0c;都可以通过设置限制编辑来达到目的。 打开PDF编辑器&#xff0c;找到设置限制编辑的界面&#xff0c;切换到加密状态&#xff0c;然后我们就看到 有印刷许可。勾选【权限密码】输入一个PDF密码&am…

vue3随机生成8位字母+数字

// 随机生成8位字母数字 export const autoPassword: any () > {// console.log("自动生成");//可获取的字符串const chars ABCDEFGHIJKLMNOPQRSTUVWSYZabcdefghijklmnopqrstuvwsyz0123456789;const list [];//通过随机获取八个字符串的索引下标for (let i 0;…

IBM ServeRAID M1015阵列卡 支持RAID5,需要配件

最近一台IBM x3400m3的旧服务器&#xff0c;折腾一下&#xff0c;要添置硬盘&#xff0c;重做RAID&#xff0c;阵列卡是ServeRAID M1015&#xff0c;默认进去WebBIOS&#xff0c;只有RAID0和RAID1&#xff0c;没有RAID5&#xff0c;参考官方原版的手册&#xff0c;如下图&#…

R语言30分钟入门

1. 环境&安装 R是支持win、linux合macos的 完整参考&#xff1a;https://zhuanlan.zhihu.com/p/596324321?utm_id0 主要是安装&#xff1a;1、R环境&#xff1b;2、rstudio开发环境&#xff08;后面主要是用rstudio&#xff0c;也可以用vscode&#xff09; 1.1. rstud…

绘制折扇-第11届蓝桥杯选拔赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第11讲。 绘制折扇&#xf…

Docker本地部署Firefox火狐浏览器并远程访问

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《Linux》《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;…

分割掩模 VS 掩膜

掩膜 Mask分割掩模 Segmentation Mask总结示例 掩膜 Mask “掩膜” 是指一种用于 标识或遮蔽图像中特定区域 的 图像。 在图像处理中&#xff0c;掩膜通常是一个 二值图像&#xff0c;其中的 像素值为 0 或 1。binary Mask 叫做二元掩膜&#xff0c;如下图所示&#xff1a; 这…

transformer模型和Multi-Head Attention

参考英文文献&#xff1a; Understanding and Coding the Self-Attention Mechanism of Large Language Models From Scratch https://www.tensorflow.org/text/tutorials/transformer 解读参考链接&#xff1a;Understanding and Coding the Self-Attention Mechanism of Lar…

Python面试破解:return和yield的细腻差别

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;我是涛哥&#xff0c;今天为大家分享 Python面试破解&#xff1a;return和yield的细腻差别&#xff0c;全文3000字&#xff0c;阅读大约10钟。 在Python的函数编程中&#xff0c;return和yield是两个常用的关键词…

springboot实现邮箱发送功能

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 邮箱效果图一、pom配置二、页面编写三、配置yml四、邮件工具类五、测试发送 邮箱效果图 1.可以利用在出现问题进行邮箱提醒 2.编写html 用于在邮箱中展示的样式 提示…

数据结构-04-队列

1-队列的结构和特点 生活中我们排队买票&#xff0c;先来的先买&#xff0c;后来的人只能站末尾&#xff0c;不允许插队。先进者先出&#xff0c;这就是典型的"队列"。队列跟栈非常相似&#xff0c;支持的操作也很有限&#xff0c;最基本的操作也是两个&#xff1a;入…