树形结构的三级分类如何实现?
概述:
本三级联动分类服务端使用的是: Springboot + MyBatis-plus,前端使用的是:Vue+ElementUI,树形控件使用的是el-tree。本三级联动分类可以把任一子项拖拽到其它目录,可以添加、编辑、删除分类。
效果图:
实现流程:
一、树形数据展示实现
1、创建表
- cat_id使用bigint类型目的是为了使用雪花算法,加快查询的速度;
- parent_cid父ID,用于子节点指向父亲节点,同理我们可根据当前节点等于子节点点父ID,然后递归,找到所属的所有子节点
- cat_level层级,用于识别当前节点是一级、二级还是三级节点
- show_status是否显示,控制是否显示,使用了逻辑删除功能
- product_unit计量单位,使用什么单位统计当前分类下产品的数量
- product_count产品数量,在添加商品时进行统计更新
- sort排序,进行分类排序
- icon图表,类别的图片,使用iconfont
CREATE TABLE `kmall_product`.`pro_category` (`cat_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '分类id',`name` char(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '分类名称',`parent_cid` bigint(20) NULL DEFAULT NULL COMMENT '父分类id',`cat_level` int(4) NULL DEFAULT NULL COMMENT '层级',`show_status` tinyint(2) NULL DEFAULT NULL COMMENT '是否显示[0-不显示,1显示]',`sort` int(4) NULL DEFAULT NULL COMMENT '排序',`icon` char(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '图标地址',`product_unit` char(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '计量单位',`product_count` int(11) NULL DEFAULT NULL COMMENT '商品数量',PRIMARY KEY (`cat_id`) USING BTREE,INDEX `parent_cid`(`parent_cid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1433 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '商品三级分类' ROW_FORMAT = Dynamic;
2、生成实体类
把上面点表内能映射为实体类,便于java中操作
@Data
@TableName("pro_category")
public class CategoryEntity implements Serializable {private static final long serialVersionUID = 1L;/*** 分类id*/@TableIdprivate Long catId;/*** 分类名称*/private String name;/*** 父分类id*/private Long parentCid;/*** 层级*/private Integer catLevel;/*** 是否显示[0-不显示,1显示]*/@TableLogic(value = "1", delval = "0")private Integer showStatus;/*** 排序*/private Integer sort;/*** 图标地址*/private String icon;/*** 计量单位*/private String productUnit;/*** 商品数量*/private Integer productCount;@JsonInclude(value = JsonInclude.Include.NON_EMPTY)@TableField(exist = false)private List<CategoryEntity> children;}
说明:下面的children是用来保存子节点数据,是暂存在内存中,所以要加上@TableField(exist = false)注解
@JsonInclude(value = JsonInclude.Include.NON_EMPTY)@TableField(exist = false)private List<CategoryEntity> children;
3、获取树形数据
创建CategoryController控制层,添加请求方法,使用的是get请求,查询到结果后以data为名称返回给前端
/*** 查出所有分类以及子分类,以树形结构组装起来*/@RequestMapping("/list/tree")public R listWithTree(){List<CategoryEntity> entities = categoryService.listWithTree();return R.ok().put("data", entities);}
4、查询封装树形数据
创建CategoryServiceImpl实现层,实现listWithTree方法
- 首先查出所有分类
- 选出一级分类
- 递归获取一级分类的所有子节点,设置到children属性中
@Overridepublic List<CategoryEntity> listWithTree() {//查出所有分类List<CategoryEntity> entities = baseMapper.selectList(null);//组装成父子树形结构//1级分类List<CategoryEntity> menus = entities.stream().filter(entity -> entity.getParentCid() == 0).map(entity -> {entity.setChildren(getChildren(entity, entities));return entity;}).sorted((menu1, menu2) ->(menu1.getSort() == null ? 0 : menu1.getSort()) -(menu2.getSort() == null ? 0 : menu2.getSort())).collect(Collectors.toList());return menus;}
/*** 递归查找所有菜单的子菜单*/private List<CategoryEntity> getChildren(CategoryEntity root, List<CategoryEntity> all) {List<CategoryEntity> children = all.stream().filter(entity -> entity.getParentCid().equals(root.getCatId())).map(entity -> {entity.setChildren(getChildren(entity, all)); //递归设置return entity;}).sorted((menu1, menu2) ->(menu1.getSort() == null ? 0 : menu1.getSort()) -(menu2.getSort() == null ? 0 : menu2.getSort())).collect(Collectors.toList());return children;}
5、前端展现实现
5.1、树形控件el-tree设置
- :data=“menus”:绑定数据menus
- :props=“defaultProps” :设置默认属性defaultProps,便于与后端数据转换
- expand-on-click-node:设置为false,表示需要单击才展开
- show-checkbox:显示checkbox复选框
- node-key=“catId” :绑定主键
- :default-expanded-keys=“expandedKey” :设置默认展开分类
- :draggable=“draggable” :是否能拖拽节点数据
- :allow-drop=“allowDrop”:拖拽时判定目标节点能否被放置。type 参数有三种情况:‘prev’、‘inner’ 和 ‘next’,分别表示放置在目标节点前、插入至目标节点和放置在目标节点后
- @node-drop=“handleDrop”:拖拽成功完成时触发的事件
<el-tree :data="menus" :props="defaultProps" :expand-on-click-node="false" show-checkbox node-key="catId":default-expanded-keys="expandedKey" :draggable="draggable" :allow-drop="allowDrop" @node-drop="handleDrop"ref="menuTree"> </el-tree>
5.2、树形控件el-tree数据初始化
data() {return {pCid: [],draggable: false,updateNodes: [],maxLevel: 0,title: "",dialogType: "", //edit,addcategory: {name: "",parentCid: 0,catLevel: 0,showStatus: 1,sort: 0,productUnit: "",icon: "",catId: null},dialogVisible: false,menus: [],expandedKey: [],defaultProps: {children: "children",label: "name"}};},
5.3、加载menus数据,绑定到树形控件
说明:/product/category/list/tree此路径对应的是controller里查找树形数据的方法
getMenus() {this.$http({url: this.$http.adornUrl("/product/category/list/tree"),method: "get"}).then(({data}) => {console.log("成功获取到菜单数据...", data.data);this.menus = data.data;});},
二、添加编辑删除树形控件实现
1、前端添加、编辑、删除实现
1.1、 html内容
- 只有叶子节点才显示删除功能
- 所有的分类都可以编辑
- 只有一级、二级分类有添加功能
<el-button v-if="draggable" @click="batchSave">批量保存</el-button>
<el-button size="mini" type="danger" @click="batchDelete">批量删除</el-button>
<el-tree :data="menus" :props="defaultProps" :expand-on-click-node="false" show-checkbox node-key="catId":default-expanded-keys="expandedKey" :draggable="draggable" :allow-drop="allowDrop" @node-drop="handleDrop"ref="menuTree"><span class="custom-tree-node" slot-scope="{ node, data }"><span>{{ node.label }}</span><span><el-button v-if="node.level <=2" type="text" size="mini" @click="() => append(data)">添加</el-button><el-button type="text" size="mini" @click="edit(data)">编辑</el-button><el-button v-if="node.childNodes.length==0" type="text" size="mini"@click="() => remove(node, data)">删除</el-button></span></span></el-tree>
1.2、js实现
- 添加:
append(data) {console.log("append", data);this.dialogType = "add";this.title = "添加分类";this.dialogVisible = true;this.category.parentCid = data.catId;this.category.catLevel = data.catLevel * 1 + 1;this.category.catId = null;this.category.name = "";this.category.icon = "";this.category.productUnit = "";this.category.sort = 0;this.category.showStatus = 1;},
//添加三级分类addCategory() {console.log("提交的三级分类数据", this.category);this.$http({url: this.$http.adornUrl("/product/category/save"),method: "post",data: this.$http.adornData(this.category, false)}).then(({data}) => {this.$message({message: "菜单保存成功",type: "success"});//关闭对话框this.dialogVisible = false;//刷新出新的菜单this.getMenus();//设置需要默认展开的菜单this.expandedKey = [this.category.parentCid];});},
submitData() {if (this.dialogType == "add") {this.addCategory();}if (this.dialogType == "edit") {this.editCategory();}},
- 批量添加
batchSave() {this.$http({url: this.$http.adornUrl("/product/category/update/sort"),method: "post",data: this.$http.adornData(this.updateNodes, false)}).then(({data}) => {this.$message({message: "菜单顺序等修改成功",type: "success"});//刷新出新的菜单this.getMenus();//设置需要默认展开的菜单this.expandedKey = this.pCid;this.updateNodes = [];this.maxLevel = 0; });},
- 编辑
edit(data) {console.log("要修改的数据", data);this.dialogType = "edit";this.title = "修改分类";this.dialogVisible = true;//发送请求获取当前节点最新的数据this.$http({url: this.$http.adornUrl(`/product/category/info/${data.catId}`),method: "get"}).then(({data}) => {//请求成功console.log("要回显的数据", data);this.category.name = data.data.name;this.category.catId = data.data.catId;this.category.icon = data.data.icon;this.category.productUnit = data.data.productUnit;this.category.parentCid = data.data.parentCid;this.category.catLevel = data.data.catLevel;this.category.sort = data.data.sort;this.category.showStatus = data.data.showStatus; });},
//修改三级分类数据editCategory() {var {catId,name,icon,productUnit} = this.category;this.$http({url: this.$http.adornUrl("/product/category/update"),method: "post",data: this.$http.adornData({catId,name,icon,productUnit}, false)}).then(({data}) => {this.$message({message: "菜单修改成功",type: "success"});//关闭对话框this.dialogVisible = false;//刷新出新的菜单this.getMenus();//设置需要默认展开的菜单this.expandedKey = [this.category.parentCid];});},
- 删除单个节点
remove(node, data) {var ids = [data.catId];this.$confirm(`是否删除【${data.name}】菜单?`, "提示", {confirmButtonText: "确定",cancelButtonText: "取消",type: "warning"}).then(() => {this.$http({url: this.$http.adornUrl("/product/category/delete"),method: "post",data: this.$http.adornData(ids, false)}).then(({data}) => {this.$message({message: "菜单删除成功",type: "success"});//刷新出新的菜单this.getMenus();//设置需要默认展开的菜单this.expandedKey = [node.parent.data.catId];});}).catch(() => {});console.log("remove", node, data);}
- 批量删除
1)首先根据选中的节点获取选中的节点 catId
2)提示是否删除
3)如果确定删除,则调用服务层的批量删除方法
4)删除成功后提示,并重新加载菜单
batchDelete() {let catIds = [];let checkedNodes = this.$refs.menuTree.getCheckedNodes();console.log("被选中的元素", checkedNodes);for (let i = 0; i < checkedNodes.length; i++) {catIds.push(checkedNodes[i].catId);}this.$confirm(`是否批量删除【${catIds}】菜单?`, "提示", {confirmButtonText: "确定",cancelButtonText: "取消",type: "warning"}).then(() => {this.$http({url: this.$http.adornUrl("/product/category/delete"),method: "post",data: this.$http.adornData(catIds, false)}).then(({data}) => {this.$message({message: "菜单批量删除成功",type: "success"});this.getMenus();});}).catch(() => {});},
2、服务端添加、编辑、删除实现
- 添加
@RequestMapping("/save")public R save(@RequestBody CategoryEntity category){categoryService.save(category);return R.ok();}
- 编辑
@RequestMapping("/info/{catId}")public R info(@PathVariable("catId") Long catId){CategoryEntity category = categoryService.getById(catId);return R.ok().put("data", category);}@RequestMapping("/update")public R update(@RequestBody CategoryEntity category){categoryService.updateCascade(category);return R.ok();}
- 删除
@RequestMapping("/delete")public R delete(@RequestBody Long[] catIds){//1.检查当前删除的分类,是否被别的地方引用categoryService.removeMenuByIds(Arrays.asList(catIds));return R.ok();}@Overridepublic void removeMenuByIds(List<Long> asList) { //逻辑删除baseMapper.deleteBatchIds(asList);}
三、树形控件拖拽功能实现
1、前端实现
1.1、html部分,添加拖拽控制开关
<el-switch v-model="draggable" active-text="开启拖拽" inactive-text="关闭拖拽"></el-switch><el-button v-if="draggable" @click="batchSave">批量保存</el-button><el-button size="mini" type="danger" @click="batchDelete">批量删除</el-button><el-tree :data="menus" :props="defaultProps" :expand-on-click-node="false" show-checkbox node-key="catId":default-expanded-keys="expandedKey" :draggable="draggable" :allow-drop="allowDrop" @node-drop="handleDrop"ref="menuTree"><span class="custom-tree-node" slot-scope="{ node, data }"><span>{{ node.label }}</span><span><el-button v-if="node.level <=2" type="text" size="mini" @click="() => append(data)">添加</el-button><el-button type="text" size="mini" @click="edit(data)">编辑</el-button><el-button v-if="node.childNodes.length==0" type="text" size="mini"@click="() => remove(node, data)">Delete</el-button></span></span></el-tree>
1.2、js部分
- 计算可拖拽的信息,找到所有子节点,求出最大深度
1)被拖动的当前节点以及所在的父节点总层数不能大于3
2)计算当前节点所在的最大层级,一般是<= 3 ,
3)计算当前节点所在的最大深度,一般是<= 3 , 公式:let deep = Math.abs(this.maxLevel - draggingNode.level) + 1;
4)判断拖拽是在内部,还是前后,如果是拖拽到某节点的内部,必须:deep + dropNode.level <= 3;
5)否则 deep + dropNode.parent.level <= 3;
allowDrop(draggingNode, dropNode, type) {//1、被拖动的当前节点以及所在的父节点总层数不能大于3//1)、被拖动的当前节点总层数console.log("allowDrop:", draggingNode, dropNode, type);//this.countNodeLevel(draggingNode);//当前正在拖动的节点+父节点所在的深度不大于3即可let deep = Math.abs(this.maxLevel - draggingNode.level) + 1;console.log("深度:", deep);// this.maxLevelif (type == "inner") { return deep + dropNode.level <= 3;} else {return deep + dropNode.parent.level <= 3;}},countNodeLevel(node) {//找到所有子节点,求出最大深度if (node.childNodes != null && node.childNodes.length > 0) {for (let i = 0; i < node.childNodes.length; i++) {if (node.childNodes[i].level > this.maxLevel) {this.maxLevel = node.childNodes[i].level;}this.countNodeLevel(node.childNodes[i]);}}else{this.maxLevel = node.level}},
- 处理拖拽的节点,排序
handleDrop(draggingNode, dropNode, dropType, ev) {console.log("handleDrop: ", draggingNode, dropNode, dropType);//1、当前节点最新的父节点idlet pCid = 0;let siblings = null;if (dropType == "before" || dropType == "after") {pCid = dropNode.parent.data.catId == undefined ? 0 : dropNode.parent.data.catId;siblings = dropNode.parent.childNodes;} else {pCid = dropNode.data.catId;siblings = dropNode.childNodes;}this.pCid.push(pCid);//2、当前拖拽节点的最新顺序,for (let i = 0; i < siblings.length; i++) {if (siblings[i].data.catId == draggingNode.data.catId) {//如果遍历的是当前正在拖拽的节点let catLevel = draggingNode.level;if (siblings[i].level != draggingNode.level) {//当前节点的层级发生变化catLevel = siblings[i].level;//修改他子节点的层级this.updateChildNodeLevel(siblings[i]);}this.updateNodes.push({catId: siblings[i].data.catId,sort: i,parentCid: pCid,catLevel: catLevel});} else {this.updateNodes.push({catId: siblings[i].data.catId,sort: i});}}//3、当前拖拽节点的最新层级console.log("updateNodes", this.updateNodes);},
2、服务端实现
@RequestMapping("/update/sort")public R updateSort(@RequestBody List<CategoryEntity> categorys){categoryService.updateBatchById(categorys);return R.ok();}
源码下载:
https://gitee.com/charlinchenlin/koo-erp
相关文章:
树形结构的三级分类如何实现?
概述: 本三级联动分类服务端使用的是: Springboot MyBatis-plus,前端使用的是:VueElementUI,树形控件使用的是el-tree。本三级联动分类可以把任一子项拖拽到其它目录,可以添加、编辑、删除分类。 效果图:…...
SSM整合完整流程
🏠个人主页:shark-Gao 🧑个人简介:大家好,我是shark-Gao,一个想要与大家共同进步的男人😉😉 🎉目前状况:23届毕业生,目前在某公司实习…...
虹科方案 | 助力高性能视频存储解决方案-2
上篇文章《虹科方案 | 助力高性能视频存储解决方案-1》我们分享了虹科&ATTO 和 Avid 共同创建协作解决方案,助力高性能视频存储,今天我们再深入介绍一下我们的案例详情。 一、行业挑战 从高端广播设施到小型独立工作室的媒体后期制作环境都需要允许多…...
java版深圳 工程管理系统软件 自主研发,工程行业适用 软件源码
Java版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下: 首页 工作台:待办工作、消息通知、预警信息,点击可进入相应的列表 项目进度图表:选择(总体或单个)项目显示…...
云原生Istio架构和组件介绍
目录 1 Istio 架构2 Istio组件介绍2.1 Pilot2.2 Mixer2.3 Citadel2.4 Galley2.5 Sidecar-injector2.6 Proxy(Envoy)2.7 Ingressgateway2.8 其他组件 1 Istio 架构 Istio的架构,分为控制平面和数据面平两部分。 - 数据平面:由一组智能代理([En…...
吹爆,全网第一个手把手教你从零开始搭建Spring Cloud Alibaba的笔记
Spring Cloud Alibaba 是阿里巴巴提供的微服务开发一站式解决方案,是阿里巴巴开源中间件与 Spring Cloud 体系的融合。 Springcloud 和 Srpingcloud Alibaba 区别? SpringCloud: 部分组件停止维护和更新,给开发带来不便;SpringCl…...
企业短信遭疯狂盗用,可能是没配置验证码
手机短信作为一种快捷的通讯方式被广泛应用。不仅在个人日常生活中,企业也习惯使用手机短信来进行验证和提醒,以保证业务的正常进行。随着数字化的发展,手机短信也成为了不法分子滥用的目标之一,给个人和企业带来不同经济损失。 个…...
【UE】直升机沿样条线移动
效果 步骤 1. 将虚幻商城中的免费资产导入工程 下载完毕后可以看到如下文件 2. 新建一个Actor蓝图类,命名为“Track”,这个蓝图就是用来画样条线的 打开“Track”,添加样条组件 3. 打开“BP_West_Heli_AH64D” 在事件图表中先新建一个时间轴…...
GaussDB_200_6.5.1部署安装
目录 安装前准备 安装依赖 修改/etc/hosts 上传解压介质 预安装 拷贝安装包 预安装配置 编辑preinstall.ini配置文件 编辑host0配置文件 执行预安装命令 安装FusionInsight_Manager 修改install安装配置文件 执行安装命令 web操作安装数据库 GaussDB200测试 配…...
软件工具 | Python调用运筹优化求解器(一):以CVRPVRPTW为例
目录 1. 引言2. 求解器介绍3. 基础语言3.1 创建模型3.2 添加变量3.3 添加目标函数3.4 添加约束3.5 设置参数3.6 求解 4. 数学模型4.1 [CVRP数学模型](https://mp.weixin.qq.com/s/DYh-5WkrYxk1gCKo8ZjvAw)4.2 [VRPTW数学模型](https://mp.weixin.qq.com/s/tF-ayzjpZfuZvelvItue…...
如何在JAVA中实现网络编程?
在Java中实现网络编程通常需要使用Java提供的网络编程库——Java Networking API。Java Networking API支持常见的TCP和UDP协议,包括Socket、ServerSocket、DatagramSocket等类,通过这些类,我们可以创建、连接、监听和传输数据。 下面是在Ja…...
【redis】redis的缓存过期淘汰策略
【redis】redis的缓存过期淘汰策略 文章目录 【redis】redis的缓存过期淘汰策略前言一、面试题二、redis内存满了怎么办?1、redis默认内存是多少?在哪查看?如何修改?在conf配置文件中可以查看 修改,内存默认是0redis的默认内存有…...
ASP.NET动态Web开发技术第8章
第8章ASP.NET数据访问 一.预习笔记 1.SqlDataSource控件 SqlDataSource数据源控件支持连接SQL关系数据库,它使用SQL命令来检索和修改数据。通常将SqlDataSource数据源控件与数据绑定控件一起使用。 属性1:ID:当前数据源控件的唯一标识符 …...
【旋转编码器如何工作以及如何将其与Arduino一起使用】
在本教程中,我们将学习旋转编码器的工作原理以及如何将其与Arduino一起使用。您可以观看以下视频或阅读下面的书面教程。 1. 概述 旋转编码器是一种位置传感器,用于确定旋转轴的角度位置。它根据旋转运动产生模拟或数字电信号。 有许多不同类型的旋转编码器按输出信号或传感…...
Tre靶场通关过程(linpeas使用+启动项编辑器提权)
Tre靶场通关 通过信息收集获得到了普通用户账号密码,利用PEASS-ng的linpeas脚本进行提权的信息收集,根据已有信息进行提权。 靶机下载地址: https://download.vulnhub.com/tre/Tre.zip 信息收集 靶机IP探测:192.168.0.129 a…...
java多线程下
ThreadLocal ThreadLocal 有什么用?通常情况下,我们创建的变量是可以被任何一个线程访问并修改的。如果想实现每一个线程都有自己的专属本地变量该如何解决呢?JDK 中自带的ThreadLocal类正是为了解决这样的问题。 ThreadLocal类主要解决的就…...
使用无标注的数据训练Bert
文章目录 1、准备用于训练的数据集2、处理数据集3、克隆代码4、运行代码5、将ckpt模型转为bin模型使其可在pytorch中运用 Bert官方仓库:https://github.com/google-research/bert 1、准备用于训练的数据集 此处准备的是BBC news的数据集,下载链接&…...
《Netty》从零开始学netty源码(五十二)之PoolThreadCache
PoolThreadCache Netty有一个大的公共内存容器PoolArena,用来管理从操作系统中获得的内存,在高并发下如果所有线程都去这个大容器获取内存它的压力是非常大的,所以Netty为每个线程建立了一个本地缓存,即PoolThreadCacheÿ…...
放弃40k月薪的程序员工作,选择公务员,我来分享一下看法
我有一个朋友,拒绝了我为他提供的4万薪水的工作,去了一个体制内的银行,做程序员,即使薪水减半。他之前在北京一家大公司做程序员,一个月30k。当我开始创业时,我拉他来和我一起干,但那时我们太小…...
【MybatisPlus】高级版可视化、可配置 自动生成代码
今天看别人使用了一个更加智能的生成代码工具,可视化、可配置策略,非常方便,配置一次,在哪都可以使用,也不会跟项目藕合下面简单说一下使用方式。 1、介绍mybatis-plus-generator-ui 主要是封装了mybatis-plus-gener…...
【图像分割】【深度学习】Windows10下f-BRS官方代码Pytorch实现
【图像分割】【深度学习】Windows10下f-BRS官方代码Pytorch实现 提示:最近开始在【图像分割】方面进行研究,记录相关知识点,分享学习中遇到的问题已经解决的方法。 文章目录 【图像分割】【深度学习】Windows10下f-BRS官方代码Pytorch实现前言f-BRS模型运行环境安装1.下载源码并…...
2023/5/4总结
刷题: 第二周任务 - Virtual Judge (vjudge.net) 这一题用到了素筛,然后穷举即可 #include<stdio.h> #define Maxsize 500000 int a[Maxsize]; long long b[Maxsize]; long long max0; int sushu() {a[0]a[1]0;int i,j,k;for(i2,k0;i<Maxsize;i){if(a[i…...
electron+vue3全家桶+vite项目搭建【17】pinia状态持久化
文章目录 引入问题演示实现效果展示、实现步骤1.封装状态初始化函数2.封装状态更新同步函数3.完整代码 引入 上一篇文章我们已经实现了electron多窗口中,pinia的状态同步,但你会发现,如果我们在一个窗口里面修改了状态,然后再打开…...
java基础入门-05-【面向对象进阶(static继承)】
Java基础入门-05-【面向对象进阶(static&继承)】 13、面向对象进阶(static&继承)1.1 如何定义类1.2 如何通过类创建对象1.3 封装1.3.1 封装的步骤1.3.2 封装的步骤实现 1.4 构造方法1.4.1 构造方法的作用1.4.2 构造方法的…...
day12 IP协议与ethernet协议
目录 IP包头 IP网的意义 IP数据报的格式 IP数据报分片 以太网包头(链路层协议) IP包头 IP网的意义 当互联网上的主机进行通信时,就好像在一个网络上通信一样,看不见互联的各具体的网络异构细节; 如果在这种覆盖…...
蓝牙耳机哪款性价比高?2023蓝牙耳机性价比排行
随着蓝牙耳机的使用愈发频繁,蓝牙耳机产品也越来越多,蓝牙耳机的功能、价格、外观设计等都不尽相同。接下来,我来给大家推荐几款性价比高的蓝牙耳机,感兴趣的朋友一起来看看吧。 一、南卡小音舱Lite2蓝牙耳机 参考价:…...
关于C语言的一些笔记
文章目录 May4,2023常量问题基本数据类型补码printf的字符格式控制关于异或、异或的理解赋值运算i和i的区别关系运算符 May5,2023逻辑运算中‘非’的理解逗号运算运算符的优先级问题三目运算 摘自加工于C技能树 May4,2023 常量问题 //定义常量 const float PI; PI…...
【Python入门知识】NumPy数组迭代及连接
前言 嗨喽~大家好呀,这里是魔王呐 ❤ ~! 数组迭代 迭代意味着逐一遍历元素,当我们在 numpy 中处理多维数组时, 可以使用 python 的基本 for 循环来完成此操作。 如果我们对 1-D 数组进行迭代,它将逐一遍历每个元素。 实例 迭…...
我们公司的面试,有点不一样!
我们公司的面试,有点不一样! 朋友们周末愉快,我是鱼皮。因为我很屑,所以大家也可以叫我屑老板。 自从我发了自己创业的文章和视频后,收到了很多小伙伴们的祝福,真心非常感谢! 不得不说&#…...
C++之初识STL—vector
文章目录 STL基本概念使用STL的好处容器vector1.vector容器简介2.vector对象的默认构造函数3.vector对象的带参构造函数4.vector的赋值5.vector的大小6.vector容器的访问方式7.vector的插入 STL基本概念 STL(Standard Template Library,标准模板库)STL 从广义上分为: 容器(con…...
大宁网站制作/源码网
认识DOM 文档对象模型DOM(Document Object Model)定义访问和处理HTML文档的标准方法。DOM 将HTML文档呈现为带有元素、属性和文本的树结构(节点树)。 先来看看下面代码: 将HTML代码分解为DOM节点层次图: HTML文档可以说由节点构…...
网站分屏布局设计/百度指数关键词
算法题——分配礼物问题描述问题分析代码实现总结问题描述 圣诞节到了,圣诞老人准备了n 个礼物给k小朋友,每个礼物都是一样的。请问将这n个礼物分给k个小朋友,有多少种分法? 编写一个程式,输入是礼物的数量n和小朋友数…...
盐城市规划建设局网站/百度爱采购优化
公众号关注 「奇妙的 Linux 世界」设为「星标」,每天带你玩转 Linux !据BleepingComputer 2月10日消息,Clop 勒索软件组织最近利用 GoAnywhere MFT 安全文件传输工具中的零日漏洞,从 130 多个企业组织中窃取了数据。该安全漏洞被追…...
禁止指定ip访问网站/开一个网站需要多少钱
LinuxShell col命令 Linux col命令用于过滤控制字符。 在许多UNIX说明文件里,都有RLF控制字符。当我们运用shell特殊字符">“和”>>",把说明文件的内容输出成纯文本文件时,控制字符会变成乱码,col指令则能有…...
泰安网站建设哪家专业/怎样建立一个网络销售平台
上一篇博客我们讲了搭建集群和节点通信,这节课我们来讲一下如果节点出问题了,redis内部是如何来进行故障转移的 1.发现有问题的节点 上节课我们也提到了redis节点是怎么通信的"ping-pong",通信时附加了消息,消息除了槽信息,还有节点状态/节点故障等 解释: 节点a发…...
如何做酒店网站设计/图床外链生成工具
1.前言 在自然语言处理领域,近几年最火的是什么?是BERT!谷歌团队2018提出的用于生成词向量的BERT算法在NLP的11项任务中取得了非常出色的效果,堪称2018年深度学习领域最振奋人心的消息。而BERT算法又是基于Transformer࿰…...