基于Springboot+Vue的在线答题闯关系统
基于Springboot+Vue的在线答题闯关系统
前言:随着在线教育的快速发展,传统的教育模式逐渐向互联网+教育模式转型。在线答题系统作为其中的一个重要组成部分,能够帮助用户通过互动式的学习方式提升知识掌握度。本文基于Spring Boot和Vue.js框架,设计并实现了一个在线答题闯关系统,旨在为用户提供顺序出题、随机出题、错题本、收藏题目、答题统计等多种功能,以增强用户的学习体验。
目录
- 前言
- 项目功能及技术
- 用户端
- 管理端
- API
- SpringBoot框架搭建
- 实体映射创建Mapper
- 接口封装
- 整合Swagger
- 常用字段类型
- 参考代码块
前言
本系统采用前后端分离架构,前端使用Vue.js框架实现,后端则通过Spring Boot进行构建,数据存储使用MySQL数据库。前端使用Vue.js进行数据渲染,而后端提供RESTful API接口来实现前后端的有效数据交互。
项目功能及技术
功能模块设计
-
顺序出题模块:该模块允许用户按顺序答题,系统根据预设的题目顺序逐一展示给用户。用户完成每一道题后可以进入下一题,适合需要系统化学习的用户。
-
体型练习模块:用户可以根据自己的需求选择特定的练习模式,比如选择某个类别或某个难度的题目进行练习。该模块支持用户自定义练习内容,帮助用户强化薄弱的知识点。
-
随机出题模块:系统可以随机从题库中抽取题目,进行答题闯关,用户在有限的时间内答题,提升学习的趣味性和挑战性。
-
错题本模块:该模块记录用户做错的题目,用户可以随时查看并重新进行练习,帮助用户集中攻克自己的薄弱环节,提升记忆与掌握度。
-
我的收藏模块:用户可以将自己喜欢或难度较高的题目收藏到个人收藏夹,方便以后再次复习或挑战。
-
答题统计模块:系统自动统计用户的答题情况,包括正确率、答题速度、错题数量等,帮助用户了解自己的学习进度和成效,并能根据数据调整学习策略。
技术:
-
Spring Boot:后端框架,利用Spring Boot的快速开发特性。同时,通过Mybatis简化数据库操作,提高数据访问效率。
-
Vue.js:前端框架,使用Vuex进行全局状态管理,提升数据的一致性与可维护性。
-
MySQL:数据库存储引擎,负责存储题目数据、用户答题记录、错题与收藏等信息。
-
Layui:前端UI组件库,用于搭建美观且响应式的用户界面,提升用户交互体验。
用户端





管理端



API
SpringBoot框架搭建
1.创建maven project,先创建一个名为SpringBootDemo的项目,选择【New Project】
然后在弹出的下图窗口中,选择左侧菜单的【New Project】
在project下创建module,点击右键选择【new】—【Module…】
左侧选择【Spring initializr】,通过idea中集成的Spring initializr工具进行spring boot项目的快速创建。窗口右侧:name可根据自己喜好设置,group和artifact和上面一样的规则,其他选项保持默认值即可,【next】
Developer Tools模块勾选【Spring Boot DevTools】,web模块勾选【Spring Web】,此时,一个Springboot项目已经搭建完成,可开发后续功能
实体映射创建Mapper
创建一个entity实体类文件夹,并在该文件夹下创建项目用到的实体类
package com.example.demo.entity;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;@Data
public class User {@TableId(type = IdType.AUTO)private Long id;private String account;private String pwd;private String userDesc;private String userHead;private LocalDateTime createTime;private Long role;private String nickname;private String email;private String tags;
}
接口封装
由于我们使用mybatis-plus,所以简单的增删改查不用自己写,框架自带了,只需要实现或者继承他的Mapper、Service
创建控制器Controller
整合Swagger
添加依赖
先导入spring boot的web包
<!--swagger依赖-->
<dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version>
</dependency>
<dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.9.2</version>
</dependency>
配置Swagger
创建一个swagger的配置类,命名为SwaggerConfig.java
/**用于定义API主界面的信息,比如可以声明所有的API的总标题、描述、版本*/private ApiInfo apiDemo() {return new ApiInfoBuilder()//用来自定义API的标题.title("SpringBoot项目SwaggerAPIAPI标题测试")//用来描述整体的API.description("SpringBoot项目SwaggerAPI描述测试")//创建人信息.contact(new Contact("测试员张三","http://localhost:8080/springboot/swagger-ui.html","xxxxxxxx@163.com"))//用于定义服务的域名//.termsOfServiceUrl("").version("1.0") //可以用来定义版本.build();}
接口测试
运行Spring Boot项目,默认端口8080,通过地址栏访问url
接口组定义
根据不同的业务区分不同的接口组,使用@API来划分
@Api(tags = "用户管理") // tags:组名称
@RestController
public class RoleController {
}
接口定义
使用@ApiModel来标注实体类,同时在接口中定义入参为实体类作为参数。
-
@ApiModel:用来标类
-
常用配置项:value:实体类简称;description:实体类说明
-
@ApiModelProperty:用来描述类的字段的含义。
常用字段类型
字段类型 | 所占字节 | 存储范围 | 最大存储值 | 使用场景 |
---|---|---|---|---|
TINYINT | 1 | -128~127 | 127 | 存储小整数 |
INT | 4 | -2147483648~2147483647 | 2147483647 | 存储大整数 |
BIGINT | 8 | -9223372036854775808~9223372036854775807 | 9223372036854775807 | 存储极大整数 |
DECIMAL | 可变长度 | 存储精度要求高的数值 | ||
CHAR | 固定长度 | 最多255字节 | 255个字符 | 存储长度固定的字符串 |
VARCHAR | 可变长度 | 最多65535字节 | 65535个字符 | 存储长度不固定的字符串 |
DATETIME | 8 | ‘1000-01-01 00:00:00’~‘9999-12-31 23:59:59’ | ‘9999-12-31 23:59:59’ | 存储日期和时间 |
参考代码块
<body style="background-color: #f7f7f7;"><div class="headerBox"><div class="logoBox"><img src="img/logo1.png" /><div class="logoTitle">在线答题闯关</div></div><div class="menuBox"><div class="menuItem activeMenu "><a href="index.html">练习模式</a></div><div class="menuItem blackColor"><a href="challengeLevels.html?param=primary">闯关模式</a></div><div class="menuItem blackColor"><a href="wrongQuestion.html">我的错题</a></div><div class="menuItem blackColor"><a href="myCollection.html">我的收藏</a></div><div class="menuItem blackColor"><a href="statistics.html">答题统计</a></div><div class="menuItem blackColor"><a href="center.html">个人中心</a></div><div class="menuItem blackColor"><a href="./login/login.html">退出登录</a></div></div></div><div class="container-fluid" id="content-page"><div class="row"><div class="col-md-2"> </div><div class="col-md-8"><div class="searchBox"><div class="leftTitle">{{pageTitle}}</div></div></div><div class="col-md-2"> </div></div><div class="row"><div class="col-md-2"> </div><div class="col-md-8"><div v-for="(item,index) in questionList"><div class="radioItemBox" v-if="item.questionType == '单选题'"><div class="BtnBox radioItem"><div>{{index+1}}.</div><textarea rows="18" cols="90" v-model="item.title" disabled></textarea><img src="img/collecQues.png" class="radioItemTypeImg"v-on:click="collection(item.id)" /></div><div class="BtnBox radioLineV2" v-if="item.checkA!=''"><div class="radioIconBox"><input type="radio" class="radioInputCheck" :name="index"v-on:change="checkOne(index,'A')" /></div><div>A.</div><input v-model="item.checkA" disabled class="radioLineV2Input" /></div><div class="BtnBox radioLineV2" v-if="item.checkB!=''"><div class="radioIconBox"><input type="radio" class="radioInputCheck" :name="index"v-on:change="checkOne(index,'B')" /></div><div>B.</div><input v-model="item.checkB" disabled class="radioLineV2Input" /></div><div class="BtnBox radioLineV2" v-if="item.checkC!=''"><div class="radioIconBox"><input type="radio" class="radioInputCheck" :name="index"v-on:change="checkOne(index,'C')" /></div><div>C.</div><input v-model="item.checkC" disabled class="radioLineV2Input" /></div><div class="BtnBox radioLineV2" v-if="item.checkD!=''"><div class="radioIconBox"><input type="radio" class="radioInputCheck" :name="index"v-on:change="checkOne(index,'D')" /></div><div>D.</div><input v-model="item.checkD" disabled class="radioLineV2Input" /></div><div class="BtnBox radioLineV2" v-if="item.checkE!=''"><div class="radioIconBox"><input type="radio" class="radioInputCheck" :name="index"v-on:change="checkOne(index,'E')" /></div><div>E.</div><input v-model="item.checkE" disabled class="radioLineV2Input" /></div></div><div class="radioItemBox" v-if="item.questionType == '多选题'"><div class="BtnBox radioItem"><div>{{index+1}}.</div><textarea rows="18" cols="90" v-model="item.title" disabled></textarea><img src="img/collecQues.png" class="radioItemTypeImg"v-on:click="collection(item.id)" /></div><div class="BtnBox radioLineV2" v-if="item.checkA!=''"><div class="radioIconBox"><input type="checkbox" class="radioInputCheck" :name="index"v-on:change="checkTwo($event,index,'A')" /></div><div>A.</div><input v-model="item.checkA" disabled class="radioLineV2Input" /></div><div class="BtnBox radioLineV2" v-if="item.checkB!=''"><div class="radioIconBox"><input type="checkbox" class="radioInputCheck" :name="index"v-on:change="checkTwo($event,index,'B')" /></div><div>B.</div><input v-model="item.checkB" disabled class="radioLineV2Input" /></div><div class="BtnBox radioLineV2" v-if="item.checkC!=''"><div class="radioIconBox"><input type="checkbox" class="radioInputCheck" :name="index"v-on:change="checkTwo($event,index,'C')" /></div><div>C.</div><input v-model="item.checkC" disabled class="radioLineV2Input" /></div><div class="BtnBox radioLineV2" v-if="item.checkD!=''"><div class="radioIconBox"><input type="checkbox" class="radioInputCheck" :name="index"v-on:change="checkTwo($event,index,'D')" /></div><div>D.</div><input v-model="item.checkD" disabled class="radioLineV2Input" /></div><div class="BtnBox radioLineV2" v-if="item.checkE!=''"><div class="radioIconBox"><input type="checkbox" class="radioInputCheck" :name="index"v-on:change="checkTwo($event,index,'E')" /></div><div>E.</div><input v-model="item.checkE" disabled class="radioLineV2Input" /></div></div><div class="radioItemBox" v-if="item.questionType == '判断题'"><div class="BtnBox radioItem"><div>{{index+1}}.</div><textarea rows="18" cols="90" v-model="item.title" disabled></textarea><img src="img/collecQues.png" class="radioItemTypeImg"v-on:click="collection(item.id)" /></div><div class="BtnBox radioLineV2" v-if="item.checkA!=''"><div class="radioIconBox"><input type="radio" class="radioInputCheck" :name="index"v-on:change="checkOne(index,'A')" /></div><div>A.</div><input v-model="item.checkA" disabled class="radioLineV2Input" /></div><div class="BtnBox radioLineV2" v-if="item.checkB!=''"><div class="radioIconBox"><input type="radio" class="radioInputCheck" :name="index"v-on:change="checkOne(index,'B')" /></div><div>B.</div><input v-model="item.checkB" disabled class="radioLineV2Input" /></div></div></div><div class="BtnBox margin-sm"><div class="AddQuesBtnItem" v-on:click="SaveChange"><img src="img/submit.png" />提交</div><div style="height:100px;"></div></div></div><div class="col-md-2"> </div></div></div><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/vue.js"></script><script type="text/javascript" src="login/layui/layui.js"></script><script>//轻量级框架var dataInfo = new Vue({el: "#content-page",//Vue的数据对象data: {questionList: [],pageTitle: ''}, //数据对象结束//方法methods: {GetAll: function() {let vm = this;let param = GetQueryString("param");let type = GetQueryString("type");let quesType = '';if (param == 'practice') {if (type == '0') {quesType = '单选题';} else if (type == '1') {quesType = '多选题';} else {quesType = '判断题';}vm.pageTitle = '练习模式:' + quesType;} else if (param == 'order') {vm.pageTitle = '顺序出题';} else {vm.pageTitle = '随机练习';}var user = JSON.parse(sessionStorage.getItem('user'));$.ajax({url: "http://127.0.0.1:8081/common/answer-list?userId=" + user.id + "¶m=" +param + "&type=" + quesType,async: false,type: "POST",contentType: 'application/json',dataType: 'json',success: function(json) {vm.questionList = json.list}});},//单选框选择事件checkOne(index, check) {let vm = this;vm.questionList[index].isChecked = check;},//多选框选择事件checkTwo(event, index, check) {let vm = this;const checked = event.target.checked;let info = vm.questionList[index];let checkedArray = info.isChecked.split(',');if (checkedArray[0] == '') {checkedArray.splice(0, 1);}if (checked) {checkedArray.push(check);info.isChecked = checkedArray.join(',');} else {let ind = checkedArray.indexOf(check);if (ind !== -1) {checkedArray.splice(ind, 1);}info.isChecked = checkedArray.join(',');}},//点击提交SaveChange() {let vm = this;//得分let number = 0;let list = vm.questionList;for (let i = 0; i < list.length; i++) {if (list[i].isChecked != '') {let right = list[i].rightKey.split(',');let check = list[i].isChecked.split(',');if (right.length === check.length && right.sort().toString() === check.sort().toString()) {list[i].correct = 1;number++;}}}var user = JSON.parse(sessionStorage.getItem('user'));var vo = {};vo.answerList = list;vo.number = number;vo.userId = user.id;vo.type = '练习';$.ajax({url: "http://127.0.0.1:8081/common/get-answer",async: false,type: "POST",contentType: 'application/json',dataType: 'json',data: JSON.stringify(vo),success: function(json) {layui.use('layer', function() {var layer = layui.layer;// 弹出提示框layer.msg('您的分数为:' + number + '分', {icon: 6, // 图标样式,默认为信息图标time: 2000, // 显示时间,默认为2秒shade: 0.5, // 遮罩层透明度,默认为0.3shadeClose: true // 是否点击遮罩关闭弹框,默认为true});});}});},//点击收藏collection(id) {var vo = {};var user = JSON.parse(sessionStorage.getItem('user'));vo.userId = user.id;vo.answerId = id;$.ajax({url: "http://127.0.0.1:8081/common/addCollect",async: false,type: "POST",contentType: 'application/json',dataType: 'json',data: JSON.stringify(vo),success: function(json) {layui.use('layer', function() {var layer = layui.layer;// 弹出提示框layer.msg(json.returnMsg, {icon: json.returnMsg == '您已收藏过' ? 5 :6, // 图标样式,默认为信息图标time: 2000, // 显示时间,默认为2秒shade: 0.5, // 遮罩层透明度,默认为0.3shadeClose: true // 是否点击遮罩关闭弹框,默认为true});});}});},}, //方法结束created: function() {var vm = this;vm.GetAll();}, //初始加载方法结束}); //vue结束function GetQueryString(name) {var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");var r = window.location.search.substr(1).match(reg);if (r != null) return unescape(r[2]);return null;}</script></body>
</html>
<head><meta charset="utf-8" /><title>答题统计</title></head><link href="css/index.css" rel="stylesheet" /><link href="css/bootstrap.min.css" rel="stylesheet" /><body style="background-color: #f7f7f7;"><div class="headerBox"><div class="logoBox"><img src="img/logo1.png" /><div class="logoTitle">在线答题闯关</div></div><div class="menuBox"><div class="menuItem blackColor"><a href="index.html">练习模式</a></div><div class="menuItem blackColor"><a href="challengeLevels.html?param=primary">闯关模式</a></div><div class="menuItem blackColor"><a href="wrongQuestion.html">我的错题</a></div><div class="menuItem blackColor"><a href="myCollection.html">我的收藏</a></div><div class="menuItem activeMenu"><a href="statistics.html">答题统计</a></div><div class="menuItem blackColor"><a href="center.html">个人中心</a></div><div class="menuItem blackColor"><a href="./login/login.html">退出登录</a></div></div></div><div class="container-fluid" id="content-page"><div class="row"><div class="col-md-2"> </div><div class="col-md-8"><div class="searchBox"><div class="leftTitle">答题统计</div><div></div></div></div><div class="col-md-2"> </div></div><div class="row"><div class="col-md-2"> </div><div class="col-md-4"><div id="main"></div></div><div class="col-md-4"><div id="main2"></div></div><div class="col-md-2"> </div></div></div><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/echarts.min.js"></script><script>function GetQueryString(name) {var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");var r = window.location.search.substr(1).match(reg);if (r != null) return unescape(r[2]);return null;}var user = JSON.parse(sessionStorage.getItem('user'));$.ajax({url: "http://127.0.0.1:8081/common/total?userId=" + user.id,async: false,type: "POST",contentType: 'application/json',dataType: 'json',data: JSON.stringify({}),success: function(json) {initCharts1(json.data);var inputArray = json.data;// 定义对应的题目类型名称数组var typeNameArray = ['单选题', '多选题', '判断题'];// 结果数组var resultArray = [];// 遍历输入数组for (var i = 0; i < inputArray.length; i++) {// 构造对象,并添加到结果数组中var item = {value: inputArray[i],name: typeNameArray[i]};resultArray.push(item);}initCharts(resultArray);}});function initCharts(data1) {var chartDom = document.getElementById('main');var myChart = echarts.init(chartDom);var option;option = {title: {text: '答题数统计',subtext: '',left: 'center'},tooltip: {trigger: 'item'},legend: {orient: 'vertical',left: 'left'},series: [{name: 'Access From',type: 'pie',radius: '50%',data: data1,emphasis: {itemStyle: {shadowBlur: 10,shadowOffsetX: 0,shadowColor: 'rgba(0, 0, 0, 0.5)'}}}]};myChart.setOption(option);};function initCharts1(data2) {var chartDom = document.getElementById('main2');var myChart = echarts.init(chartDom);var option;option = {xAxis: {type: 'category',data: ['单选题', '多选题', '判断题']},yAxis: {type: 'value'},series: [{data: data2,type: 'bar',showBackground: true,backgroundStyle: {color: 'rgba(180, 180, 180, 0.2)'}}]};myChart.setOption(option);};</script></body>
</html>
相关文章:

基于Springboot+Vue的在线答题闯关系统
基于SpringbootVue的在线答题闯关系统 前言:随着在线教育的快速发展,传统的教育模式逐渐向互联网教育模式转型。在线答题系统作为其中的一个重要组成部分,能够帮助用户通过互动式的学习方式提升知识掌握度。本文基于Spring Boot和Vue.js框架&…...

声音克隆GPT-SoVITS
作者:吴业亮 博客:wuyeliang.blog.csdn.net 一、原理介绍 GPT-SoVITS,作为一款结合了GPT(生成预训练模型)和SoVITS(基于变分信息瓶颈技术的歌声转换)的创新工具,正在声音克隆领域掀…...

【STM32 Modbus编程】-作为主设备读取保持/输入寄存器
作为主设备读取保持/输入寄存器 文章目录 作为主设备读取保持/输入寄存器1、硬件准备与连接1.1 RS485模块介绍1.2 硬件配置与接线1.3 软件准备2、读保持寄存器2.1 主设备发送请求2.2 从设备响应请求2.3 主机接收数据3、读输入寄存器4、结果4.1 保持寄存器4.2 输入寄存器在前面的…...

前端开发入门指南Day 17:TypeScript高级类型(泛型,类型守卫,Partial<T>和 Required<T>等)
泛型:代码的"变色龙" 🦎 为什么需要泛型? 想象一个快递员,每天要处理不同类型的包裹。如果为每种类型的包裹都写一套处理程序,那会很麻烦。泛型就像是一个"通用的包裹处理系统",它能…...

flex布局容易忽略的角色作用
目录 清除浮动 作用于行内元素 flex-basis宽度 案例一: 案例二: 案例三: flex-grow设置权重 案例一: 案例二: 简写flex-grow:1 0 auto; flex作为一维布局,行和列的使用,忽略的小角色,大…...

如何开发高效的企业内训APP?教育培训系统源码搭建实战详解
本篇文章,小编将从教育培训系统的源码搭建、功能设计以及技术实现等方面,详细探讨如何开发一款高效的企业内训APP。 一、企业内训APP的需求分析 在开发企业内训APP之前,首先需要明确其基本需求。一个高效的企业内训APP应该具备以下几个核心…...

【软考网工笔记】网络基础理论——传输层
IPSec协议 Internet协议安全性是一种开放标准的框架结构,通过使用加密的安全服务以确保在Internet协议(IP)网络上进行保密而安全的通讯。 工作在OSI模型的第三层网络层上,使其在单独使用时适于保护基于TCP或UDP的协议࿰…...

如何预防服务器后台爆破攻击
服务器后台爆破(Brute Force Attack)是一种通过反复尝试用户名和密码组合,以非法获取系统访问权限的攻击方式。这种攻击不仅会消耗服务器资源,还可能导致合法用户被锁定或敏感数据泄露。为了有效预防服务器后台爆破攻击࿰…...

CMake笔记之在CMakeLists.txt文件中开启Debug模式
CMake笔记之在CMakeLists.txt文件中开启Debug模式 code review! 文章目录 CMake笔记之在CMakeLists.txt文件中开启Debug模式1.设置 CMake 的构建类型2.添加编译器的调试选项3.使用 CMAKE_CXX_STANDARD (可选)4.编译和构建5.针对多配置生成器6.最终示例 CMakeLists.txt 1.设置 …...

C++编程:模拟实现CyberRT的DataVisitor和DataDispatcher
文章目录 0. 引言1. 设计概要1.1 主要组件1.2 类关系图1.3 工作流程 2. 代码实现2.1. 定义数据结构2.2. 实现 DataVisitor2.3. 实现 DataDispatcher2.4. 实现 Receiver2.5. 实现具体的 DataVisitor2.6. 示例主程序2.7. 编译和运行 0. 引言 使用 C 实现一个类似CyberRT 架构的 …...

【Flutter】WillPopScope组件-监听物理返回键事件自定义返回事件
WillPopScope(onWillPop: () async {if ( flutterWebViewPlugin ! null && await flutterWebViewPlugin.canGoBack() true) {flutterWebViewPlugin!.goBack();return false; // 阻止默认的返回行为} else {return true; // 允许默认的返回行为}},child: Scaffold(),);…...

【sqlserver】mssql 批量加载数据文件 bulk copy使用
参考文章: Using bulk copy with the JDBC driver SqlServer数据批量写入 SqlServer批量插入数据方法–SqlBulkCopy sqlserver buld copy需要提供,数据文件的对应表的元数据信息主要的字段的位置、字段的名称、字段的数据类型。 执行bulk load时候不一…...

flinkSql中累计窗口CUMULATE
eventTime package com.bigdata.day08;import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.table.api.bridge.java.StreamTableEnvironment;public class _05_flinkSql_Cumulate_eventTime {/*** 累积窗口 eventTime* …...

关于在ubuntu上无法运行EasyConnect的解决方法
需要这三个文件 libpangocairo-1.0-0_1.40.14-1_amd64.deb libpangoft2-1.0-0_1.40.14-1_amd64.deb libpango-1.0-0_1.40.14-1_amd64.deb然后执行 cp source /usr/share/sangfor/EasyConnect再重启EasyConnect即可 下载链接 http://kr.archive.ubuntu.com/ubuntu/pool/main/…...

【Axure高保真原型】数值条件分组
今天和大家分享数值条件分组的原型模板,效果包括: 点击添加分组按钮,可以显示添加弹窗,填写分组名称和数值区间后,可以新增该分组信息‘’ 修改分组区间,可以直接在输入框里修改已有的分组区间,…...

python学习——字符串的拼接操作
在Python中,字符串拼接是一项基本操作,用于将多个字符串合并成一个字符串。以下是几种常见的字符串拼接方式: 1. 使用 运算符 最简单和直接的方式是使用 运算符来拼接字符串。 str1 "Hello, " str2 "World!" resu…...

多线程篇-8--线程安全(死锁,常用保障安全的方法,安全容器,原子类,Fork/Join框架等)
1、线程安全和不安全定义 (1)、线程安全 线程安全是指一个类或方法在被多个线程访问的情况下可以正确得到结果,不会出现数据不一致或其他错误行为。 线程安全的条件 1、原子性(Atomicity) 多个操作要么全部完成&a…...

el-select的搜索功能
el-select的相关信息: 最基本信息 v-model的值为当前被选中的el-option的 value 属性值 :label是选择器可以看到的内容 过滤搜索 普通过滤搜索 <el-selectv-model"selectedCountry"placeholder"请选择国家"filterable:loading"lo…...

MFC实现全屏功能
之前全屏都是参考: MFC单文档(SDI)全屏程序的实现 主要思路就是将各种菜单工具栏隐藏恢复。 随着MFC的升级,MFC框架本身就具备了全屏的功能。 微软有一个全屏实现类: CFullScreenImpl Class managing full-screen mod…...

网络安全技术详解:虚拟专用网络(VPN) 安全信息与事件管理(SIEM)
虚拟专用网络(VPN)详细介绍 虚拟专用网络(VPN)通过在公共网络上创建加密连接来保护数据传输的安全性和隐私性。 工作原理 VPN的工作原理涉及建立安全隧道和数据加密: 隧道协议:使用协议如PPTP、L2TP/IP…...

v-model 根据后端接口返回的数据动态地确定要绑定的变量
在 Vue 中,v-model 是用于创建双向绑定的指令。通常,它用于与组件或表单元素的值进行绑定。但有时你可能需要根据后端接口返回的数据动态地确定要绑定的变量。 你可以通过以下步骤来实现这个需求: 步骤 1: 获取后端接口数据 首先ÿ…...

图形开发基础之在WinForms中使用OpenTK.GLControl进行图形绘制
前言 GLControl 是 OpenTK 库中一个重要的控件,专门用于在 Windows Forms 应用程序中集成 OpenGL 图形渲染。通过 GLControl,可以轻松地将 OpenGL 的高性能图形绘制功能嵌入到传统的桌面应用程序中。 1. GLControl 的核心功能 OpenGL 渲染上下文&…...

离散数学重点复习
第一章.集合论 概念 1.集合是不能精确定义的基本数学概念.通常是由指定范围内的满足给定条件的所有对象聚集在一起构成的 2.制定范围内的每一个对象称为这个集合的元素 3.固定符号如下: N:自然数集合 Z:整数集合 Q:有理数集合 R:实数集合 C:复数集合 4.集合中的元素是…...

Javaweb梳理21——Servlet
Javaweb梳理21——Servlet 21 Servlet21.1 简介21.3 执行流程21.4 生命周期4.5 方法介绍21.6 体系结构21.7 urlPattern配置21.8 XML配置 21 Servlet 21.1 简介 Servlet是JavaWeb最为核心的内容,它是Java提供的一门动态web资源开发技术。使用Servlet就可以实现&…...

推荐学习笔记:矩阵补充和矩阵分解
参考: 召回 fun-rec/docs/ch02/ch2.1/ch2.1.1/mf.md at master datawhalechina/fun-rec GitHub 业务 隐语义模型与矩阵分解 协同过滤算法的特点: 协同过滤算法的特点就是完全没有利用到物品本身或者是用户自身的属性, 仅仅利用了用户与…...

etcd分布式存储系统快速入门指南
在分布式系统的复杂世界中,确保有效的数据管理至关重要。分布式可靠的键值存储在维护跨分布式环境的数据一致性和可伸缩性方面起着关键作用。 在这个全面的教程中,我们将深入研究etcd,这是一个开源的分布式键值存储。我们将探索其基本概念、特…...

解决VUE3 Vite打包后动态图片资源不显示问题
解决VUE3 Vite打包后动态图片资源不显示问题 <script setup> let url ref()const setimg (item)>{let src ../assets/image/${e}.pngurl.value src }</script><template><div v-for"item in 6"><h1 click"setimg(item)"…...

大数据新视界 -- 大数据大厂之 Hive 临时表与视图:灵活数据处理的技巧(上)(29 / 30)
💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...

Android学习14--charger
1 概述 最近正好在做关机充电这个,就详细看看吧。还是本着保密的原则,项目里的代码也不能直接用,这里就用的Github的。https://github.com/aosp-mirror 具体位置是:https://github.com/aosp-mirror/platform_system_core/tree/mai…...

页面开发样式和布局入门:Vite + Vue 3 + Less
页面开发样式和布局入门:Vite Vue 3 Less 引言 在现代前端开发中,样式和布局是页面开发的核心部分。随着技术的不断发展,Vite、Vue 3和Less等工具和框架的出现,使得前端开发变得更加高效和灵活。然而,尽管这些工具…...