编写函数将一个M * N的矩阵转置成 N * M 的矩阵

任务描述 本关任务:编写函数将一个M * N的矩阵转置成一个N * M的矩阵,要求定义函数分别进行二维数组输入、输出和转置。 相关知识 由M * N个数排成的M行N列的数表称为M行N列的矩阵,简称 M * N矩阵,在编程语言中可以当做二维数组来处理。 转置:把矩阵A的行换成同序数的列所得到的新矩阵B称为A的转置矩阵。 定义两个二维数组如下: int a[M][N],b[N][M]; 如果3*5的矩阵A的值如下 : 55 8 74 66 23 32 12 1 36 58 94 45 56 88 31 那么矩阵A的转置矩阵B的值如下 : 55 32 94 8 12 45 74 1 56 66 36 88 23 58 31 M和N有可能相等,也有可能不相等,针对二维数组不同的列数,定义不同的输出二维数组的函数: void Output1(int (*b)[M],int m,int n){int i,j; for(i=0;i<m;i++){ for(j=0;j<n;j++)printf("%d\t",*(*(b+i)+j));printf("\n");} }void Output2(int (*b)[N],int m,int n){int i,j; for(i=0;i<m;i++){ for(j=0;j<n;j++)printf("%d\t",*(*(b+i)+j));printf("\n");} } 编程要求 根据提示,在右侧编辑器 Begin-End 区间补充代码,编写函数输入一个3 * 5的矩阵,转置成一个5 * 3的矩阵,具体要求如下:

使用自己的数据利用pytorch搭建自编码器提取特征

使用自己的数据利用pytorch搭建自编码器提取特征 1、定义编码器(Encoder)和解码器(Decoder)模型2、定义自编码器(Autoencoder)模型3、定义自定义数据集(MyDataset)4、参数初始化5、加载数据集6、构造数据集7、定义损失函数和优化器8、训练自编码器模型9、特征提取10、完整代码 使用PyTorch实现的自编码器模型,它的作用是对一个数据集进行特征提取。具体步骤如下: 1、定义编码器(Encoder)和解码器(Decoder)模型 它们分别由两个全连接层组成。 2、定义自编码器(Autoencoder)模型 它包含一个编码器和一个解码器。 3、定义自定义数据集(MyDataset) 它用于加载数据集,构造tensor数据集。 4、参数初始化 定义超参数。 5、加载数据集 提取需要的特征和标签,对特征进行数据标准化。 6、构造数据集 构造tensor数据集并封装为可迭代对象,创建Dataloader对象,用于批量读取数据。 7、定义损失函数和优化器 初始化模型、损失函数和优化器 8、训练自编码器模型 训练模型,并输出每个epoch的损失值。 9、特征提取 使用训练好的自编码器模型对数据集进行特征提取,并将提取的特征保存为csv文件。 需要注意的是,这段代码没有包含模型的测试部分,但是在训练之后,可以使用训练好的自编码器模型对新的数据进行特征提取。 10、完整代码 # -*- coding: utf-8 -*- # @Time : 2023/5/25 14:29 # @Author : huangjian # @File : AE.py import torch import torch.nn as nn from torch.utils.data import DataLoader, Dataset import pandas as pd from sklearn import preprocessing # 定义编码器 class Encoder(nn.Module): def __init__(self, input_dim, hidden_dim, latent_dim): super(Encoder, self).

一篇文章带你看懂5G网络(接入网+承载网+核心网)

通过这张网络简图帮助大家认识一下全网的网络架构,通过对全网架构的了解,将方便您对后面每一块网络细节的理解。 这张图分为左右两部分,右边为无线侧网络架构,左边为固定侧网络架构。 无线侧:手机或者集团客户通过基站接入到无线接入网,在接入网侧可以通过RTN或者IPRAN或者PTN解决方案来解决,将信号传递给BSC/RNC。在将信号传递给核心网,其中核心网内部的网元通过IP承载网来承载。 固网侧:家客和集客通过接入网接入,接入网主要是GPON,包括ONT、ODN、OLT。信号从接入网出来后进入城域网,城域网又可以分为接入层、汇聚层和核心层。BRAS为城域网的入口,主要作用是认证、鉴定、计费。信号从城域网走出来后到达骨干网,在骨干网处,又可以分为接入层和核心层。其中,移动叫CMNET、电信叫169、联通叫163。 固网侧和无线侧之间可以通过光纤进行传递,远距离传递主要是有波分产品来承担,波分产品主要是通过WDM+SDH的升级版来实现对大量信号的承载,OTN是一种信号封装协议,通过这种信号封装可以更好的在波分系统中传递。 最后信号要通过防火墙到达INTERNET,防火墙主要就是一个NAT,来实现一个地址的转换。这就是整个网络的架构。 看完宏观的架构,让我们深入进每个部分,去深入解读一下吧。 由于我们的手机打电话或者上网时,信号首先抵达的就是无线接入网,因此这里我们从无线接入网开始谈起。 什么是无线接入网? 首先大家看一下这个简化版的移动通信架构图: 无线接入网,也就是通常所说的RAN(Radio Access Network)。 简单地讲,就是把所有的手机终端,都接入到通信网络中的网络。 大家耳熟能详的基站(BaseStation),就是属于无线接入网(RAN)。 无线基站 虽然我们从1G开始,历经2G、3G,一路走到4G,号称是技术飞速演进,但整个通信网络的逻辑架构,一直都是:手机→接入网→承载网→核心网→承载网→接入网→手机。 通信过程的本质,就是编码解码、调制解调、加密解密。 要做的事情就这么多,各种设备各司其职,完成这些事情。 通信标准更新换代,无非是设备改个名字,或者挪个位置,功能本质并没有变化。 基站系统,乃至整个无线接入网系统,亦是如此。 一个基站,通常包括BBU(主要负责信号调制)、RRU(主要负责射频处理),馈线(连接RRU和天线),天线(主要负责线缆上导行波和空气中空间波之间的转换)。 基站的组成部分 在最早期的时候,BBU,RRU和供电单元等设备,是打包塞在一个柜子或一个机房里的。 基站一体化 后来,慢慢开始发生变化。 怎么变化呢?通信砖家们把它们拆分了。 首先,就是把RRU和BBU先给拆分了。 硬件上不再放在一起,RRU通常会挂在机房的墙上。 BBU有时候挂墙,不过大部分时候是在机柜里。 机柜里的BBU 再到后来,RRU不再放在室内,而是被搬到了天线的身边(所谓的“RRU拉远”),也就是分布式基站DBS3900,我们的余承东总裁当年在圣无线的时候就是负责这方面变革的专家,该产品一出解决了欧洲运营商的刚需,为打开欧洲市场立下了汗马功劳。 天线+RRU 这样,我们的RAN就变成了D-RAN,也就是Distributed RAN(分布式无线接入网)。 这样做有什么好处呢? 一方面,大大缩短了RRU和天线之间馈线的长度,可以减少信号损耗,也可以降低馈线的成本。 另一方面,可以让网络规划更加灵活。毕竟RRU加天线比较小,想怎么放,就怎么放。 说到这里,请大家注意:通信网络的发展演进,无非就是两个驱动力,一是为了更高的性能,二是为了更低的成本。 有时候成本比性能更加重要,如果一项技术需要花很多钱,但是带来的回报少于付出,它就很难获得广泛应用。 RAN的演进,一定程度上就是成本压力带来的结果。 在D-RAN的架构下,运营商仍然要承担非常巨大的成本。因为为了摆放BBU和相关的配套设备(电源、空调等),运营商还是需要租赁和建设很多的室内机房或方舱。 大量的机房=大量的成本 于是,运营商就想出了C-RAN这个解决方案。 C-RAN,意思是Centralized RAN,集中化无线接入网。这个C,不仅代表集中化,还代表了别的意思: 相比于D-RAN,C-RAN做得更绝。 除了RRU拉远之外,它把BBU全部都集中关押起来了。关在哪了?中心机房(CO,Central Office)。 这一大堆BBU,就变成一个BBU基带池。 C-RAN这样做,非常有效地解决了前文所说的成本问题。 可能在没有接触一线业务的时候,我们总以为设备运行后,运营商大量的前都用到了网络设备的维护中,但通过前期的勘测,我才了解到,运营商支持最大的成本不是通信设备维护,也不是雇佣维护人员,而是电费! 在整个移动通信网络中,基站的能耗占比大约是…… 72% 56% 传统方式机房的功耗分析 采用C-RAN之后,通过集中化的方式,可以极大减少基站机房数量,减少配套设备(特别是空调)的能耗。 若干小机房,都进了大机房 机房少了,租金就少了,维护费用也少了,人工费用也跟着减少了。这笔开支节省,对饱受经营压力之苦的运营商来说,简直是久旱逢甘霖。 另外,拉远之后的RRU搭配天线,可以安装在离用户更近距离的位置。距离近了,发射功率就低了。 低的发射功率意味着用户终端电池寿命的延长和无线接入网络功耗的降低。说白了,你手机会更省电,待机时间会更长,运营商那边也更省电、省钱! 更重要一点,除了运营商可以省钱之外,采用C-RAN也会带来很大的社会效益,减少大量的碳排放(CO2)。 此外,分散的BBU变成BBU基带池之后,更强大了,可以统一管理和调度,资源调配更加灵活! C-RAN下,基站实际上是“不见了”,所有的实体基站变成了虚拟基站。 所有的虚拟基站在BBU基带池中共享用户的数据收发、信道质量等信息。强化的协作关系,使得联合调度得以实现。小区之间的干扰,就变成了小区之间的协作(CoMP),大幅提高频谱使用效率,也提升了用户感知。 此外,BBU基带池既然都在CO(中心机房),那么,就可以对它们进行虚拟化了! 虚拟化,就是网元功能虚拟化(NFV)。简单来说,以前BBU是专门的硬件设备,非常昂贵,现在,找个x86服务器,装个虚拟机(VM,Virtual Machines),运行具备BBU功能的软件,然后就能当BBU用啦! 这样又可以帮客户节省好多的经费,不过这项技术短期内主要还是应用于核心网的网元中,前一段时间刷屏的亚马逊上销售的仅需每月90美元的核心网设备,就是利用这项核心技术。具体的我们留到后面再说,这里让我们继续聚焦于接入网。

第五章 API (第四次作业)

一.单选题(共38题,38.0分) 1已知 String 对象 s="abcdefg",则 s.substring(2, 5)的返回值为() A、"bcde"B、"cde"C、"cdef"D、"def" 正确答案: B 答案解析:字符串索引从0开始,substring()方法截取的字符串是包左不包右的。 2阅读下面的代码,输出结果是() public static void main(String[] args) { Random random1 = new Random(10); Random random2 = new Random(10); for(int i=0;i<5;i++){ System.out.print(random1.nextInt(5)); } System.out.println(); for(int i=0;i<5;i++){ System.out.print(random2.nextInt(5)); } } A、3030130301B、5048132680C、3268023579D、1111111111 正确答案: A 答案解析:当创建Random类的实例对象时,如果指定了相同的种子,则每个实例对象产生的随机数具有相同的序列,调用nextInt(int in)方法时产生的随机数在(0 =< 参数值)之间。 3StringBuffer类的append()方法的返回值类型是() A、StringB、voidC、StringBufferD、StringBuilder 正确答案: C 答案解析:StringBuffer类似一个字符容器,当在其中添加或删除字符时,并不会产生新的StringBuffer对象返回值类型还是StringBuffer类型。 4下列选项中,对Math.random()方法描述正确的是( ) A、返回一个不确定的整数B、返回0或是1C、返回一个随机的double类型数,该数大于等于0.0小于1.0D、返回一个随机的int类型数,该数大于等于0.0小于1.0 正确答案: C 答案解析:返回一个随机的double类型数,该数大于等于0.0小于1.0。 5下列选项中,可以正确实现String初始化的是() A、String str = "abc";B、String str = ‘abc’;C、String str = abc;D、String str = 0; 正确答案: A 6System类的getProperties()方法的作用是()

path.resolve()、path.resolve(__dirname)使用

path.resolve的用法整理 path.resolve参数__dirname 返回当前文件相对路径../ 返回上一级路径 path.resolve参数 传入参数开头是否有 / ,返回值有两种: 第一种: 返回绝对路径 path.resolve(‘src’) F:\个人学习项目\vue-dev\scripts\src 第二种: 返回相对路径 path.resolve(‘/src’) F:\src __dirname 返回当前文件相对路径 path.resolve()path.resolve(‘’)path.resolve(‘./’)path.resolve(__dirname) 这三个都返回当前文件的绝对路径 F:\个人学习项目\vue-dev\scripts …/ 返回上一级路径 path.resolve(__dirname, ‘…/’) F:\个人学习项目\vue-dev path.resolve(__dirname, ‘…/src’) F:\个人学习项目\vue-dev\src path.resolve(__dirname, ‘…/’, ‘src’) path.resolve(__dirname, ‘…/’, ‘examples’) F:\个人学习项目\vue-dev\src F:\个人学习项目\vue-dev\examples

CSS hack

连接:https://blog.csdn.net/freshlover/article/details/12132801

由于过多的连接错误而被 MySQL服务器 阻止

Caused by: com.mysql.cj.exceptions.CJException: null, message from server: "Host '10.105.***.**' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'" 这个错误可能表示当您尝试使用 IP 地址为 "10.105.***.**" 的主机建立连接到 MySQL 服务器时,该主机因为出现了太多的连接错误而被 MySQL 服务器自动阻止。这种情况通常是由于错误的密码、连续连接失败或其他网络问题所致。 要解决这个问题,您可以尝试以下几个步骤: 1. 尝试使用 `mysqladmin flush-hosts` 命令来清除 MySQL 服务器中关于该主机的连接错误记录,以允许该主机重新连接。 2. 核实使用的数据库用户名和密码是否正确,并检查该用户是否拥有连接到指定数据库的权限。 3. 检查网络连接是否存在问题,并确认客户端与 MySQL 服务器之间的网络连接是否稳定。 4. 修改应用程序代码并使用连接池等技术,以避免重复建立连接并最小化与 MySQL 服务器之间的连接错误。 在解决这个问题之后,建议保持正常连接一段时间以避免再次出现这种情况。 我使用的是方法1 命令执行方法如下:到你的mysql文件夹bin目录处cmd打开命令行 执行命令:mysqladmin -u root -p flush-hosts 接着输入root的密码 加大错误请求次数: 修改mysql配置文件,在[mysqld]下面添加 max_connect_errors=1000,然后重启mysql

树形数据展示 - 嵌套子表格

一、目标样式 父表格嵌套子表格,子表格默认折叠,点击父表格左侧加号可以展开父表格显示对应的子表格,展示每行数据更详细的信息 目标效果 二、问题样式 (一)问题说明 父表格展开后,子表格展示成功,但是子表格的数据以2种方式各渲染了一次,即:同一个子表格出现两次 问题展示 (二)问题原因 childrenColumnName 的默认值是 children ,所以当数据中的子数据是 children ,展开时会默认加载到子表格中,就会出现子表格重复渲染两次的问题 三、解决办法 将树形结构数据中的 children 改成其它名字,如:改成 childrens 四、代码示例: 1、 html部分 <a-table :columns="acList.columns" :data-source="acList.dataSource" class="tables" :pagination="false" :rowKey="(record) => record.id" :loading="acList.loading" > // 嵌套子表格 <template #expandedRowRender="{ record }"> <a-table :columns="acList.columns2" :data-source="record.childrens" :pagination="false" :rowKey="(record) => record.id" > </a-table> </template> </a-table> 嵌套表格相关参数 嵌套表格可用参数及说明 2、 js部分 vue3定义相关数据 //表格所需数据 const acList = reactive({ // 父表格和子表格所需数据 dataSource: [ { "id": 5, "batch": "1", "state": 1, "

网络中的四元组、五元组、七元组

四元组:源IP地址(sip)、目的IP地址(dip)、源端口(sport)、目的端口(dport) 五元组:源IP地址、目的IP地址、协议号(Protocol )、源端口、目的端口 七元组:源IP地址、目的IP地址、协议号、源端口、目的端口,服务类型以及接口索引

JavaScript处理鼠标各个事件的示例代码、说明和案例

当使用JavaScript处理鼠标事件时,可以配合HTML代码来说明每个事件的使用方法、作用以及常见使用案例。 click(点击事件):当鼠标点击某个元素时触发。 <button id="myButton">点击我</button> <script> var button = document.getElementById('myButton'); button.addEventListener('click', function(event) { // 处理点击事件 alert('按钮被点击了'); }); </script> 作用:当按钮被点击时,弹出一个提示框显示"按钮被点击了"。 常见使用案例:在网页中创建一个按钮,当用户点击按钮时触发相应的操作,例如提交表单、打开弹窗等。 mouseover(鼠标移入事件):当鼠标移动到元素上方时触发。 <div id="myDiv">将鼠标移入此处</div> <script> var div = document.getElementById('myDiv'); div.addEventListener('mouseover', function(event) { // 处理鼠标移入事件 div.style.backgroundColor = 'red'; }); </script> 作用:当鼠标移入<div>元素时,将元素的背景色改为红色。 常见使用案例:在网页中的导航菜单上,当用户将鼠标移动到菜单项上方时,改变菜单项的样式以提供视觉反馈。 mouseout(鼠标移出事件):当鼠标从元素上方移出时触发。 <div id="myDiv">将鼠标移出此处</div> <script> var div = document.getElementById('myDiv'); div.addEventListener('mouseout', function(event) { // 处理鼠标移出事件 div.style.backgroundColor = 'white'; }); </script> 作用:当鼠标从<div>元素上移出时,将元素的背景色恢复为白色。 常见使用案例:在网页中的图片上,当用户将鼠标移出图片区域时,恢复图片的原始样式或显示其他相关信息。 mousemove(鼠标移动事件):当鼠标在元素内移动时触发。 <div id="myDiv">在此处移动鼠标</div> <script> var div = document.getElementById('myDiv'); div.addEventListener('mousemove', function(event) { // 处理鼠标移动事件 console.

Java中的Replace和ReplaceAll的区别

replace和replaceAll是都是String类中提供的两种用于字符/字符串替换的方法,从字面意思理解,replace表示替换单个匹配项,而replaceAll表示替换所有匹配项;实际上并不是这样子的,replace和replaceAll都是替换所有匹配项,replace是非正则模式替换,replaceAll是正则模式替换。 String类中一共提供了四种替换字符/字符串相关的方法,分别是replace的两个重载方法、replaceAll方法和replaceFirst方法 replace(字符):全部匹配的都替换;参数为字符(char)类型;不调用Pattern和Matcher方法。 replace(字串接口实现类):全部匹配的都替换;参数为字串接口实现类(如String);不支持正则匹配,调用Pattern(不匹配正则模式)和Matcher的replaceAll方法。 replaceAll:全部匹配的都替换,参数为String类型,支持正则匹配;调用Pattern(匹配正则模式)和Matcher的replaceAll方法。 replaceFirst:第一个匹配到的替换,参数为String类型,支持正则匹配;调用Pattern(匹配正则模式)和Matcher的replaceFirst方法。 主要相关的类主要有String、Pattern、Matcher 对应的调用关系图: 使用replaceAll和replaceFirst方法需要注意,参数要为正确的正则表达式,如果不正确会导致替换失败甚至报错。 比如下面的代码: String b = "这才是进度款发动机(ssdc)"; String regexp = "这才是进度款发动机ssdc)"; String vb = b.replaceAll(regexp, "AA"); System.out.println(vb); 执行的时候会提示: java.util.regex.PatternSyntaxException: Unmatched closing ')' near index 12 提示我们正则表达式有误,没有正确的使用')'进行关闭。所以使用replaceAll和replaceFirst是需要注意自己的正则表达式有没有写对的,特别是regexp是用户输入的时候,如果包含正则表达式的特殊符号,很容易报错。

使用nsenter检查docker网络

文章目录 一 环境准备二 需求三 解决 一 环境准备 虚拟机IP:10.0.0.100 拉取的三个镜像,镜像名称与ID如下: [root@canway01 ~]# docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/nginx latest f9c14fe76d50 2 hours ago 143 MB docker.io/centos 6.9 2199b8eb8390 4 years ago 195 MB docker.io/google/cadvisor latest eb1210707573 4 years ago 69.6 MB 运行以下命令,交互式启动容器: docker container run -it 2199b8eb8390 检查容器状态: [root@canway01 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 354fd8ba2770 2199b8eb8390 "/bin/bash" 33 minutes ago Up 33 minutes suspicious_yalow 镜像为centos:6.

Python入门到进阶,这9本书让你脱胎换骨(Python必看书籍)!!!

为了让更多想通过看书来学习Python的人能够把时间花在刀刃上,我总结了Python目前所有热门方向上我个人觉得性价比很高、值得一看的书籍,今天来分享给大家,希望对大家有帮助呀! 一、入门扫盲 1.看漫画学Python 有趣、有料、好玩、好用 这本书只要会电脑开关机就能看懂,适合激发对Python的兴趣。 主要通过三个漫画人物的简单对话,把复杂的问题进行通俗易懂的解释。 2.Python编程—从入门到实践 针对所有层次的Python读者的佳作,无论是初学者还是想进阶,都能学到东西。 帮助小白快速掌握Python基础知识,编写出能解决实际问题的代码。 3.Excel+Python飞速搞定数据分析 本书作者是流行开源Python库xlwings的创始人 是为Excel用户准备的一本内容丰富又简明扼要的Python入门指南。 4.Python编程快速上手 这本书不仅是介绍Python语言的基础知识 还通过项目实践教会读者如何应用这些知识和技能。 5.Python编程初学者指南 本书主要是通过轻松有趣的方式来学Python 通过编写好玩的小软件来学习编程,所有的概念和术语都在一个个游戏制作中讲解,对初学者很友好 二.进阶入行 1.流畅的Python 这本书阐述全面且包含大量实战技巧,探讨了Python语言的高级用法,同层次的开发者可以通 过对这些特性的学习更好地理解自己地程序,从而写出更优质地代码。 2.利用Python进行数据分析 数据分析入门必读书籍。 书里详细介绍了利用Pytho进行操作、处理、清洗和整理数据等方面的基本要点和具体细节,还有大量的实践案例。 3.“笨办法”学Python3:进阶篇 本书旨在帮助读者从单纯地编写能运行地代码,跨越到能编写能解决实际问题的高质量Python代码,成为一名高阶Python程序员。 4.Python核心编程 Python开发者的完全指南,真入门了再看,讲解了Python的一些通用应用。 这九本Python书电子版已经打包到一个📂里,拿出来就能学,非常方便,无偿分享给各位正在学习Python的小伙伴,记得留言领取哦!

C语言基础 --使用自定义函数,交换两个变量的值

一、思路解析 我们再做这个题目之前,需要先知道c语言交换两个变量的值的原理: 1.首先我们要清楚在C语言中=是一个赋值运算符,所以我们不能直接用a=b,b=a 2.了解完上述情况,我们就能够知道要将两个值进行交换,单只有两个变量是行不通的,所以我们要设置第三个变量来做‘场外援助’,所以我们可以额外重新声明一个c的变量,当c=a ,a=b,b=c,此时a,b两者的值就已经被交换了。当c=a的时候a和c的值都为a,a=b的时候a就为b的值了,最后再让b=c,而c第一步已经被a赋值了,所以b就成为了a的值 如下图: ​ 二、方法实现 了解了上述原理我们通常会如下例所示去定义一个函数,但其实这是不对的!这样并不能实现数据的交换,原因有两点: 1.我们在先执行main方法时定义的a,b两个变量已经有了各自独立的空间和地址 2.执行swap函数,里面又分配了两个空间,分别是x,y,swap函数里面的x与又是独立的两个 空间,跟main函数里面的a,b两者是不同的。所以x,y在swap函数里面进行交换并不会影响 main函数里面a,b的结果。 #include<stdio.h> #include<stdlib.h> void swap(int x,int y){ int temp = x; x=y; y=temp; } int main(){ int a = 10; int b = 20; printf("交换之前:a=%d b=%d\n",a,b); swap(a,b); printf("交换之后:a=%d b=%d\n",a,b); return 0; } 正确写法: 在调用函数传值时加上取地址符(&),并在swap函数中的x,y前加入指针符号(*),这样就可以把main方法中的a,b的地址传递到函数中,之后swap函数就可以通过指针找到main方法中的a,b进而改变a,b的值 #include<stdio.h> #include<stdlib.h> void swap(int *x,int *y){ int temp = *x; *x=*y; *y=temp; } int main(){ int a = 10; int b = 20; printf("

Mesh写入GLTF(学习记录)

目录 1.GLTF::BUffer* buffer=asset->packAccessors()什么意思? 2.unsigned char*啥意思? 3.bufferData=(unsigned char*)realloc(bufferData,1000+2000)什么意思? 4.GLTF::BufferView* bufferView=new GLTF::BufferView(byteOffset,image->byteLength,buffer);什么意思? 5.std::memcpy(bufferData+byteOffset,image->data,image->byteLength)什么意思 ? 6.rapidjson::StringBuffer s;什么意思? 7.int jsonPadding=(4-(jsonString.length()&3))&3什么意思? 8.reinterpret_cast(writeHeader)什么意思? 9.std::clock_t start=std::clock()和std::clock_t end=std::clock()什么意思 ? 10.stream.seekp(std::streampos(8)) 什么意思? 这边主要是阅读源码出现的一些代码问题,源码可不敢放 1.GLTF::BUffer* buffer=asset->packAccessors()什么意思? asset->packAccessors()是对 GLTF(glTF)资源中的访问器(Accessor)进行打包的操作。 在 glTF 中,访问器用于描述和访问缓冲区(Buffer)中的数据。访问器可以指定数据的类型、组件类型、数量以及在缓冲区中的偏移量等信息。而缓冲区则存储着实际的二进制数据,例如顶点坐标、法线、纹理坐标等。 2.unsigned char*啥意思? `unsigned char*` 是 C/C++ 语言中的数据类型,表示一个指向无符号字符(unsigned char)的指针。 无符号字符(unsigned char)是一种数据类型,用于表示 0 到 255 之间的整数值。它是一个占用 1 个字节的数据类型,通常用来表示字节(byte)数据。 指针(pointer)是用来存储内存地址的变量。通过指针,我们可以访问或操作该地址上存储的数据。 因此,`unsigned char*` 表示一个指向无符号字符数据的指针。可以使用该指针来访问、读取或修改内存中存储的无符号字符数据。 例如,下面是一个示例代码片段,演示如何声明一个 `unsigned char*` 类型的指针,并使用它访问内存中的数据: ``` unsigned char* ptr; // 声明一个 unsigned char* 类型的指针 unsigned char value = 42;

kali 单元07 渗透攻击

目录 本章节是基于漏洞工具Metasploit做的 渗透环境 7.1 Metasploit的基础 7.3 使用Metasploit对操作系统发起攻击 7.4 使用Metasploit对软件发起攻击 7.5使用Metasploit对客户端发起攻击 7.5.1 使用Metersploit对客户端发起攻击 7.5.2 利用HTA文件进行渗透攻击 7.5.3 使用宏病毒进行渗透攻击 7.5.4 使用browser_autopwn2模块进行渗透攻击 本章节是基于漏洞工具Metasploit做的 该文章只提供学习,禁止做违法的事情,任何后果与作者无关 1. 依据《刑法修正案(七)》第9条增的《刑法》第 285条第3款的规定,犯提供非法侵入或者控制计算机信息系罪的,处3年以下有期徒刑或者拘役,并处或者单处罚金;情节特别严重的,处3年以上7年以下有期徒刑,并处罚金。 2.第二百八十五条第二款 违反国家规定,侵入前款规定以外的计算机信息系统或者采用其他技术手段,获取该计算机信息系统中存储、处理或者传输的数据,或者对该计算机信息系统实施非法控制,情节严重的,处三年以下有期徒刑或者拘役,并处或者单处罚金;情节特别严重的,处三年以上七年以下有期徒刑,并处罚金。 3.刑法第二百五十三条之一:“国家机关或者金融、电信、交通、教育、医疗等单位的工作人员,违反国家规定,将本单位在履行职责或者提供服务过程中获得的公民个人信息,出售或者非法提供给他人,情节严重的,处三年以下有期徒刑或者拘役,并处或者单处罚金。情节特别严重的,处三年以上七年以下有期徒刑,并处罚金。 渗透环境 使用Kali Linux2022.1进行演示操作 目标靶机:靶机(Windows7 64位 永恒之蓝);靶机(32位Windows 7,安装了Easy File Sharing HTTP Server) 软件:Msfvenom、Msfconsole(Kali Linux系统内置) 7.1 Metasploit的基础 1、Metasploit启动的三种方法: (1)菜单 (2)工具栏 (3)命令行 2、Metasploit的常用模块: (1)exploit(漏洞渗透模块) (2)payload(攻击载荷模块) (3)auxiliary(辅助模块) (4)post(后渗透攻击模块) 3、帮助help 4、命令几个种类: (1)核心命令core command (2)模块命令module command (3)任务命令job command (4)资源命令resource script command (5)数据库后台命令database backed command (6)登录凭证后台命令credentials backed command 7.2 Metasploit的基本命令

二进制安装1.26版本k8s(docker)

文章目录 前言准备工作准备4台虚拟机说明下载对应的二进制包初始化操作CentOS7配置yum源配置免密、修改hostname、关闭防火墙、selinux、关闭swap分区(方便后面进行其它操作)下载软件包并批量安装配置时间同步配置打开文件描述符添加ipvs模块和内核模块 Ubuntu配置apt源配置免密、修改hostname、关闭防火墙、关闭swap分区(方便后面进行其它操作)下载软件包并批量安装配置时间同步配置打开文件描述符添加ipvs模块和内核模块 编译一个nginx做负载均衡安装容器运行时安装docker安装cri-docker 安装etcd准备etcd所需证书分发证书、二进制文件及service文件 安装k8s组件apiserver准备apiserver 证书准备metrics-server证书准备service文件分发apiserver文件并启动 kubectl准备admin证书创建kubeconfig创建 clusterrolebinding 实现 exec 进入容器权限 controller-manager准备controller-manager 证书创建kubeconfig准备service文件分发controller-manager文件并启动 scheduler准备scheduler证书创建kubeconfig准备service文件分发scheduler文件并启动 检查管理组件需要的服务是否正常kubelet准备kubelet证书创建kubeconfig准备kubelet配置文件准备service文件分发kubelet文件并启动 kube-proxy准备kube-proxy证书创建kubeconfig创建kube-proxy配置文件准备service文件分发kube-proxy文件并启动 检查是否起来 安装网络插件cni插件coredns 验证集群是否正常后记 前言 v1.24.0 - v1.26.0 之前支持docker,但是需要额外安装cri-docker来充当垫片由于工作原因作者会同时使用Ubuntu和CentOS,因此本次将两个系统的K8S安装一起记录一下(与CentOS7.9、Ubuntu2004验证)证书采用cfssl工具制作使用二进制方式部署3主1从高可用集群etcd采用二进制部署,复用3个管理节点本次还是选择docker,containerd很多命令不习惯,而且不能直接构建dockerfile本次环境为私有云环境,默认情况无法使用keepalived,因此本次部署无vip,采用nginx做负载均衡(各位可自行使用keepalived+haproxy做vip来进行负载均衡) 理想拓扑图如下 准备工作 准备4台虚拟机 虚拟机建议同时使用相同操作系统并配置好正确的IP地址 # centos7网卡配置文件位置: /etc/sysconfig/network-scripts/ifcfg-eth0 或 ens33等,vim编辑完成之后重启network服务即可 # ubuntu2004网卡配置文件位置:/etc/netplan/50-cloud-init.yaml 一般是xxx.yaml文件,配置完成之后 netplan apply 生效即可 # centos8 无network服务,且centos7/8或者Ubuntu2004/2204都可以直接使用 NetworkManager服务来管理网络,可以使用nmtui类图形界面配置,也可以直接 nmcli 命令行配置 IP地址角色10.10.21.223master/worker10.10.21.224master/worker10.10.21.225master/worker10.10.21.226worker 说明 如无特殊说明,以下操作均在第一个节点进行 如果需要完全按官方给的各个软件推荐版本的话,可以先下载一个对应的kubeadm,然后命令查看镜像版本,再去下载对应版本,我这边就直接很多都给上新了 # 例如 [root@node1 ~]# kubeadm config images list W0523 17:58:43.225920 28717 version.go:104] could not fetch a Kubernetes version from the internet: unable to get URL "

SpringBoot 插件 spring-boot-maven-plugin 原理,以及SpringBoo工程部署的 jar 包瘦身实战

spring-boot-maven-plugin 我们直接使用 maven package (maven自带的package打包功能),打包Jar包的时候,不会将该项目所依赖的Jar包一起打进去,在使用java -jar命令启动项目时会报错,项目无法正常启动。这个时候,我们就可以考虑引用spring-boot-maven-plugin插件来为项目打Jar包。 maven项目的pom.xml中,添加了下述插件,当运行 maven package 进行打包时,会打包成一个可以直接运行的JAR(fat jar)文件,使用 java -jar 命令就可以直接运行。 注意:如果你的项目没有继承spring-boot-starter-parent 这个POM,你需要做如下配置,将目标绑定到repackage。 <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build> 默认情况下maven项目的打包命令,在打Jar包时不会把依赖的jar包也打包进去,但是spring-boot-maven-plugin插件,会将依赖的jar包全部打包进去。例如下面这个使用spring-boot-maven-plugin插件打包生成的jar包的BOOT/INF/lib目录下面就包含了所有依赖的jar包: 引入了spring-boot-maven-plugin插件后,在使用打包功能时会将mvn package 生成的 jar或者war 重新打包成可执行文件,同时修改原文件名,增加.origin 后缀。 可执行 Jar 包内部结构 将打出来的可执行 Jar 解压开我们能看到下面的结构: 可执行 jar 目录结构 ├─BOOT-INF │ ├─classes │ └─lib ├─META-INF │ ├─maven │ ├─app.properties │ ├─MANIFEST.MF └─org └─springframework └─boot └─loader ├─archive ├─data ├─jar └─util 结构对比 从上面的文件结构和 jar 清单内容来看,Spring Boot 打包后的 fatjar 对比 源 jar 主要有以下差异:

阿里云免费ssl证书申请与部署

一、证书申请 1、找到 ssl 证书 2、点击选择SSL 证书 进入其管理控台 3、如果你还没有免费证书,选择购买即可,一个自然年内每个账号可以领取一次数量为20的免费单域名试用证书额度,我的已经购买过来,今年的,所以无法再次购买 4、点击创建证书 5、创建之后,列表出现一个带申请的证书,我们点击证书申请按钮,进行我们相关的网站配置 6、进行生成 7、点击提交审核之后,会提示你如下信息 8、可以发现填写申请已经结束了,接下来就验证信息步骤,我们按照图示步骤进行即可 二、配置证书对应的域名 1、登录域名管理控制台,点击你选择使用https的域名 2、在域名控制台添加DNS解析记录 注意如果下面的记录里面已经有了,就无需填写了,我的就是,因为我的域名和服务器都是阿里云的,它已经帮我把记录给自动填写生成好了。 3、对应的几个选项值就是前面第二步骤出现的内容,一一copy过去即可 4、添加完成之后,对应的域名下面的列表就会出现一行记录 注意如果下面的记录里面已经有了,就无需上面的手动填写了,我的就是,因为我的域名和服务器都是阿里云的,它已经帮我把记录给自动填写生成好了。 5、点击验证,如果验证是成功,就没必要再点击验证了,就像前面所说的,如果都是阿里云的,它会帮你做好的 6、以上我们的申请就完成了,可以看到证书已经签发了,所以我们接下来就要将这个证书部署到对应域名的服务器上面即可. 三、将证书部署到对应域名下的服务器上 1、点击下载,就会出现各个部署方式 2、因为我的服务都是基于nginx的,所以我直接使用nginx的方式部署即可,也可以点击右侧的帮助按钮,阿里云提供了很多对应的部署文档,比较的详细,大家也可以参考参考。 建议去查看,还是不错的,几乎是一步一步的教我们。 如果你是docker 记得把 443 端口也暴露出来 3、如果你的网站 还没有备案,那么你通过 https + 域名 访问,是无法访问的,如下 这里使用以下别人回复,虽然是腾讯云的,但是原理都一样 原文地址 困扰我两天的问题(nginx配置好ssl证书,https却不能访问) 4、但是没有备案,http + 域名也是可以访问的,但是会被拦截 4、但是你如果你用ip就可以 5、这里贴一份 完整的配置,其实就是阿里云文档上面的 server { #配置HTTPS的默认访问端口为443。 #如果未在此处配置HTTPS的默认访问端口,可能会造成Nginx无法启动。 #如果您使用Nginx 1.15.0及以上版本,请使用listen 443 ssl代替listen 443和ssl on。 listen 443 ssl; #填写证书绑定的域名 server_name wh.51job.cn; #填写证书文件名称 ssl_certificate /etc/nginx/conf.d/cert/10156555_wh.51job.cn.pem; #填写证书私钥文件名称 ssl_certificate_key /etc/nginx/conf.d/cert/10156555_wh.51job.cn.key; ssl_session_timeout 5m; #表示使用的加密套件的类型 ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!

这可能是最全面的Java学习路线了

大家好,我是大彬~ 我本科学的不是计算机,大四开始自学Java,并且拿到了几个互联网中大厂的offer。在学习Java这方面还是比较有经验的,下面我来分享下我整理的Java自学路线。 在这里也提醒学弟学妹们,要尽早确定以后的方向,读研还是工作,找工作的话,也要尽快确定工作岗位,想转行的,需要花更多的时间准备。很多同学到了大四快毕业的时候,才思考自己未来要做什么,这个时候已经有点晚了。如果错过了校招,走社招渠道去找工作,难度将会提升一个等级,到时后悔也来不及! 下面来说说自己的经历吧(附自学路线)。 接触编程 大学以前基本没碰过电脑,家里没电脑,也没去过网吧。高中的计算机课程,期末作业要完成一个自我介绍的PPT,也不会做,最后直接抄同桌的作业(复制粘贴都不会。。还得同桌教,捂脸)。 高考完一个月后,买了电脑,真正开始使用上了电脑。 大一上学期的时候,系里开了一门C语言的课程,这也是我第一次接触编程。教材是英文的,刚开始学还是挺头大的。每次课程作业,周围的同学都是一顿复制粘贴,我也一样嘿嘿。 记得在讲指针那一章的时候,听的一头雾水。稍微走神,回过头来,已经不知道讲的是啥了。 后面系里开设了兴趣小组,因为平时比较闲,也想着去捣鼓点东西,就去参加了。刚开始的时候,什么都不懂,老师推荐我学一下51单片机,拿了一本厚厚的51单片机的书籍,跟着书里的demo敲了一遍,发现了新天地!原来编程这么有意思! 记得第一次跑出流水灯的时候,那叫一个激动啊,满满的都是成就感!后面也写了一些电机、红外遥控等demo。从那以后,激发了我学习编程的兴趣。 到了大二,辅导员在群里发布全国电子设计大赛的信息,参赛题跟四轴飞行器相关,那段时间对四轴飞行器比较感兴趣,于是约了两个小伙伴一块参加。距离比赛时间只有一个月,在那一个月的时间里,每天都是早出晚归,吃饭的时候还在想着哪一块代码出了bug。虽然最后没能获奖,但是在这个过程中,学到很多知识,编程能力也有了很大的提升。 决定转码 转眼间,大三开学,开始纠结考研还是工作,思考了一周时间,也进了系里的实验室体验了一把研究生生活,最后还是听从内心的想法,决定直接找工作。 我咨询了本专业的师兄师姐们往年的就业情况,他们大部分人还是找了互联网方向的工作。有一个在传统行业的师兄,也劝我投互联网公司的岗位,因为在传统行业加班也不少,但是工资贼低。。最后决定转行程序员,找后端相关的工作。 那么学习哪一种语言呢?当时有三个选择:c++,Java,python。 那段时间python比较火,但是经过一番深思熟虑之后,还是选择了Java。为什么选择Java呢? 很简单,市场需求大,学习难度适中。相比科班同学来说,我缺乏系统的计算机基础知识,而距离秋招也只有不到一年时间,所以还是选择学习难度低一点的Java。 闭关自学 确定方向后,便开始制定学习路线。不得不说,Java要学的东西是真的多。。 自学期间遇到挺多问题,比如一些环境配置问题,有时候搞上好几天,很打击积极性。中途也有很多次怀疑自己的水平,是不是不适合干编程,差点就放弃了。幸好最后还是坚持了下来。 半年多的时间,除了平时上课,其他时间就是在图书馆。周末或者节假日,每天都是7点起床,八点到图书馆开始学习,到了晚上十点,图书馆闭馆,才回宿舍,每天都是图书馆最后走的一批。回到宿舍,洗完澡,继续肝到十二点多(卷王!)。 很多人在问,大三才开始自学Java,来的及吗? 我觉得,还是看个人的投入程度和学习能力。有些人自学能力强一点,每天可以投入10小时及以上的时间去学习,那完全没问题。 自学过程还是挺辛苦的,要耐得住寂寞,最最重要的还是得坚持! 我根据自己的自学经历,整理了一些学习过程中踩坑总结的经验,希望自学的小伙伴可以少走弯路: 注重实践,不要只是埋头看书,一定要多动手写代码。刚开始自学的时候,可以不用太深究细节,不然可能会怀疑自己的学习能力。等到后面有了一定的基础,回过头来重新回顾,可能会恍然大悟,没有当初想的那么难。可以适当加一些交流群,遇到不懂的知识点,多与其他人交流。 好了,下面给大家分享一下我的自学经验。 自学路线 首先看一下Java学习路线图: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p10iwXFS-1684976576805)(http://img.topjavaer.cn/image/Java学习路线-gitmind-清晰.png)] 在这里也给大家分享一份精心整理的大厂高频面试题PDF,小伙伴靠着这份手册拿过阿里offer,需要的小伙伴可以自行下载: http://mp.weixin.qq.com/s?__biz=Mzg2OTY1NzY0MQ==&mid=2247485445&idx=1&sn=1c6e224b9bb3da457f5ee03894493dbc&chksm=ce98f543f9ef7c55325e3bf336607a370935a6c78dbb68cf86e59f5d68f4c51d175365a189f8#rd Java 推荐书籍: 《head first java》《JAVA核心技术卷》 head first系列的书籍讲解比较有趣,比较好理解。《JAVA核心技术卷》难度相对适中,内容也比较全面,部分章节(如Swing)可以跳过。 视频推荐动力节点老杜的视频教程,1000w的播放量!视频总体上质量很不错,讲解挺详细,适合新手。跟着老杜的视频学下来,可以学到很多知识! 再次强调:多敲代码!多敲代码!多敲代码! 学习编程就是看书加实践,要多动手,不然看过的知识点很快就会忘,而且多实践也会遇到很多坑,丰富经验。 可以到github上找一些项目练练手,通过做项目巩固知识,而且每实现一个功能之后,会有满满的成就感,也会激励你不断去学习。 Java基础知识主要有: 面向对象特性 Java语言基础、循环、数组 ; 了解类和对象 掌握强制数据类型转换和自动类型提升规则;常量如何声明及赋值;循环的语法及作用;数组的声明及定义;掌握类的概念以及什么是对象。 抽象类和接口 数据类型、重写重载、封装继承多态 容器类Map/List/Set等 异常处理 反射机制 泛型 常用类:String、时间类 函数式编程 Stream API Lambda 表达式 IO流操作,多线程及Socket 掌握IO读写流相关的类,了解字节流,字符流和字符流缓冲区;掌握线程的概念,多线程的创建、启动方式,锁和同步的概念及运用;掌握Socket通信的概念,如何声明客户端服务端,如何完成双端数据通信。 Java Web Java Web是一系列技术的综合,也是大多数Java开发者的技术方向。有必要学习一下。这部分可以看看视频教程。 视频推荐尚硅谷的JavaWeb全套教程,HTML/CSS/JavaScript等跟前端相关的可以倍速观看。

用fastadmin开发一个插件的基本步骤

以下是使用FastAdmin框架开发一个插件的基本步骤: 安装FastAdmin 首先,你需要安装FastAdmin框架,可以在FastAdmin的官方网站上下载最新版,也可以使用composer进行安装。 创建插件项目 在FastAdmin的项目根目录下,使用命令行创建一个插件项目: php think fastadmin:plugin your-plugin-name 请将 “your-plugin-name” 替换为你的插件名称。 此命令将创建一个名为 “your-plugin-name” 的目录,其中包含插件基本的文件结构和目录。 修改插件配置 修改项目根目录下的 config.php 文件,设置插件名称和主类路径: return [ 'name' => 'Your Plugin Name', 'path' => 'your-plugin-name', 'version' => '1.0.0', 'description' => 'Your plugin description', 'author' => 'Your name', 'default_enable' => 0, 'services' => [ 'your_plugin_name' => \app\your_plugin_name\Service::class, ], ]; 请将 “Your Plugin Name”、“your-plugin-name”、“Your plugin description”、“Your name” 和 “\app\your_plugin_name\Service::class” 替换为你的插件名称、路径、描述、作者和主类路径。 创建控制器 在插件目录下创建一个名为 “controller” 的目录,在此目录下创建一个名为 “Index.php” 的控制器: <?php namespace app\your_plugin_name\controller; class Index { public function index() { return 'Hello, World!

python中assert的使用

文章目录 python中assert的作用 python中assert的作用 之前一直是在框架中使用assert今天才发现了自己的肤浅,mark一下; 在python程序中使用assert是一个非常好的习惯,程序未完善之前不让它在运行到最后崩溃,这时候就需要我们的assert的帮助了。 assert主要用于程序调试 #语法 assert expression assert 1==2 #拓展使用 assert expression [, arguments] assert 表达式 [, 参数] assert 1==2,"报错" 断言失败后会进行后面的报错 PS:这里的assert后续的表达式其实就是一个布尔类型,所以也可以跟单独的字符串,以及空字符串等类型,类似我们的if后面的表达式用法

使用Java来实现统计单词出现的次数两种方法

public class Numberofwords { public static void main(String[] args) { String str = "Hello World abc Hello hello"; // 截取字符串 第一个包含的 第二个不包含 Numberofwords test = new Numberofwords(); int count = test.wordCount(str,"hello"); System.out.println(count); // String str ="hello hello wrod wrod wrod wrod wrod wrod hello"; // String str1 = "hello"; // String replace = str.replace(str1, ""); // int replaceTest = str.length() - replace.length(); // int count = replaceTest / str1.length(); // System.

分析| Flutter 3.10版本有哪些变化?

Flutter是Google推出的一款用于构建高性能、高保真度移动应用程序、Web和桌面应用程序的开源UI工具包。Flutter使用自己的渲染引擎绘制UI,为用户提供更快的性能和更好的体验。Flutter还提供了丰富的构建工具、库和插件,使开发人员能够更快地构建应用程序。 今天就为大家带来Flutter 3.10版本的变化分析。 1、Dart 3 众所周知,Flutter是建立在Dart语言基础上的,本次大会上,Dart发布了一个大的版本,这是编程语言的重大更新。 (Flutter 的安装说明可在docs.dev.flutter找到,Dart SDK 的安装说明可在dart.dev找到。)Dart 3现在作为稳定版本提供,包含以下三项主要改进: 100% 可靠的 null 安全性,它避免了 null 的运行时错误,提供更小的编译输出,并提高了性能。目前,Dart开发包管理器上的 1,000 个包中有 99%支持空安全。 新语言功能支持具有记录、解构和模式匹配的结构化数据,以及用于现代编程的抽象数据类型。 类修饰符,一种“高级用户”功能,使包所有者能够更好地表达 API 的功能。 Dart 的构建者也一直致力于将 Dart 编译为 Wasm 二进制格式,目标是在浏览器中带来更快的加载速度并提高 Web 应用程序的性能。Dart 到Wasm 的编译现在正在预览中。要编译为 Wasm,开发人员需要支持WasmGC 的浏览器。 2、Material 3 widget Flutter 3.10改进了对 Material 3 widget 工具包的支持,包括对 Material 3 算法配色方案生成的支持,以及一些使构建 macOS 和 iOS 应用程序更容易的改进。后者包括在可编辑文本小部件中添加拼写检查支持、一个新的复选框小部件以及对无线调试的支持。Impeller 渲染器从 Flutter 3.7 开始预览,现在是 iOS 上的默认渲染器,承诺更少的卡顿和更一致的性能。 Flutter 3.10 中还有一个 JNI 桥接器,用于连接用Kotlin编写的 Jetpack 库,无需外部插件即可直接从 Dart 调用新的 Jetpack 库。

web功能测试方法大全—完整!全面!(纯干货,建议收藏哦~)

本文通过六个部分为大家梳理了web功能测试过程中,容易出现的遗漏的部分,用以发掘自己工作中的疏漏。(纯干货,建议收藏哦~) 一、输入框 1、字符型输入框 2、数值型输入框 3、日期型输入框 4、信息重复 在一些需要命名,且名字应该唯一信息输入的,需要关注重复的名字或ID,查看系统有没有处理,会否报错。重名包括:是否区分大小写,以及在输入内容的前后输入空格,系统是否作出正确处理。 二、搜索功能 若查询条件为输入框,则参考输入框对应类型的测试方法。 1、功能实现 2、组合测试 三、添加、修改功能 1、特殊键 (1)是否支持Tab键; (2)是否支持回车键。 2、提示信息 不符合要求的地方是否有错误提示? 3、唯一性 (1)字段唯一的,是否可以重复添加; (2)添加后,是否能修改为已存在的字段(字段包括区分大小写以及在输入的内容前后输入空格,保存后,数据是否真的插入到数据库中,注意保存后数据的正确性)。 4、数据正确性 四、删除功能 1、特殊键 (1)是否支持Tab键; (2)是否支持回车键。 2、提示信息 (1)不选择任何信息,直接点击删除按钮,是否有提示; (2)删除某条信息时,应该有确认提示。 3、数据实现 五、注册、登陆模块 六、链接测试 2、图形测试 通常来说,使用少许或尽量不使用背景是个不错的选择。如果您想用背景,那么最好使用单色的,和导航条一起放在页面的左边。另外,图案和图片可能会转移用户的注意力。 最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走: 这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!有需要的小伙伴可以点击下方小卡片领取 

俄罗斯方块 CCF 201604-2

做的一些题目代码:https://gitee.com/mapf0/test_CCF-CSP.git 题目链接:http://118.190.20.162/view.page?gpid=T41 做了不少题目了,感觉考的是阅读理解 结果 题目 代码 /** * 俄罗斯方块 * * 100 * ^ * / \ * | * 之前判断完重合边界,又从重合边界循环比较 * 修改:边界确认后直接复制板块到方格图中 * * 80 * ^ * / \ * | * 没有判断:当板块中某一个方块的下边缘与方格图上的方块上边缘重合或者达到下边界时,板块不再移动 * 对策:添加了从上向下移动,40 -> 80 * * 40 * ^ * / \ * | * * 板块最下面一行为0是,可以忽略 * 对策:将板块中的图像(1)按行下移 20->40 * * 20 * * */ #include<stdio.h> #include<math.h> #include<string.h> #include<algorithm> using namespace std; int main() { int a[16][11] = {0}; int b[5][5] = {0}; int left; for(int i = 15; i >= 1; i--) { for(int j = 1; j <= 10 ; j++) { scanf("

基于JavaWeb开发的销售商城系统(手机销售,笔记本电脑销售,书籍等通用版销售系统)大学生毕设通用程序销售管理系统

基于JavaWeb开发的销售商城系统,大学生毕设通用程序销售管理系统 重点:不需要修改代码实现各种销售商城系统 简介: 这是一个基于JavaWeb开发的通用商城系统,即使没有编程经验也能轻松使用。通过后台管理系统,您可以根据自己的网站需求轻松修改内容,使其适用于不同类型的销售网站。 优点: 各类产品通用版销售商城网站 (举一个简单的例子:假如你要将网站改成书籍销售系统,你只需要到后台修改类容为书籍的类容它就变成啦一个书籍类销售网站系统 假如你的题目是电子产品,那你只需要到后台将类容修改为你要卖的商品即可。) 灵活的定制化: 通过后台管理系统,您可以根据您的网站需求自由地修改内容,使系统适应不同的产品销售,如书籍、电子产品等。简化的操作流程: 系统提供直观易用的后台管理界面,让您可以轻松管理商品信息、价格、库存等,并灵活调整网站布局和样式,以符合您的品牌形象和用户体验要求。多样化的商品展示: 您可以根据需求添加、编辑和删除商品信息,包括商品名称、描述、图片等,使用户能够清晰了解每个商品的特点。便捷的购物流程: 系统提供购物车功能和订单管理,用户可以方便地选择商品、结算并跟踪订单状态,提供良好的购物体验。可靠的安全性: 系统采用安全的登录和数据加密机制,保护用户和商家的信息安全,确保网站运行的稳定性和可靠性。友好的用户交互: 系统提供用户评价和推荐功能,促进用户之间的交流和购物经验分享,增强用户参与感和忠诚度。全天候的技术支持: 我们提供全天候的在线技术支持,解答您在使用过程中遇到的问题,并及时处理技术故障,确保系统的正常运行。 总结: 这个通用商城系统为您提供了灵活、简便的方式来搭建适应不同类型产品销售的网站。无论您是销售书籍、电子产品还是其他商品,只需在后台进行简单的配置修改,即可将系统定制为符合您的需求的销售商城网站。 开发环境及工具 开发工具:Intelij Idea 技术栈:开发语言 Java8 JDK1.8数据库:mysql 5.7服务器 : tomcat8.5前端开发:jsp、 html、 css 、javascript 本地部署运行 在部署运行之前需要先确保已经有以上开发工具及开发环境。 获取源码,下载源码到本地计算机。(保存路径不能有中文)创建数据库运行sql将代码导入到 Idea 中修改数据库配置为自己的(数据库账号和密码)配置tomcat服务器运行项目前台访问地址:http://127.0.0.1:tomcat端口 或者http://locathost:tomcat端口后台管理访问地址:http://127.0.0.1:tomcat端口/admin 或者http://locathost:tomcat端口/admin 系统功能 该系统有用户前台功能和管理员后台管理功能两个大模块 前台功能 前台功能导航 注册登录首页 欢迎信息产品推荐 浏览商品 浏览1商品浏览2商品…浏览n商品 购物车 将商品添加到购物车 订单结算 结算支付购物车中的产品 搜索商品 按照需求输入关键词搜索需要的商品 个人中心 查看个人信息修改个人信息查看订单数据管理我的订单 优惠活动 优惠活动1优惠活动2优惠活动n 咨询客服导购 咨询客服1咨询客服2咨询客服3 联系我们 联系系统客服 退出系统 退出登录 用户注册与登录: 提供用户注册账号并登录的功能,以便用户进行购物和管理个人信息。 商品分类与搜索: 将商品按照分类进行展示,并提供搜索功能,方便用户查找和筛选所需商品。 商品展示与详情: 展示商品的主要信息、图片和价格,并提供详细的商品描述,包括规格、特性、用户评价等。 购物车与结算: 允许用户将感兴趣的商品添加到购物车,并提供购物车管理功能,用户可以查看、修改购物车中的商品,最终结算并生成订单。

Oracle中rownum的使用

一、rownum的说明 rownum是oracle特有的一个关键字。 (1)对于基表,在insert记录时,oracle就按照insert的顺序,将rownum分配给每一行记录,因此在select一个基表的时候,rownum的排序是根据insert记录的顺序显示的,例如: select rownum as rn, t.* from emp t; (2)对于子查询,则rownum的顺序是根据子查询的查询顺序进行动态分配的,例如: select rownum as t2_rn, t2.* from (select rownum as t1_rn , t1.* from emp t1 order by t1.sal) t2; 由上图可以看到T1_RN和T2_RN的区别。 t1中的rownum是根据emp这个基表的默认顺序分配的,而内层子循环是根据SAL字段进行排序,所以t2的rownum是根据内层子查询的记录顺序分配的。 ----------------------------- 分 割 线 ------------------------------------- 二、rownum的一些使用技巧 (1)使用rownum限制查询返回的记录数 1、例如,我们现在只想看到emp表中的第一条记录: select * from emp where rownum=1; 将rownum限制为1,这样就只能查询出一条记录。 2、现在,我们现在想查看emp中的前2条记录: select * from emp where rownum<=2; 将rownum的限制为2条,这样就可以查询出前2条记录。 3、假如我们现在只想查看emp中的第二条记录,又该如何写语句呢? 如果我们先这样写: select * from emp where rownum=2; where条件为:rownum=2,来看看查询结果: 发现没有查出任何数据,为什么呢?这里就要对oracle的rownum做进一步的理解。 因为rownum并不是当作实体数据存放在每一张表中,而是在每一次select查询的时候,根据基表的默认insert顺序由oracle动态分配的,有1才有2,如果rownum没有1,那么2也就没有了意义,所以这个查询就不会有任何结果出来。这个时候我们就需要利用子查询和别名列来实现这个需求: select * from ( select rownum as rn, t.

自己封装的移动端可横向滚动表格组件,可实现滚动加载

<template> <div ref="table"> <div :style="tableStyle" v-scrollX="this"> <div> <div class="thead"> <div v-for="(item, index) in columns" :key="item + index" class="thead-item" > <div :style="{ left: left + 'px', background: '#ccc' }" > <div>{{ item.lable }}</div> </div> </div> </div> </div> <div class="tbody" :style="tbodyStyle" v-if="dataList.length >= 0"> <div v-for="(item, index) in dataList" :key="item + index" class="tbody-item" > <div v-for="(items, indexs) in columns" :key="items + indexs" :style="styleObject(items, 1)" @click="lineClick(indexs, index)" > <div :style="{ ...styleObject(items, 2), left: left + 'px' }"

Flink1.14.3 Sink Hive

flink版本:1.14.3 hive版本:2.1.1 mavn依赖如下: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.hiphi</groupId> <artifactId>flink-datasync</artifactId> <version>3.0-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <scala.binary.version>2.12</scala.binary.version> <flink.version>1.14.3</flink.version> <hive.version>2.1.1</hive.version> <hadoop.version>3.0.0</hadoop.version> <lombok.version>1.18.16</lombok.version> </properties> <dependencies> <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-java</artifactId> <version>${flink.version}</version> <exclusions> <exclusion> <artifactId>slf4j-api</artifactId> <groupId>org.slf4j</groupId> </exclusion> </exclusions> <!--<scope>provided</scope>--> </dependency> <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-streaming-java_${scala.binary.version}</artifactId> <version>${flink.version}</version> <exclusions> <exclusion> <artifactId>slf4j-api</artifactId> <groupId>org.slf4j</groupId> </exclusion> </exclusions> <!--<scope>provided</scope>--> </dependency> <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-table-api-java-bridge_${scala.binary.version}</artifactId> <version>${flink.version}</version> <exclusions> <exclusion> <artifactId>slf4j-api</artifactId> <groupId>org.slf4j</groupId> </exclusion> </exclusions> <!--<scope>provided</scope>--> </dependency> <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-table-planner_${scala.binary.version}</artifactId> <version>${flink.version}</version> <exclusions> <exclusion> <artifactId>slf4j-api</artifactId> <groupId>org.

MySql经典语句练习50题 ---- 40 ~ 50题

目录 40、查询选修"张三"老师所授课程的学生中,成绩最高的学生信息及其成绩: 41、查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩: 42、查询每门课成绩最好的前两名 43、统计每门课程的学生选修人数(超过5人的课程才统计)。要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列 : 44、检索至少选修两门课程的学生学号: 45、查询选修了全部课程的学生信息 46、查询各学生的年龄 47、查询本周过生日的学生 48、查询下周过生日的学生 49、查询本月过生日的学生 50、查询下月过生日的学生 40、查询选修"张三"老师所授课程的学生中,成绩最高的学生信息及其成绩: SELECT student.s_id, s_name, s_birth, s_sex, s_score FROM student, teacher, score, (SELECT c_id, MAX(s_score) max FROM score GROUP BY c_id) AS sc WHERE t_name = "张三" AND teacher.t_id = sc.c_id AND score.s_id = student.s_id AND score.c_id = sc.c_id AND score.s_score = max; 41、查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩: SELECT sc1.* FROM score sc1 WHERE EXISTS (SELECT * FROM score sc2 WHERE sc1.

SpringBoot的配置如何动态刷新(方案)

对于微服务而言配置本地化是个很大的鸡肋,不可能每次需要改个配置都要重新把服务重新启动一遍,因此最终的解决方案都是将配置外部化,托管在一个平台上达到不用重启服务即可一次修改多处生效的目的。 但是对于单体应用的Spring Boot项目而言,动态刷新显然是有点多余,反正就一个服务,改下重启不就行了,然而在某些特殊的场景下还是必须用到动态刷新的 微服务下有哪几种主流的方案? 微服务下的动态配置中心有三种主流的方式,如下图: 上图中的三种配置中心方案可以说是现在企业中使用率最高的,分别是: Nacos:阿里巴巴的最近开源的项目,这个家伙很牛逼,一个干掉了Eureka(停更)和Config+Bus,既能作为配置中心也能作为注册中心,并且有自己的独立的 管理平台,可以说是现在最主流的一种。 Config+Bus:早期在用的微服务配置中心,可以依托GitHub管理微服务的配置文件,这种现在也是有不少企业在用,但是需要自己独立部署一个微服务,和Nacos相比逊色了不少。 Apollo:携程开源项目Apollo,这个也是不少企业在用,陈某了解的不多,有兴趣的可以深入研究下。 针对Spring Boot 适用的几种方案? 其实上述三种都可以在Spring Boot项目中适配,但是作为单体应用有些重了。 1. 如果项目是一个微服务的集群,业务功能复杂 建议: Spring Boot+Nacos 2. 如果项目是单体服务,业务功能单一 建议: Spring Boot+Config+actuator Spring Boot+手动refresh 针对Spring Boot+Nacos 阿里要做的其实是一个微服务生态,Nacos不仅仅可以作为Spring Cloud的配置和注册中心,也适配了Dubbo、K8s,官方文档中对于如何适配都做了详细的介绍,作者 这里就不再详细介绍了,如下图: 当然Nacos对Spring、Spring Boot 项目同样适用。 如何使用呢?这里作者只提供下思路,不做过多的深究,这篇在作者下个专栏Spring Cloud 进阶会详细介绍: 下载对应版本的Nacos,启动项目,访问http://localhost:8848进入Nacos的管理界面; Spring Boot 项目引入Nacos的配置依赖nacos-config-spring-boot-starter,配置Nacos管理中心的地址。 @NacosPropertySource、@NacosValue两个注解结合完成。 @NacosPropertySource:指定配置中心的dataId,和是否自动刷新 @NacosValue替代@Value注解完成属性的自动装配 如果公司项目做了后台管理,则可以直接调用Nacos开放的API修改对应配置的值(替代了Nacos管理界面的手动操作),API的地址:https://nacos.io/zh-cn/docs/open-api.html 针对Spring Boot+Config+actuator 1. 添加Config的依赖,如下 <!-- springCloud的依赖--> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR3</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <!-- config的依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <!

java开发环境配置

1、JDK安装和配置 Windows环境JDK安装与配置 - 简书 变量名:JAVA_HOME 变量值:C:\Program Files\Java\jdk1.8.0_121(填写jdk的安装目录) 变量名:Path 变量值: %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin; 变量名:CLASSPATH 变量值:.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar(注意:前面有个点) 验证java安装:打开命令控制台,输入java -version。 2、maven安装和配置 正确的安装方法:https://blog.csdn.net/weixin_43843824/article/details/93903018 http://wiki.jikexueyuan.com/project/maven/environment-setup.html 变量名:M2_HOME 变量值:D:\dev\Java\apache-maven-3.39(填写maven的安装目录) 变量名:M2 变量值:%M2_HOME%\bin(错误) D:\dev\Java\apache-maven-3.39\bin(正确) 变量名:MAVEN_OPTS 变量值:Xms256m -Xmx512m 添加 M2 变量到系统“Path”变量中:添加字符串 “;%M2%” 到系统“Path”变量末尾。 验证maven安装:打开命令控制台,输入mvn --version。 3、Tomcat安装和配置 Windows安装配置Tomcat - 临江仙卜算子的个人空间 - OSCHINA - 中文开源技术交流社区 Tomcat的目录结构 |-bin: 存放tomcat的命令。 catalina.bat(sh) 命令: startup.bat(sh) -> catalina.bat(sh) start shutdown.bat - > catalina.bat(sh) stop |- conf: 存放tomcat的配置信息。其中server.xml文件是核心的配置文件。 |-lib:支持tomcat软件运行的jar包。其中还有技术支持包,如servlet,jsp |-logs:运行过程的日志信息 |-temp: 临时目录 |-webapps: 共享资源目录。web应用目录。(注意不能以单独的文件进行共享) |-work: tomcat的运行目录。jsp运行时产生的临时文件就存放在这里 变量名:TOMCAT_HOME 变量值:D:\dev\tomcat8\apache-tomcat-8.0.12\bin(填写tomcat的安装目录) 变量名:CLASSPATH 变量值:.;%TOMCAT_HOME%\;(注意:前面有个点)

HCIA-学习总结

一、路由器配置实验(测试五个路由器是否可以联通) 实验拓扑图如下: 此次使用的是华为模拟器eNSP 使用SecureCRT进行配置 首先为每个端口配置ip地址 [R1-GigabitEthernet0/0/0]ip address 192.168.1.1 24 [R2-GigabitEthernet0/0/0]ip address 192.168.1.2 24 [R2-GigabitEthernet0/0/1]ip address 192.168.2.1 24 [R3-GigabitEthernet0/0/0]ip address 192.168.2.2 24 [R3-GigabitEthernet0/0/1]ip address 192.168.3.1 24 [R4-GigabitEthernet0/0/0]ip address 192.168.3.2 24 [R4-GigabitEthernet0/0/1]ip address 192.168.4.1 24 [R5-GigabitEthernet0/0/0]ip address 192.168.4.2 24 路由器的路由功能: 当数据包到达路由器后,路由器会基于数据包中的目的IP地址来查询本地的路由表 如果存在记录,则无条件转发,若不存在则直接丢弃。 查看路由表 此时如果我们ping第五台路由器 则会失败 因为路由表中不存在 192.168.4.2 的直连路由条目,所以会被丢弃,所以我们需要为每台路由器添加相应的路由条目。此时我们选择静态路由添加。 静态路由--原理--将未知网段通过手工的方式添加到路由表中 做法: 静态路由前缀 未知网段及掩码 下一跳地址 下一跳:流量从本地发出后,下一个入接口的IP地址 此时我们会发现 路由表中已经添加上了我们手动输入的静态路由条目 此时查看每台路由器的路由表: R1 R2 R3 R4 R5 此时我们用第一台路由器去ping第五台路由器 不难发现。此时已经相通,我们再试试第三台路由器去ping第一台和第二台 也是成功的。 综上,实验成功。 二、实验总结 通过本实验,我对静态路由有了一定的了解,也基本掌握了静态路由的配置方法,熟悉了使用Ping命令查询路由信息的方法,对各个网络的互联也有一个深刻的理解。 分析:静态路由是指路由信息由管理员手工配置,而不是路由器通过路由算法和其他路由器学习得到的。所以,静态路由主要适合网络规模不大、拓扑结构相对固定的网络使用,当网络环境比较复杂时,由于其拓扑或链路状态相对容易变化,就需要管理员再手工改变路由,这对管理员来说是一个烦琐的工作,且网络容易受人的影响,对管理员来说,不论技术上还是纪律上都有更高的要求。

java--基础--17.7--线程--内存模型与线程

java–基础–17.7–线程–内存模型与线程 1、内存模型 1.1、主内存和工作内存之间的交互 1.2、对于 volatile 型变量的特殊规则 关键字 volatile 是 Java 虚拟机提供的最轻量级的同步机制。 一个变量被定义为 volatile 的特性 保证此变量对所有线程的可见性。但是操作并非原子操作,并发情况下不安全。 如果不符合 运算结果并不依赖变量当前值,或者能够确保只有单一的线程修改变量的值 和 变量不需要与其他的状态变量共同参与不变约束 就要通过加锁(使用 synchronize 或 java.util.concurrent 中的原子类)来保证原子性。 禁止指令重排序优化。 通过插入内存屏障保证一致性。 1.3、对于 long 和 double 型变量的特殊规则 Java 要求对于主内存和工作内存之间的八个操作都是原子性的,但是对于 64 位的数据类型,有一条宽松的规定:允许虚拟机将没有被 volatile 修饰的 64 位数据的读写操作划分为两次 32 位的操作来进行,即允许虚拟机实现选择可以不保证 64 位数据类型的 load、store、read 和 write 这 4 个操作的原子性。这就是 long 和 double 的非原子性协定。 1.4、原子性、可见性与有序性 1.4.1、原子性(Atomicity) 由 Java 内存模型来直接保证的原子性变量操作包括 read、load、assign、use、store 和 write。大致可以认为基本数据类型的操作是原子性的。同时 lock 和 unlock 可以保证更大范围操作的原子性。而 synchronize 同步块操作的原子性是用更高层次的字节码指令 monitorenter 和 monitorexit 来隐式操作的。

雪花算法id值精度丢失问题

雪花算法id值问题(丢失精度) 问题描述:MybatisPlus默认雪花算法生成id策略,生成的id为19位,而前端网页界面js能处理的数值长度最多为16位,从而会造成id从前端返回后端会出现精度丢失,以至于后端根据id修改数据时修改失败。 问题解决思路:将Long型的id转为String类型传给前端,从而避免id在前后端传输时造成精度丢失。以下两种自定义转换器同时对日期格式和Long型id做了设置。 方案一 问题解决方法:1、提供对象转换器JacksonObjectMapper,基于jackson进行Java对象到json数据的转换 /** * 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象 * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象] * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON] */ public class JacksonObjectMapper extends ObjectMapper { public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd"; public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss"; public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss"; public JacksonObjectMapper() { super(); //收到未知属性时不报异常 this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false); //反序列化时,属性不存在的兼容处理 this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); SimpleModule simpleModule = new SimpleModule() .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))) .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))) .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT))) .addSerializer(BigInteger.class, ToStringSerializer.instance) .addSerializer(Long.class, ToStringSerializer.

vue3的学习【超详细】

目录 一、vue3的优点1、vue3的优点 二、常用的API1、setup(Composition API)2、生命周期(Composition API)3、ref函数和reactive函数用法和区别(Composition API)1、ref2、reactive3、ref和reactive的区别 4、计算属性(computed)和侦听属性(watch)(Composition API)1、computed2、watch 5、nextTick(全局API)6、props(选项式API)1、非ts语法2、ts语法 7、toRefs(Composition API)8、vue3中的响应式原理1、vue2中的响应式原理2、vue3中的响应式原理 总结9、自定义指令1、什么是指令2、怎么实现3、应用场景 10、自定义修饰符11、vue的vueuse库(工具库) 三、新组件和新属性1、v-bind(内置内容)2、teleport 传送门3、Suspense 一、vue3的优点 1、vue3的优点 1、源码体积得到优化: (1) API减少,移除一些冷门API,如filter、inline-template等; (2)引入tree-shaking 减少打包体积; 2、源码的升级: (1)Vue3使用Proxy进行数据劫持,可以很好的规避vue2使用Object.defineProperty进行数据劫持带来的缺陷; 3、拥抱TypeScript: (1) 更好的支持Ts(typescript) 4、高级给与: (1)暴露了更底层的API和提供更先进的内置组件; 5、 组合API(Composition API): (1) 能够更好的组织逻辑,封装逻辑,复用逻辑; 二、常用的API 1、setup(Composition API) 1、setup是vue3中的一个全新的配置项,值为一个函数; 2、setup是所有CompositionAPI(组合API)的基础,组件中所用到的数据、方法等都需要在setup中进行配置; (1):若返回一个对象,则对象中的属性、方法,均可以在模板中直接使用; (2):若返回一个渲染函数:则可以自定义渲染内容; setup的两个注意点: 1、setup执行时机,在beforeCreate之前执行一次,this是undefined; 2、setup的参数: (1):props:指为对象,包含组件外部传递过来,且组件内部声明接收了的属性。 (2):context:上下文对象 attrs:值为对象,包含组件外部传递过来,但没有在props配置中声明的属性,相当于this.$attrs; slots:收到的插槽内容,相当于this.$slots; emit:分发自定义事件的函数,相当于this.$emit。 2、生命周期(Composition API) vue3中的生命周期和vue2的区别: beforeCreate=>setup()(创建实例前) created=>setup() (创建实例后) beforeMount=>onBeforeMount ( 挂载DOM前) mounted=>onMounted ( 挂载DOM后) beforeUpdate=>onBeforeUpdate (更新组件前) updated=>onUpdated (更新组件后) beforeUnmount=>onBeforeUnmount (卸载销毁前) unmounted=>onUnmounted (卸载销毁后)

2023最新版Java面试八股文大全(附各大厂面试真题及答案)

作为一个 Java 程序员,你平时总是陷在业务开发里,每天噼里啪啦忙敲着代码,上到系统开发,下到 Bug 修改,你感觉自己无所不能。然而偶尔的一次聚会,你听说和自己一起出道的同学早已经年薪 50 万,而自己却囊中羞涩。于是你也想看看新机会,找个新平台,好好发展。 但是面试的时候,当那个笑眯眯的面试官问出那些你再熟悉不过的 Java 问题时,你只是感觉似曾相识,却怎么也回答不到点上。比如 HashMap 的工作原理,再或者 volatile 的使用场景。 这个时候,你可能会怀疑自己的能力,也痛恨为什么当初自己没有好好复习。 该新版文档在 Github 上上传一个星期已经收获 30K+star 的 Java 核心面试神技(这参数,质量多高就不用我多说了吧)非常全面,包涵 Java 基础、Java 集合、JavaWeb、Java 异常、OOP、IO 与 NIO、反射、注解、多线程、JVM、MySQL、MongoDB、Spring 全家桶、计算机网络、分布式架构、Redis、Linux、git、前端、算法与数据结构、MyBatis、RocketMQ、Netty、Dubbo、Zookeeper、分布式缓存、数据结构等等内容非常丰富,已经帮很多人拿下互联网一线公司的 offer。下面我来跟大家一起分享一下。 JavaOOP 什么是 B/S 架构?什么是 C/S 架构Java 都有哪些开发平台?什么是 JDK?什么是 JRE?Java 语言有哪些特点面向对象和面向过程的区别什么是数据结构?Java 的数据结构有哪些?什么是 OOP?类与对象的关系?Java 中有几种数据类型 Java 集合/泛型 ArrayList 和 linkedList 的区别HashMap 和 HashTable 的区别Collection 包结构,与 Collections 的区别泛型常用特点 (待补充)说说 List,Set,Map 三者的区别Array 与 ArrayList 有什么不一样?Map 有什么特点集合内存放于 Java.util 包中, 主要有几 种接口什么是 list 接口说说 ArrayList(数组) Java 异常 Java 中异常分为哪两种?异常的处理机制有几种?如何自定义一个异常try catch fifinally,try 里有 return,finally 还执行么?Excption 与 Error 包结构Thow 与 thorws 区别Error 与 Exception 区别?error 和 exception 有什么区别 Java 中的 IO 与 NIO Java 中 IO 流?Java IO 与 NIO 的区别常用 io 类有哪些字节流与字符流的区别阻塞 IO 模型非阻塞 IO 模型多路复用 IO 模型信号驱动 IO 模型异步 IO 模型JAVA NIO Java 反射 除了使用 new 创建对象之外,还可以用什么方法创建对象?Java 反射创建对象效率高还是通过 new 创建对象的效率高?java 反射的作用哪里会用到反射机制?反射的实现方式:实现 Java 反射的类:反射机制的优缺点:Java 反射 API反射使用步骤(获取 Class 对象、调用对象方法)获取 Class 对象有几种方法利用反射动态创建对象实例 Java 序列化 什么是 java 序列化,如何实现 java 序列化?保存(持久化)对象及其状态到内存或者磁盘序列化对象以字节数组保持-静态成员不保存序列化用户远程对象传输Serializable 实现序列化writeObject 和 readObject 自定义序列化策略序列化 ID序列化并不保存静态变量Transient 关键字阻止该变量被序列化到文件中序列化(深 clone 一中实现) 多线程 &并发 JAVA 并发知识库

HTML小说排行榜案例

效果图: 代码实现: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>今日小说排行榜</title> </head> <body> <table align="center" cellspacing="0" width="500" height="249" border="1"> <tr> <th>排名</th> <th>关键词</th> <th>趋势</th> <th>进入搜索</th> <th>最近七日</th> <th>相关链接</th> </tr> <tr> <td>1</td> <td>鬼吹灯</td> <td><img src="down.jpg" alt=""></td> <td>456</td> <td>123</td> <td><a href="#">贴吧</a> <a href="#">图片</a> <a href="#">百科</a></td> </tr> <tr> <td>1</td> <td>鬼吹灯</td> <td><img src="down.jpg" alt=""></td> <td>456</td> <td>123</td> <td><a href="#">贴吧</a> <a href="#">图片</a> <a href="#">百科</a></td> </tr> <tr> <td>3</td> <td>西游记</td> <td><img src="up.jpg" alt=""></td> <td>456</td> <td>123</td> <td><a href="

JVM常用的调优参数和调优工具

文章目录 JVM调优如何设置参数值tomcat的设置vm参数boot项目jar文件启动 常用的JVM调优参数常用的JVM调优工具命令工具可视化工具 本文主要讲的是JVM常用的调优参数和调优工具。JVM调优可以简单的理解为,JVM中的堆区中存放的是实际的对象,是需要被GC的。其他的都无需GC。 对JVM内存的系统级的调优主要的目的是减少GC的频率和Full GC的次数。 JVM调优如何设置参数值 tomcat的设置vm参数 修改TOMCAT_HOME/bin/catalina.sh文件,如下图 JAVA_OPTS="-Xms512m -Xmx1024m" boot项目jar文件启动 通常在linux系统下直接加参数启动springboot项目 nohup java -Xms512m -Xmx1024m -jar xxxx.jar --spring.profiles.active=prod & nohup:用于在系统后台不挂断地运行命令,退出终端不会影响程序的运行。 参数 & :让命令在后台执行,终端退出后命令仍旧执行。 常用的JVM调优参数 ​ 对于JVM调优,主要就是调整年轻代、年老代、元空间的内存空间大小及使用的垃圾回收器类型。 Oracle官网上相关的 -XX 选项 1)设置堆的初始大小和最大大小,为了防止垃圾收集器在初始大小、最大大小之间收缩堆而产生额外的时间,通常把最大、初始大小设置为相同的值。 -Xms:设置堆的初始化大小 -Xmx:设置堆的最大大小 2) 设置年轻代中Eden区和两个Survivor区的大小比例。该值如果不设置,则默认比例为8:1:1。Java官方通过增大Eden区的大小,来减少YGC发生的次数,但有时我们发现,虽然次数减少了,但Eden区满的时候,由于占用的空间较大,导致释放缓慢,此时STW的时间较长,因此需要按照程序情况去调优。 -XXSurvivorRatio=3,表示年轻代中的分配比率:survivor:eden = 2:3 3)年轻代和老年代默认比例为1:2。可以通过调整二者空间大小比率来设置两者的大小。 -XX:newSize 设置年轻代的初始大小 -XX:MaxNewSize 设置年轻代的最大大,初始大小和最大大小两个值通常相同 4)线程堆栈的设置:每个线程默认会开启1M的堆栈,用于存放栈帧、调用参数、局部变量等,但一般256K就够用。通常减少每个线程的堆栈,可以产生更多的线程,但这实际上还受限于操作系统。 -Xss 对每个线程stack大小的调整,-Xss128k 5)一般来说,当survivor区不够大或者占用量达到50%,就会把一些对象放到老年区。通过设置合理的eden区,survivor区及使用率,可以将年轻对象保存在年轻代,从而避免full GC,使用-Xmn设置年轻代的大小。 6)系统CPU持续飙高的话,首先先排查代码问题,如果代码没问题,则咨询运维或者云服务器供应商,通常服务器重启或者服务器迁移即可解决。 7)对于占用内存比较多的大对象,一般会选择在老年代分配内存。如果在年轻代给大对象分配内存,年轻代内存不够了,就要在eden区移动大量对象到老年代,然后这些移动的对象可能很快消亡,因此导致full GC。通过设置参数:-XX:PetenureSizeThreshold=1000000,单位为B,标明对象大小超过1M时,在老年代(tenured)分配内存空间。 8)一般情况下,年轻对象放在eden区,当第一次GC后,如果对象还存活,放到survivor区,此后,每GC一次,年龄增加1,当对象的年龄达到阈值,就被放到tenured老年区。这个阈值可以同构-XX:MaxTenuringThreshold设置。如果想让对象留在年轻代,可以设置比较大的阈值。 (1)-XX:+UseParallelGC:年轻代使用并行垃圾回收收集器。这是一个关注吞吐量的收集器,可以尽可能的减少垃圾回收时间 (2)-XX:+UseParallelOldGC:设置老年代使用并行垃圾回收收集器 9)尝试使用大的内存分页:使用大的内存分页增加CPU的内存寻址能力,从而系统的性能。 -XX:+LargePageSizeInBytes 设置内存页的大小 10)使用非占用的垃圾收集器。 -XX:+UseConcMarkSweepGC老年代使用CMS收集器降低停顿 常用的JVM调优工具 命令工具 jps(Java Process Status) 输出JVM中运行的进程状态信息(现在一般使用jconsole) jstack 查看java进程内线程的堆栈信息。 jstack [option] <pid> Java案例

linux系统的字符集查看及修改

一、查看字符集 Linux字符集在系统中体现形式是一个环境变量,以CentOS7为例,其查看当前终端使用字符集的方式可以有以下四种方式: 第一种: [root@Testa-www tmp]# echo $LANG zh_CN.UTF-8 第二种: [root@Testa-www ~]# env |grep LANG LANG=zh_CN.UTF-8 第三种: [root@Testa-www ~]# export |grep LANG declare -x LANG=”zh_CN.UTF-8″ 第四种: [root@Testa-www ~]# locale LANG=zh_CN.UTF-8 LC_CTYPE=”zh_CN.UTF-8″ LC_NUMERIC=”zh_CN.UTF-8″ LC_TIME=”zh_CN.UTF-8″ LC_COLLATE=”zh_CN.UTF-8″ LC_MONETARY=”zh_CN.UTF-8″ LC_MESSAGES=”zh_CN.UTF-8″ LC_PAPER=”zh_CN.UTF-8″ LC_NAME=”zh_CN.UTF-8″ LC_ADDRESS=”zh_CN.UTF-8″ LC_TELEPHONE=”zh_CN.UTF-8″ LC_MEASUREMENT=”zh_CN.UTF-8″ LC_IDENTIFICATION=”zh_CN.UTF-8″ 二、Linux修改字符集的方法 在Linux系统中如果默认语言是en_US.UTF-8,在Linux的字符和图形界面下都是无法显示和输入中文的。如果默认语言是中文,比如zh_CN.GB18030 或者zh_CN.gb2312,字符界面无法显示和输入,图形界面可以。 Linux修改字符集的方式有如下两种: 1、直接设置变量的方式修改 export LANG=zh_CN.UTF-8 2、修改文件方式,通过修改/etc/sysconfig/i18n文件控制 [root@Testa-www ~]# vim /etc/sysconfig/i18n LANG=”zh_CN.UTF-8″ [root@Testa-www ~]# source /etc/sysconfig/i18n

遍历数组在数组中每一条数据里增加一个字段

var data = [ {name:'小明',value:'1'}, {name:'小红',value:'2'} ] 遍历数组给每条数据都加上age字段: data.map((item, index) => { item.age = '18'; //添加的字段 }) 再次打印数组结果如下: [ {name:'小明',value:'1',age:'18'}, {name:'小红',value:'2',age:'18'} ]

常听人说并发量高达多少多少,这个值是怎么测的?

前言 近期即将上线一个在线考试类的系统,由于甲方客户比较重视此次考试,所以各种准备工作也要做足。故此对线上系统做了一次比较全面的压力测试,也是通过这次测试,验证了之前的很多想法,自感收获颇丰,故留此文。 准备测试用例 正常来说,待测用例可能是接口,也可能是页面,或者是一连串的操作动作,比如先登录,再浏览某页面,再提交某表单等等。具体情况不同,准备用例的复杂程度也有区分。我这里就是准备了几个接口,然后把接口里实现了一些模拟真实情况的操作,这样准备的用例就会很简单。 概括一下就是,数据库读,缓存读,数据库写,数据库更新 4 个操作 具体代码就不贴了,都是些业务操作,只简单贴一下接口名和一些接口配置 #region 性能压力测试相关接口,模拟考试各种动作 /// <summary> /// 模拟获取考试列表,并缓存 /// </summary> /// <param name="associationId"></param> /// <returns></returns> [AllowAnonymous] [ResponseCache(Duration = 100)] public async Task<IActionResult> TestGetExaminations(string token) { //业务动作 } /// <summary> /// 模拟验证身份接口 /// 这里只验证接口访问情况,故将所有情况返回值都设定为code=1 /// </summary> /// <returns></returns> [AllowAnonymous] public async Task<IActionResult> TestInfoVerification(string token,string testExamId="",string testIdNumber="") { //业务动作 } /// <summary> /// 模拟抽卷, /// 这里不实际抽题,执行一个相对的耗时插入操作,并标记为删除 /// </summary> /// <returns></returns> [AllowAnonymous,HttpPost] public async Task<IActionResult> TestConfirmMyPaper(string token) { //业务动作 } /// <summary> /// 模拟提交答题 /// </summary> /// <returns></returns> [AllowAnonymous, HttpPost] public async Task<IActionResult> TestSubmitPaper(string token) { //业务动作 } #endregion 注意,我把这几个接口的访问级别设定成了不需要验证即可访问,一是为了方便,二是由于我们的用户中心是隔离出去的,也是为了避免多个系统的影响,直接测试本系统性能。

10.BeanFactoryPostProcessor

highlight: arduino-light BeanFactoryPostProcessor 前几篇我们详细讲解了BeanDefinition的源码,我们知道spring扫描符合规则的业务类后会通过 AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner将业务类封装成BeanDefinition保存在IOC容器中,那么,spring容器启动过程中是在哪里扫描的呢? 答案是在BeanFactoryPostProcessor后置处理器中完成扫描功能,不仅仅是类扫描,BeanFactoryPostProcessor能完成更丰富的功能,比如bean拦截处理、spring扩展开发都离不开它。 从本篇文章开始,笔者将向大家详细阐述BeanFactoryPostProcessor。 BeanFactoryPostProcessor分两种,一种是spring内置,一种由程序员提供。 我们首先通过注解的方式启动spring: java AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.register(Config.class); context.refresh(); context.refresh()完成了spring的启动过程,类扫描也是在这个方法中完成的,这个方法的实现是在AnnotationConfigApplicationContext的父类AbstractApplicationContext方法中完成的。 跳转到具体的实现,找到下面这行源码: java invokeBeanFactoryPostProcessors(beanFactory); 这行代码的逻辑:先执行已经注册到bean工厂中的所有内置BeanFactoryPostProcessor,再执行程序员提供的BeanFactoryPostProcessor。 BeanFactoryPostProcessor BeanFactoryPostProcessor是bean工厂的后置处理器,能干预bean工厂的工作流程。 那么什么又是bean工厂呢? java AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); 这行代码首先会执行无参构造函数,学过java的读者都知道,无参构造函数在调用前先调用父类的构造函数,AnnotationConfigApplicationContext的父类是GenericApplicationContext: java public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry 我们看下GenericApplicationContext无参构造函数: ```java private final DefaultListableBeanFactory beanFactory; public GenericApplicationContext() { //实例化bean工厂 this.beanFactory = new DefaultListableBeanFactory(); } ``` DefaultListableBeanFactory就是bean工厂,在BeanDefinition我们讲过spring生成的BeanDefinition会保存在一个map当中,这个map就是保存在DefaultListableBeanFactory的beanDefinitionMap当中: java //DefaultListableBeanFactory中的属性beanDefinitionMap,用于保存BeanDefinition private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256); BeanFactoryPostProcessor是一个接口,它只定义了一个方法postProcessBeanFactory,spring启动过程中会自动回调BeanFactoryPostProcessor的实现类的postProcessBeanFactory方法。 postProcessBeanFactory方法有一个ConfigurableListableBeanFactory的类型参数beanFactory,也就是说我们可以在这个postProcessBeanFactory方法里操作bean工厂。

生活中有趣好玩的产品设计

生活纷繁忙碌,设计无处不在。我们的衣食住行、吃喝玩乐都在跟设计打交道,创作奇才们用竭尽所能的心智引导和体验设计,吸引着我们的注意力。 这其中充满着做产品的思路,散发着智慧的光芒,留心观察就会发现很多有趣好玩的设计,这里分享四个案例。 01 小罐茶的十大名茶 北京南站,看到了小罐茶的广告——中国十大名茶。看到广告我愣住了,我虽然不能说出十大名茶包含哪些,但小罐茶肯定不是十大名茶(小罐茶是品牌,名茶是品种)。 在仔细看到了茶字后面小小的「套装」两字,我由衷赞叹这真是一个好广告,不愧是营销出身的大师。借势营销,小罐茶是懂的。 首先借用了大家熟悉但模糊的概念,十大名茶有什么?相信大部分人未必回答的上来。但模糊不代表消费者不知道、不理解其中的品牌价值。消费者是吃榜单这套逻辑的。 茶叶售卖全靠经验定价,不同产地、不同时间、不同大师、不同成色都是不同的价格。当我们购买非标的茶叶时,心里肯定有疑问:到底值不值这个价? 因此现有的茶叶交易逻辑是人,基于对人的信任决定了对茶叶的信任,在向附近商家购买茶叶时心里默念:他不会骗我,我一直喝的都是他的茶。 小罐茶的妙就妙在标准化的定价:大师制作、原产地、工艺保鲜,都是在告诉消费者——茶叶为什么值千元。重要吗?茶叶的送礼/社交属性,只要相信就好了。 好的广告自带流量,小罐茶的广告借了10大名茶的势能,在高铁站更偏商务出行和社交的场景中,确实是一个好的广告案例。 小罐茶,解决花费是不被坑的心理,解决收礼人已知价格的状态,是当代社交的“斯蒂庞克牌轿车”,是社交中的“十大名茶”。 02 霸蛮米粉的空间利用 在等待湖南米粉上桌的间隙,我看了看霸蛮的装修设计,不由暗叹一石二鸟。 首先看到4个白板牌子,通过文字解释了何谓标题的根正苗红:「湖南米粉」的出炉「汤、料、方」和现煮。这是立店之本,要说明本店就是正宗的湖南米粉生意。 同时,四块白板稍微挡住了观察后厨的视线。如果不用这4块板子,而是纯透明的玻璃,那消费者的视线就会聚焦在堆满了瓶瓶罐罐的后台和店员的出餐动作,此时消费者会不会对米粉的卫生的产生担忧呢?因此,不能让消费者的注意力集中在店员身上,消费者只需要看到忙碌新鲜就好。 但也不能用毛纱玻璃,这种类似封闭的空间,员工长期待在里面会顶不住,而且店员无法留意店内的情况,比如当看到来人的时候,店员会自发的起立准备接单。 这4块白板设计的是真好,即解释本店米粉了正宗的原因,也能给10平小店带来一些干净清爽的气息。 另一个值得一提是辣椒炒肉盖板的海报,这是一个和米粉无法并存的主食(臭豆腐是并存的小食)。这应该是霸蛮牛肉粉寻找的第二个超级单品,给消费者另一个进店消费和二次消费的理由。 一个连锁门店要考虑的核心是产品模型和单店模型,在全面铺开的连锁店里,低成本的拓展店内的品类,找到下一个超级单品,不失为拓客/增收的好方式。类似的还有正新鸡排的小串、报亭的烤红薯。 还有一个细节,辣椒炒肉没有沿用在湖南是小炒肉的叫法,而是直呼其名,让大家知道菜品的所见即所得。即面向消费者做产品,一切设计以降低理解成本为宗旨。 03 夫子庙的掷币祈福 游客为什么要投掷硬币呢?没有场景,制造场景。 站在寺庙香火的角度,希望游客多投掷,这样就能增加收入。但站在游客的角度,为什么要投呢?为什么要心甘情愿的投呢?以及为何要投多次呢? 看到夫子庙的盘子,让人眼前一亮,给投币行为设置标的物,用不同的文案,给每位游客一个投币的理由。 学子家长对应金榜提名,大学毕业生对应前程似锦,恋爱情侣对应姻缘美满,家庭对应家庭和睦和一生平安。 我们总能触景生情,我们总能对号入座,我们投掷的不是一份给寺院的香火钱,而是对一份对自己的美好期许。 这算PUA吗?是的,寺院通过包装游客期许的场景,进而达到自己创收的目的。我们作为游客也陷入其中,做着对方期望我们做出的动作。但何尝不是快乐呢? 生活多美学,处处皆设计。 04 百旺公园的旺字设计 中午散步的百旺公园,只有旺字是实心的钢结构,其余三字是镂空+石头的设计。为什么旺字跟其他三个不是同一风格呢? 这必然是设计者基于某种想法的刻意为之。虽然我们无法当面询问,但可以猜测一番。 旺是一个美好的字,寓意兴隆发达。百旺是一个常见的词,其中百是量词、虚词,泛指一切事情都顺畅旺盛。自然而然,百旺公园就是寓意一切顺利美好兴旺繁盛的公园场所。 百旺公园作为一个公园的名字,最重要的是哪个字呢?必然是「旺」,公园场所名,百是旺的量词,因此,旺的重要性大于其他三个字。基于这个前提,如果要突出其中的一个字,那么必然是旺字。 但为什么是用实心的钢结构突出,不是用镂空+石头的艺术设计突出呢?除了用料更贵以外,在视觉上我们最容易被实心的事物吸引。考虑到背景是石墙,公园两字已经融于背景,视觉上弱化了。 由此设计,我们看到公园名称的时候的视觉重心必然是旺字,再基于旺延伸到百旺公园的名称,既强化突出了公园的寓意,也承载了名称的说明作用。 感谢设计者的用心,让我们收获了一个不一样的游园体验。 最后 世事洞察皆学问,人情达练即文章。 生活很有趣,身边多美好。观察生活,发现用心者的精雕细琢。上下求索,洞察创作者的深思熟虑。 用真心对待所做的事情,毕竟当有心人发现的时候,可能会会心一笑吧:) 注:封面和题图来自初夏的798 欢迎关注公众号 持续输出深度思考的干货文章 ↓↓↓↓↓↓

【web-ctf】ctf-pikachu-file_download

文章目录 File Download(文件下载漏洞)1. Unsafe FileDownload 总结 File Download(文件下载漏洞) 漏洞产生原因:很多网站都会提供文件下载功能,即用户可以通过点击下载链接,下载到链接所对应的文件。 但是,如果文件下载功能设计不当,则可能导致攻击者可以通过构造文件路径,从而获得到后台服务器上的其他的敏感文件。(又称:任意文件下载) 1. Unsafe FileDownload 随便点开一个球员名字进行下载,并使用burpsuite进行抓包,观察网页和url有什么变化。 假设我们点击“艾弗森”的名字。 发现该请求为一个get请求,参数filename=ai.png,这里就可能产生了一个文件下载漏洞,如果后台没有对该参数进行过滤和限制,那么我们可以修改该参数值,来对后台存在的某些敏感文件进行下载。 修改filename参数。 假设D盘根目录下有一个1.txt文件,为了利用该漏洞下载到1.txt文件,我们可以将filename参数修改为 filename = ../../../../../../../../1.txt 漏洞利用成功! 总结 防范措施: 对传入的文件名进行严格的过滤和限定,比如判定下载的文件名是否为该目录下存在的文件。对文件下载的目录进行严格的限定。

【Vue3】滑动验证组件 | 滑动验证

前言 滑块验证不只判断是否滑动到尾部,真正的目的是检测用户行为,检测行为是人为、脚本、还是其它。 防止使用脚本大量注册、请求等 。比如发送请求时,判断用户在某个页面停留了多长时间。登录、注册时是否点击了登录、注册按钮,如果没有点击就直接发送登录、注册请求,那么这个行为十有八九是脚本、机器行为。 滑块验证有几个重要的数据 滑块的起点滑块的终点滑块从起点滑动到终点所用的时间,比如人为滑动长度为240px的滑块,至少需要50毫秒,才能冲起点滑倒终点。若起点滑到终点所用的时间是50毫秒以下,那么这种行为99%是机器、脚本行为。人为滑的没那么快。滑块的长度,滑块的长度越长越好,因为长度越长,我们采集到的数据就越多,数据越多就越容易判断是人为还是机器、脚本行为。滑块最好在200px+以上。滑动滑块的轨迹,例如滑动一个长度为300px的滑块,至少可以采集到20个点位,每个点位有用户滑动的x,y轴位置、滑动时间等。 验证方式 人为滑动轨迹参考 当我们用手滑动验证滑块时,滑动轨迹为变速曲线运动,上下起伏分布不均、且变速运动。如下图3图 图1 图2 图3 人为/人机/脚本滑动判断 滑动滑块所用时间低于50毫秒判断为人机/脚本,200px的滑块,人为滑动没那么快。判断滑动的线条起伏,若是纯直线,则为人机,因为人为滑动没那么直。计算滑动速度,人为滑动肯定是变速滑动,若是匀速滑动则为人机。 若不是人为滑动,多数是直线匀速滑动,不会上下起伏。例如脚本滑动。 但部分机器/脚本可以模拟人为滑动,所以很轻易破解滑块验证。 下面是一串人为滑动的数据,用canvs渲染出来, x - x轴位置,y - y轴位置 ,moveTime - 滑动到该点的时间 <canvas id="cvs" width="300" height="60"></canvas> <script> const draw = data => { const cvs = document.querySelector('#cvs'), c = cvs.getContext('2d') c.clearRect(0, 0, cvs.width, cvs.height) c.lineWidth = 2 c.strokeStyle = 'red' c.beginPath() data.forEach((it, i) => { if (i === 0) c.moveTo(it.x, it.y) c.lineTo(it.x, it.y) }) c.stroke() } const data = [{"

Charles使用教程【简易版】

Charles抓包教程 1、电脑安装charles 2、电脑打开charles后安装root证书 3、电脑信任证书 4、手机连接与电脑同一wifi 5、设置手机代理 wlan设置中将当前 wifi 的代理改成手动,主机名填电脑 ip,端口填8888 此时如果当前手机是第一次被你的电脑设备代理或者更换了wifi环境,那charles中没有记录手机的ip,此时charles会有一个弹窗,提示要不要允许,点击允许 6、手机下载charles证书 随后打开 uc 浏览器,搜索 chls.pro/ssl,会开始 chares 证书的下载,这里有个坑,如果你的手机设备是一次与当前电脑连接或者更换了 wifi 环境,但是刚才并没有请求allow的弹窗,这里是不会开始下载证书的,需要手动把当前手机设备的局域网 ip 添加到电脑 charles 中 输入完ip记得敲下回车临时保存一下,否则即使点击了「OK」,这个ip信息也不会被保存到设置中。生成一个有效的行记录后点击OK按钮, 随后再次到uc浏览器中搜索 chls.pro/ssl,证书将会自动开始下载。 如果还是无法安装证书,尝试在chls.pro/ssl前添加前缀 http://, 浏览器完全输入 http://chls.pro/ssl 会弹窗开始下载证书 7、手机配置安装证书 wlan中的高级设置,点击安装证书,去UCDownloads目录下找到刚才下载的证书,点击证书后重命证书,这样证书就安装好了,有可能会要输入密码或者指纹验证,验证就好。 抓不到包排查 1、需要关闭手机和电脑的 vpn,否则会走 vpn 代理,而不是 charles 2、确认电脑的 charles 证书处于生效状态,检查 charles 证书是否生效的步骤:mac 确认 charles 证书是否生效 3、红米/小米手机还需要在安全选项中配置 CA 证书,否则会提示 You may need to configure your browser or application to trust the Charles Root Certificate. See SSL Proxying in the Help menu.

Vite环境变量不生效

Vite使用环境变量,在项目中的import.meta.env.VITE_XXX显示undefined 搞到这一步的应该都清楚环境变量的配置了,就不多阐述了。默认只识别VITE开头的变量应该也不用多说。 VITE创建项目后就有了.env.development文件了,开发环境运行时默认使用该文件,但是在项目中就是读不出值undefined,只能读出默认项。 解决办法:删了该文件重创(有具体知道为什么要重创的请提点一下我,谢谢。我有空也会再研究研究,这个坑踩了我很久了)

采用simulink构建AWGN信道中分组码的BPSK数字通信系统

综合实验设计题5: 采用simulink构建AWGN信道中分组码的BPSK数字通信系统 1、实验要求: (1)构建在AWGN信道中,采用BPSK调制的分组差错控制编码方法的模型,并给出误码率性能。 (2)构建在AWGN信道中,采用FSK调制的分组差错控制编码方法的模型,并给出误码率性能。 (3)构建在AWGN信道中,采用QAM调制的分组差错控制编码方法的模型,并给出误码率性能。 2、 实验说明 (1)3个方向中任选一种完成实验 (2)分组差错控制编码方法自选,如:线性分组码(n,k);循环码(n,k);Hamming(n,k); RS (n,k);Golay(n,k)等 (3)给出各个模块的参数配置说明 (4)给出Eb/No(dB)与BER 误码性能关系图,包括理论误码性能和仿真实验误码性能。 (5)对所建模的系统性能进行分析说明。 3、实验步骤 (1)、构建在AWGN信道中,采用BPSK调制的分组差错控制编码方法的模型,并给出误码率性能。 (2)、采用循环码(31,16)进行差错控制编码。 (3)、各模块配置 随机生成二进制random integer generator Set size:设置为:2 延时模块Buffer Output buffer size 设置为:16 循环码BCH Encoder CodeWord length,N 设置为:31 Message length,K 设置为:16 信道噪声AWGN channel Eb/No设置为变量参数:EbNo Symbol period 设置为:1 误码率计算Error Rate Calculation Receive delay设置为:16 变量名称设置为:imout01和simout02 保存格式设置为:带时间的结构体 (4)、总体仿真图 (5)、给出Eb/No(dB)与BER 误码性能关系图,包括理论误码性能和仿真实验误码性能。 仿真代码: %作者:gxu.计算机与电子信息学院.通信201 clc clear all; ebno = 0:0.1:10;%%信噪比范围 snr = 10.^(ebno/10); %单位换算 for i = 1:length(ebno) EbNo = ebno(i); sim('BPSK.

吃饱没事做——用chatGPT生成图像缩放代码,使用双线性插值

这是一个 Verilog 的模块化代码,用于缩放图像。以下是对每行代码的注释解释: module image_resize( input clk, rst_n, input [31:0] image_in, // 输入图像 input h_sync_in, // 输入水平同步信号 input v_sync_in, // 输入垂直同步信号 output reg [31:0] image_out, // 输出缩放后图像 output reg h_sync_out, // 输出缩放后水平同步信号 output reg v_sync_out // 输出缩放后垂直同步信号 ); 该代码的模块名为 image_resize,有几个输入和输出端口,分别是:clk(时钟信号)、rst_n(复位信号)、image_in(输入图像)、h_sync_in(输入水平同步信号)、v_sync_in(输入垂直同步信号)、image_out(输出缩放后图像)、h_sync_out(输出缩放后水平同步信号)、v_sync_out(输出缩放后垂直同步信号)。其中,[31:0] 表示信号的位宽为 32 位。 parameter W_IN = 2400; parameter H_IN = 1080; parameter W_OUT = 1540; parameter H_OUT = 720; 定义一些参数,分别表示输入图像的宽度和高度、输出图像的宽度和高度。 wire [10:0] h_sync_end = 1547; // 行同步信号结束时机 wire [10:0] v_sync_end = 725; // 场同步信号结束时机 定义行同步信号和场同步信号在输出图像中的结束位置。

未匹配到本域名(www.xxx.com)有效授权码,请到PbootCMS官网获取

PbootCMS默认授权提示语句为: 未匹配到本域名(www.xxx.com)有效授权码,请到PbootCMS官网获取,并填写到网站后台"全局配置>>配置参数"中 sn修改办法 其实官方已经预制了免费的解决方案,只需要在网站根目录下新建一个sn.html的文件,里面编写自己的提示信息,比如请联系某某,这时候再访问未授权的域名,系统会自动调用sn.html并显示其中的内容。 程序修改办法 文件位置:/core/function/handle.php 搜索:parse_info_tpl()函数 将函数里面 $tpl_content = str_replace('{info}', $string, $tpl_content); 替换为: if (strpos($string, '未匹配到本域名') !== false) { $tpl_content = str_replace('{info}', '您当前域名未授权,请联系开发者获取授权!', $tpl_content); } else { $tpl_content = str_replace('{info}', $string, $tpl_content); }

基于docker搭建心跳开源系统,HertzBeat

1:HertzBeat赫兹跳动 是一个拥有强大自定义监控能力,无需 Agent 的开源实时监控告警工具。 集 监控+告警+通知 为一体,支持对应用服务,数据库,操作系统,中间件,云原生,网络等指标监控,阈值告警通知一步到位。 支持更自由化的阈值规则(计算表达式),邮件 Discord Slack Telegram 钉钉 微信飞书 短信 Webhook 等方式及时送达。 我们将Http,Jmx,Ssh,Snmp,Jdbc等协议规范可配置化,您只需配置YML就能使用这些协议去自定义采集任何您想要的指标。 您相信只需定义YML就能立刻适配一款K8s或Docker等新的监控类型吗? 2;开始搭建【前提有一台linux服务器,并搭建了docker】 3:只需要一条docker命令即可安装体验heartbeat docker run -d -p 1157:1157 --name hertzbeat tancloud/hertzbeat 安装成功后会生成 账户密码 4:通过ip:1157 直接在浏览器进行访问; 5:可以通过消息通知,配置钉钉webHook 机器人。同步到钉钉群里,实现预警通知功能。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/92acce69dac647aaa95cbb7a17ba599b.png

图形学中的抗锯齿讨论以及在unity中的应用

抗锯齿(Anti-Aliasing)是图形学中,很重要的一个部分。本文旨在做一些分析总结,并对平时不理解的细节,做了调研,但毕竟不是做GPU行家,所以有不对的地方,欢迎拍砖^^。 1 什么是锯齿 下图,是一个在unity中,不开启抗锯齿的情况下的渲染效果,可以看到,边沿区域,例如黄色块的边沿,有非常明显的锯齿效果。 接着, 我启用了抗锯齿功能(URP设置里,有个Anti Aliasing),渲染效果如下,边沿区域,有一些过度颜色,不会那么生硬的,要么黄,要么灰了! 2 锯齿原因 原因是:光栅化阶段,执行片元着色器时,采色要么采A色,要么采B色。例如上面的黄色区域,采样时,要么就黄色,要么就某种灰色了。所以边界区域,颜色变化比较剧烈,看起来像锯齿。 再回溯一下,光栅化阶段,最重要2个部分(更多请参考 GPU 渲染管线与着色器 大白话总结): 三角形设置与遍历 + 片元着色器。 三角形设置与遍历,简单的说,是找出所有三角形都覆盖哪些像素,然后生成对应的片元。 具体而言,是判断像素的中心点,是否在三角形内。判断方法,请参考叉乘在图形学中的几何意义 ---- 判断一个点是否在三角形内。如果在三角形内,就生成一个片元。 当然了,肯定存在不同三角形对应同一个屏幕像素,那对应的2个片元,其深度值z不一样。z值最小的,在最上面,z值大的片元,在下面,如果上面没有透明色,那下面的片元,就不需要执行片元着色器了。 anyway,有效的片元,总归要执行片元着色器(fragment shader,又叫pixel shader),对该片元着色。着色后,对于一些边界区域,颜色变化如果很大,就会看起来有锯齿。 例如下图,根据像素中心是否在三角形内的原则,采样后的三角形,如下,锯齿非常明显。 3 抗锯齿的方法 抗锯齿的目标,就是让颜色剧烈变化的像素区域,有一些过度色,不那么生硬! 在图形学中,有几种主流的抗锯齿方法,常用的包括: 超级采样抗锯齿(Super-Sample Anti-Aliasing,SSAA): 渲染管线阶段:光栅化阶段。简要介绍:SSAA在渲染过程中使用比实际屏幕分辨率更高的分辨率进行渲染,然后再将图像缩小到目标分辨率。这样做会导致在渲染过程中对于每个像素执行更多次的片元着色器,从而获得更平滑的图像。特点:效果好,消耗性能。 多重采样抗锯齿(Multisample Anti-Aliasing,MSAA): 渲染管线阶段:光栅化阶段。简要介绍:对SSAA的优化,在每个像素位置进行多次采样,然后根据采样结果进行平均。特点:比SSAA节约性能,但效果差一些。 快速近似抗锯齿(Fast Approximate Anti-Aliasing,FXAA): 渲染管线阶段:后期处理阶段。简要介绍:不管什么三角形了,只关心最终图像。通过对图像进行分析,检测锯齿和边缘走样,并应用特定的滤波器来减少锯齿效果。FXAA是一种快速而低成本的抗锯齿技术,但可能会导致细节损失和模糊。 优点:节约性能。特点:最节约性能。 子像素采样抗锯齿(Subpixel Morphological AA, SMAA): 渲染管线阶段:后期处理阶段。简要介绍:都是对像素左侧和上侧的边进行边缘检测,但又考虑了局部的像素对比,提取更多几何信息,保留不该模糊的边缘。 帧间抗锯齿(Temporal AA, TAA) 渲染管线阶段:后期处理阶段。简要介绍:通过加权混合相邻多帧达到抗锯齿效果,从理论上解释就是将计算量分摊(Amortized)至多帧的超采样 下文对一些抗锯齿方法做一些详细介绍。 3.1 SSAA简介 既然叫超采样,顾名思义,就是增加采样点了。 一个像素本来采1个中心点,现在采N个: 例如上面的最左边像素,本来像素中心不在三角形内,就没颜色。现在像素内取4个点采,就有1个子采样点,在三角形内了。 实际落地办法,先弄个虚拟的输出画面buffer,分辨率是最终输出画面的N倍,例如4个采样点,就提高2倍。然后渲染到该buffer上。然后,再同比缩小到实际输出画面上。 缩小后,一个实际像素的颜色,会取4个子采样点的像素的平均值。 所以,实际效果会这样: 在边沿区域,有了较好的过度色。例如最左下方,本来没颜色,现在color = 1/4 * yellow_color,有了一些过度了。 注意,4个子采样点,都是独立运算的,那就可能发生4个子采样点,得到的颜色值不一样。 那最终像素的颜色,也是根据多种颜色的平均值哦。 好了,问题是解决了,但是增加了计算量,具体而言,是增加了片元数量。 例如,没有SSAA,上面的三角形,需要12个片元,执行12次fragment shader。但如果用了SSAA,需要49个片元,意味着要执行49次fragment shader了。真实游戏中,三角形数量成千上万个,计算量增加就很恐怖了!

echarts——关系图

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> html, body { width: 100%; height: 100%; } .myChart { width: 100%; height: 900px; margin: 0 auto; } </style> </head> <body> <div> <div id="myChart" class="myChart" /> </div> <script src="./echart/echarts.min.js"></script> <script> function changeData() { var data, linksData data = [ { name: '玛丽亚', symbolSize: 100, value:40 }, { name: '宏宇', symbolSize: 50, value:14 }, { name: '任小仙', symbolSize: 60, value:22 } ] linksData = [{ source: '玛丽亚', target: '宏宇', relationshipName: '朋友' }, { source: '玛丽亚', target: 'imipramine', relationshipName: '朋友' }, { source: '宏宇', target: '任小仙', relationshipName: '朋友' }, { source: '玛丽亚', target: '任小仙', relationshipName: '同事' }, { source: '玛丽亚', target: '任小仙', relationshipName: '家人' }, { relationshipName: '战友', target: '玛丽亚', source: '任小仙' }, { relationshipName: '战友', target: '玛丽亚', source: '宏宇' }] var arr = [] for (const i in linksData) { linksData[i].

linux运维进阶:代码上线之SonarQube安装

01.sonarqube介绍 1. SonarQube基础java开发,需安装open JDK8版本 2. SonarQube需要依赖MySQL数据库,至少5.6版本以上 3. SonarQube的小型实例至少4G内存,如果大型实例需要16G内存 02.安装软件 yum -y install git java unzip wget 03.安装数据库 右键复制链接地址下载到sonar服务器中 wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm rpm -ivh mysql80-community-release-el7-3.noarch.rpm 更改默认安装版本为5.6 enabled=1 vim /etc/yum.repos.d/mysql-community.repo [mysql56-community] name=MySQL 5.6 Community Server baseurl=http://repo.mysql.com/yum/mysql-5.6-community/el/7/$basearch/ enabled=1 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql [mysql80-community] name=MySQL 8.0 Community Server baseurl=http://repo.mysql.com/yum/mysql-8.0-community/el/7/$basearch/ enabled=0 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql 下一步安装MySQL5.6 yum install mysql-community-server -y service mysql start 配置数据库密码 mysqladmin -uroot passwd xxx123 创建sonar库 mysql -uroot -plizhenya123 -e "CREATE DATABASE sonar DEFAULT CHARACTER SET utf8;"

MySQL数据库存储过程(基础)

存储过程是什么 是一组为了完成特定功能的SQL 语句集合 经编译后保存在数据库中 通过指定存储过程的名字并给出参数的值 MySQL5.0版本开始支持存储过程,使数据库引擎更加灵活和强大 可带参数,也可返回结果 可包含数据操纵语句、变量、逻辑控制语句等 优点: 减少网络流量 提升执行速度 减少数据库连接次数 安全性高 复用性高 缺点: 可移植性差 批量执行SQL操作的方法 DELIMITER指令修改SQL语句结束符 mysql> SELECT USER(); #;结束SQL语句 +----------------+ | USER() | +----------------+ | root@localhost | +----------------+ 1 row in set (0.01 sec) mysql> DELIMITER // #定义//为SQL语句结束符 mysql> SELECT USER()// #测试 +----------------+ | USER() | +----------------+ | root@localhost | +----------------+ 1 row in set (0.00 sec) mysql> DELIMITER ; #定义;为SQL语句结束符 mysql> SELECT USER(); #测试 +----------------+

vue3组件通信五种方式

方式一:props props是实现父组件向子组件传递信息,props的数据是只读的。 使用实例: 父组件: <template> <div class="box"> <h1>我是父组件</h1> <hr /> <Child info="我是父组件参数" :money="money"></Child> </div> </template> 子组件:需要使用到defineProps方法去接受父组件传递过来的数据 <script setup lang="ts"> //defineProps是Vue3提供方法,不需要引入直接使用 let props = defineProps(['info','money']); //数组|对象写法都可以 </script> 方法二:全局总线事件 全局事件总线$bus可以实现兄弟之间的通信 实例: 子组件1:接受子组件2传递的参数 <script setup lang="ts"> import $bus from "../../bus"; import { onMounted } from "vue"; //组件挂载完毕的时候绑定一个事件,受将接来兄弟组件传递的数据 onMounted(() => { $bus.on("money", (money) => { console.log(car); }); }); </script> 子组件2:给子组件1传递参数 <script setup lang="ts"> import $bus from '../../bus'; //点击按钮回调 const handler = ()=>{ $bus.emit('money',{money:"1个w"}); } </script> 方法3:v-model进行通信 相当于给子组件绑定props,同时也相当于绑定了自定义事件

vim使用技巧 多行注释、取消注释

1、背景 大家使用vim编辑器经常会遇到批量注释或取消注释的需求,本人亦是如此。写本文前参考了其他文章,感谢他们的好文。写该文的目的用于记录(防止遗忘)和分享。 2、总结(方便时间久了遗忘快速回忆) 块选择方法 vim多行内容批量注释: ①vim打开文档,光标放在批量注释行的首行第一字节。②按v进入,进入VISUAL模式。③按“ctrl+v”进入VISUAL BLOCK模式。④按大写“I”进入可编辑模式。⑤在光标所在位置插入#,然后双击“Esc”,实现行批量注释要求。 vim多行内容批量取消注释: ①ctrl + v 进入块选择模式,选中你要删除的行首的注释符号,注意// 要选中两个。②选好之后按d即可删除注释。 正则方法 批量添加注释 :起始行号,结束行号s/^/注释符/g 批量取消注释 :起始行号,结束行号s/^注释符//g 3、块选择模式 批量注释具体步骤 1)vim打开需要操作文件,光标放在需要注释内容的第一行,按v进入-- 可视(visual) --模式。(参考下图) 2)然后上下方向键选择需要注释的行。 3)按“ctrl+v”进入VISUAL BLOCK模式。 4)按大写“I”进入可编辑模式。 5)在光标所在位置插入#,然后双击“Esc”,实现行批量注释要求。 批量取消注释详细步骤 1)ctrl + v 进入块选择模式,选中你要删除的行首的注释符号,注意## 要选中两个。 2)选好之后按d即可删除注释。 4、正则替换 批量添加注释 方法::起始行号,结束行号s/^/注释符/g,参考下图。 :起始行号,结束行号s/^/注释符/g 批量取消注释 方法: :起始行号,结束行号s/^注释符//g 参考网址:https://www.cnblogs.com/huchong/p/12452607.html

Quartus II 集成开发环境的基本开发流程

目录 前言 一、建立一个工程 二、在一个工程下进行电路设计 三、编译 四、下载方式设置 五、通过ByteBlasterII下载电缆的Jtag口下载编译好的sof文件到目标板 前言 Quartus II是一款综合性PLD/FPGA开发软件,支持原理图、VHDL、VerilogHDL以及AHDL (Altera Hardware Description Language)等多种设计输入形式,内嵌自有的综合器以及仿真器,可以完成从设计输入到硬件配置的完整PLD设计流程。 一、建立一个工程 1.启动QuartusII 10.1后的运行界面如下: 2.选择File|New Project Wizard,启动(New Project Wizard),点击Next跳过Introduction,进入工程目录设置界面,如下图所示: 点击下图红色框提示区,弹出“浏览文件夹”提示框,找到硬盘的根目录位置(如C盘),再点击新建文件夹,作为整个工程的文件夹。(注意不要用中文名,一些未中文化的版本不支持中文)。 如下图,在C盘根目录建立了myfpgatest工程文件夹。 在第2行输入工程名,如下图所示: 3.单击“next>”按钮,得到如下界面,可以在File name 输入添加已设计好的电路。如没有单击“next>”按钮直接跳过。 4.单击“next>”按钮,启动(Family & Device Sectings),在Family下拉菜单选择Cyclone II,在 Show in Available device’list栏设置 Package->PQFP; Pin count->208;Speed grade->Any。在Avilable devices单选框选择EP2C8Q208C8(单击选择)。 5.单击 Finish,工程目录即创建完毕。 二、在一个工程下进行电路设计 1.选择File|New ,单击Block Diagram/Schematic File 2.单击OK按钮,得到一张空白的模块图形设计文件,在空白处双击左键,得到如下对话框,输入器件名称,如调入xor,单击ok按钮即可。 3.按照上述方法设计好电路后,点击File|Save 菜单保存,保存文件名称可以自己定义。 三、编译 1.编译:一个电路设计好后,即可点击Processing|Start ComPilation进行编译完成后,会有类似如下界面,表示编译成功。 2.指定IO输出管脚:单击Assignments|Pinplanner,出现如下界面,在Location位置选择输出管脚。 如本图把out指定到PIN_173作为输出,分配好管脚后,再重复一次编译工作。 四、下载方式设置 1.单击Tools|Programer,出现如下界面。 2.硬件设置(Hardware Setup):如果没有设置下载方式,则需要进行这一步的设置。单击Hardware Setup按钮,则出现如下对话框. 单击Add Hardware 按钮后:出现如下对话框,选择ByteBlasterII后点击OK按钮。 这时Hardware Setup对话框的Avaliable hardware items出现了硬件列表。在Currently selected haredware下拉菜单选择ByteBlasterII[LPT1],单击close按钮即可。

Linux 安装Docker教程

目录 Docker 简介 什么是Docker Docker理念 Docker用途 centos安装docker 安装docker 启动docker 修改docker数据目录 普通用户赋权Docker Docker 简介 什么是Docker Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。 一个完整的Docker有以下几个部分组成: DockerClient客户端Docker Daemon守护进程Docker Image镜像DockerContainer容器 Docker理念 Docker是基于Go语言实现的云开源项目。 Docker的主要目标是“Build,Ship and Run Any App,Anywhere”,也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的APP(可以是一个WEB应用或数据库应用等等)及其运行环境能够做到“一次封装,到处运行”。 Linux 容器技术的出现就解决了这样一个问题,而 Docker 就是在它的基础上发展过来的。将应用运行在 Docker 容器上面,而 Docker 容器在任何操作系统上都是一致的,这就实现了跨平台、跨服务器。只需要一次配置好环境,换到别的机子上就可以一键部署好,大大简化了操作 Docker用途 提供一次性的环境。比如本地测试他人的软件、持续集成的时候提供单元测试和构建的环境提供弹性的云服务。因为Docker容器可以随开随关,很适合动态扩容和缩容组件微服务架构。通过多个容器,一台机器可以跑多个服务,因此在本机就可以模拟出微服务架构。 centos安装docker 安装docker 更新yum工具 yum install -y yum-utils \ device-mapper-persistent-data \ lvm2 --skip-broken 结果如下图所示: 2.更新镜像源 # 设置docker镜像源 yum-config-manager \ --add-repo \ https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo sed -i 's/download.docker.com/mirrors.aliyun.com\/docker-ce/g' /etc/yum.repos.d/docker-ce.repo yum makecache fast 如下图: 3.安装docker yum install -y docker-ce 如下图:

Python可视化神器Seaborn入门系列——kdeplot

Seaborn是基于matplotlib的Python可视化库。 它提供了一个高级界面来绘制有吸引力的统计图形。Seaborn其实是在matplotlib的基础上进行了更高级的API封装,从而使得作图更加容易,不需要经过大量的调整就能使你的图变得精致。但应强调的是,应该把Seaborn视为matplotlib的补充,而不是替代物。 Seaborn安装 pip install seaborn 安装完Seaborn包后,我们就开始进入接下来的学习啦,首先我们介绍kdeplot的画法。 kdeplot(核密度估计图) 核密度估计(kernel density estimation)是在概率论中用来估计未知的密度函数,属于非参数检验方法之一。通过核密度估计图可以比较直观的看出数据样本本身的分布特征。具体用法如下: seaborn.kdeplot(data,data2=None,shade=False,vertical=False,kernel='gau',bw='scott', gridsize=100,cut=3,clip=None,legend=True,cumulative=False,shade_lowest=True,cbar=False, cbar_ax=None, cbar_kws=None, ax=None, **kwargs) 我们通过一些具体的例子来学习一些参数的用法: 首先导入相应的库 %matplotlib inline #IPython notebook中的魔法方法,这样每次运行后可以直接得到图像,不再需要使用plt.show() import numpy as np #导入numpy包,用于生成数组 import seaborn as sns #习惯上简写成sns sns.set() #切换到seaborn的默认运行配置 绘制简单的一维kde图像 x=np.random.randn(100) #随机生成100个符合正态分布的数 sns.kdeplot(x) cut:参数表示绘制的时候,切除带宽往数轴极限数值的多少(默认为3) sns.kdeplot(x,cut=0) cumulative :是否绘制累积分布 sns.kdeplot(x,cumulative=True) shade:若为True,则在kde曲线下面的区域中进行阴影处理,color控制曲线及阴影的颜色 sns.kdeplot(x,shade=True,color="g") vertical:表示以X轴进行绘制还是以Y轴进行绘制 sns.kdeplot(x,vertical=True) 二元kde图像 y=np.random.randn(100) sns.kdeplot(x,y,shade=True) cbar:参数若为True,则会添加一个颜色棒(颜色帮在二元kde图像中才有) sns.kdeplot(x,y,shade=True,cbar=True) 举例说明二元kde图像 定义了一个函数 def plot_distribution_target(df, target, cols): dist_cols=5 dist_rows=len(cols) plt.figure(figsize=(5*dist_cols,5*dist_rows)) i=1 for col in cols: ax=plt.subplot(dist_rows,dist_cols,i) ax=sns.kdeplot(df[df[target]==1][col],color='Red',shade=True)#train_data ax=sns.

MySQL数据库视图(一看就会!!!)

视图是什么 视图本质上是个虚拟的表,只有表结构,数据来源于真实的表 通常用于查询场景 为什么要用视图 视图操作 视图被创建后可以象普通表来使用,主要是查询 对视图操作基表会改变,反之亦然 视图相关练习 [root@server51 ~]# mysql -hlocalhost -uroot -p'123qqq...A' #登录MySQL服务 mysql> CREATE DATABASE viewdb; #创建练习库 创建视图 mysql> CREATE VIEW viewdb.v1 AS -> SELECT name,uid,shell FROM tarena.user; #创建视图引用原表字段名 mysql> CREATE VIEW viewdb.v2(用户名,用户id,解释器) AS -> SELECT name,uid,shell FROM tarena.user; #创建视图自定义字段名 mysql> CREATE VIEW viewdb.emp(name,email,dept_name) AS -> SELECT e.name,e.email,d.dept_name FROM -> tarena.employees AS e INNER JOIN tarena.departments AS d -> ON e.dept_id=d.dept_id; #联表视图 mysql> SHOW TABLES FROM viewdb; #查看指定库下表(视图是特殊表)

docker配置远程访问

根据公司业务需求,需要远程访问docker,就看了一下docker的官方文档,发现有2种方式可以配置远程连接。先试了第二种方法,执行systemctl restart docker一直报错,没找到具体的原因。按第一种方式来配置,可以成功配置远程访问。 具体步骤: vim /usr/lib/systemd/system/docker.service 修改ExecStart这一行,在后面加上-H tcp://0.0.0.0:2375 注意ip这里要写0.0.0.0,不要写127.0.0.1,写127.0.0.1远程访问会失败 2.systemctl daemon-reload 3.systemctl restart docker 4.在本地浏览器执行 http://ip:2375/version测试是否能访问

Lua学习笔记:浅谈对闭包的认识

前言 本篇在讲什么 我们从几个方面简单认识和理解lua的闭包 本篇适合什么 适合初学Lua的小白 本篇需要什么 对Lua语法有简单认知 依赖Lua5.1的环境 依赖Sublime Text3编辑器 本篇的特色 具有全流程的图文教学 重实践,轻理论,快速上手 提供全流程的源码内容 ★提高阅读体验★ 👉 ♠ 一级标题 👈 👉 ♥ 二级标题 👈 👉 ♣ 三级标题 👈 👉 ♦ 四级标题 👈 目录 ♠ 什么是闭包♠ lua的闭包♥ 词法定界♥ 第一类值♥ 上值(upvalue)♥ 总结 ♠ 推送♠ 结语 ♠ 什么是闭包 闭包就是能够读取其他函数内部变量的函数 可以理解为,闭包就是定义在函数内部的函数 本质上,闭包是将函数内部和函数外部连接起来的桥梁 例:以下述代码为例 lua方法newCounter内包含了一个局部变量count,在作用域的限制下,只有方法体内可以访问count,闭包可是让我们从外部访问count function newCounter() local count = 0 end ♠ lua的闭包 首先我们需要了解几个关于Lua语法的特性,对我们理解闭包有帮助 在Lua语言中,函数是严格遵循词法定界的第一类值 并且函数作为第一类值,能够逃逸出它们变量的原始定界范围 ♥ 词法定界 function B() local b1 = 1 local b2 = 2 function A() print(b1+b2) end end 当编写一个被其他函数B包含的函数A时,被包含的函数A可以访问包含其的函数B的所有局部变量,我们将这种特性称为词法定界

Mysql索引(一看就会!!!)

老规矩先上理论知识~ 索引是什么 索引是为了加速查询的一种数据结构 类似于书的目录,所有的数据类型都可以被索引 为快速查找数据而排好序的一种数据结构 三种索引结构:Btree,B+Tree,Hash 优点: 提高mysql检索速度 索引减小了服务需要扫描的数据量 避免排序和临时i表 缺点: 降低更新表的速度 会占用磁盘空间的索引文件,如果创建了很多组合索引,索引文件会膨胀很快 如果数据列包含太多重复内容,建立建立索引没有太大实际效果 对于非常小的表,大部分情况下简单的全表扫描更高效,索引对于数据量越大,索引效果越明显 索引分类: 功能 普通索引 唯一索引 全文索引 作用字段 单列索引 多列索引 理论说的差不多了,那接下开始操作吧~ 索引操作 创建索引 mysql> CREATE TABLE execdb.t11(name CHAR(20),uid INT, shell CHAR(20),INDEX(name),INDEX(uid),INDEX(shell)); #建表时创建索引 #命令——在哪个库. 创建的表名——字段设计——创建的索引字段index(字段名) mysql> DESC execdb.t11; #查看表结构MUL 语法格式: 已有表添加索引 语法格式: mysql> CREATE TABLE execdb.t12(name CHAR(20),uid INT, shell CHAR(20)); #建表 mysql> DESC execdb.t12; #查看表结构(key位置为空代表没有索引) mysql> CREATE INDEX name ON execdb.t12(name); #添加索引 # 命令——索引名字——on对哪个库表的哪个字段添加索引 mysql> DESC execdb.t12; #查看表结构(key字段有MUL代表有索引)

java基础之对象类型

POJO:Plain Ordinary Java Object 简单的Java对象 实际就是普通JavaBeans,是为了避免和EJB混淆所创造的简称。通指没有使用Entity Beans的普通java对象,可以把POJO作为支持业务逻辑的协助类。 POJO实质上可以理解为简单的实体类,顾名思义POJO类的作用是方便程序员使用数据库中的数据表,对于广大的程序员,可以很方便的将POJO类当做对象来进行使用,当然也是可以方便的调用其get,set方法。POJO类也给我们在struts框架中的配置带来了很大的方便。 1 .POJO持久化之后==〉PO (在运行期,由Hibernate中的cglib动态把POJO转换为PO,PO相对于POJO会增加一些用来管理数据库entity状态的属性和方法。PO对于programmer来说完全透明,由于是运行期生成PO,所以可以支持增量编译,增量调试。) 2 .POJO传输过程中==〉DTO 3 .POJO用作表示层==〉VO PO:persistant object 持久对象 1 .有时也被称为Data对象,对应数据库中的entity,可以简单认为一个PO对应数据库中的一条记录。 2 .在hibernate持久化框架中与insert/delet操作密切相关。 3 .PO中不应该包含任何对数据库的操作。 就是在Object/Relation Mapping框架中的Entity,po的每个属性基本上都对应数据库表里面的某个字段。完全是一个符合Java Bean规范的纯Java对象,没有增加别的属性和方法。持久对象是由insert数据库创建,由数据库delete删除的。基本上持久对象生命周期和数据库密切相关。 DTO(TO):Data Transfer Object 数据传输对象 1 .用在需要跨进程或远程传输时,它不应该包含业务逻辑。 2 .比如一张表有100个字段,那么对应的PO就有100个属性(大多数情况下,DTO 内的数据来自多个表)。但view层只需显示10个字段,没有必要把整个PO对象传递到client,这时我们就可以用只有这10个属性的DTO来传输数据到client,这样也不会暴露server端表结构。到达客户端以后,如果用这个对象来对应界面显示,那此时它的身份就转为VO。 VO:view object 值对象 视图对象,用于展示层,它的作用是把某个指定页面(或组件)的所有数据封装起来。 1 .主要对应页面显示(web页面/swt、swing界面)的数据对象。 2 .可以和表对应,也可以不,这根据业务的需要。 BO :business object 业务对象 封装业务逻辑为一个对象(可以包括多个PO,通常需要将BO转化成PO,才能进行数据的持久化,反之,从DB中得到的PO,需要转化成BO才能在业务层使用)。 关于BO主要有三种概念 1 、只包含业务对象的属性; 2 、只包含业务方法; 3 、两者都包含。 在实际使用中,认为哪一种概念正确并不重要,关键是实际应用中适合自己项目的需要。 这个对象可以包括一个或多个其它的对象。 比如一个简历,有教育经历、工作经历、社会关系等等。 我们可以把教育经历对应一个 PO ,工作经历对应一个 PO ,社会关系对应一个 PO 。 建立一个对应简历的 BO 对象处理简历,每个 BO 包含这些 PO 。 这样处理业务逻辑时,我们就可以针对 BO 去处理。

SQL Server数据库 笔记----对表的查询

操作数据之插入数据 对表的操作:插入,更新,删除 1.单条数据插入 --1) insert (into) 表名(列名,列名......) values(值,值......) --2) insert 表名(列名......) select 值...... 2.多条插入 一次性插入多条 批量插入操作 --1) insert into 表名(列名1,列名2......) values (值1,值2......),(值1,值2......),(值1,值2......)...... --2)union去除,union all允许重复 union all 效率比 union 高 insert 表名(列名1,列名2......) select (值1,值2......) union select(值1,值2......) union ...... select(值1,值2......) 3.克隆表数据 将一张表的数所复制到另一张表 --1)目标表在数据库中已经存在 insert into 目标表名(目标表中列名) select 源表中列名 from 源表 --2)目标表之前数据库中不存在,执行操作时自动创建 select 源表中列名 into 新表--目标表 from 源表 操作数据之更新删除数据 1.更新数据 update update 表名 set 列名=值,列名=值 where 标识列=值 (and | or)条件 --修改的某一列 注:主键不可以修改

latex各类符号(红心、方块、五角星等)集合

找到一个网站,汇集了一些latex里常用的特殊symbol: 更新: 询问ChatGPT之后的结果: "$\spadesuit$": ♠ "$\clubsuit$": ♣ "$\diamondsuit$": ♦ "$\heartsuit$": ♥ "$\star$": ★ "$\sharp$": ♯ "$\lozenge$": ◊ "$\triangle$": △ "$\circledast$": ⊛ "$\bigstar$": ✪ "$\checkmark$": ✓ "$\bullet$": • "$\ast$": * "$\aleph$": ℵ "$\natural$": ♮ "$\oplus$": ⊕ "$\ominus$": ⊖ "$\otimes$": ⊗ "$\odot$": ⊙ "$\oslash$": ⊘ "$\dagger$": † "$\ddagger$": ‡ "$\S$": § "$\P$": ¶

前端Vue:权限管理,给角色分配权限

👉前端-Vue权限控制,菜单权限,按钮权限_一人创客的博客-CSDN博客 目录 介绍: 前端权限的概念: 前端权限的意义: Vue权限管理的代码实现: 菜单 刷新界⾯菜单消失 标识⽤户名, ⽅便查看当前⽤户 退出登陆: 界面: 1.判断当前是否登陆 2.控制是否可以访问角色界面 (不太理解) 按钮: 请求和响应: 请求控制 响应控制 总结(重要): 菜单: 界面: 按钮控制 请求和响应控制 介绍: 前端权限的概念: 前端权限的控制本质上来说, 就是控制前端的 视图层的展示和前端所发送的请求。 前端权限的实现必须要后端提供数据⽀持, 否则⽆法实现。返回的权限数据的结构,前后端需要沟通协商, 怎样的数据使⽤起来才最⽅便. 前端权限的意义: 如果仅从能够修改服务器中数据库中的数据层⾯上讲,确实只在后端做控制就⾜够了, 那为什么越来越多的项⽬也进⾏了前端权限的控制, 主要有这⼏⽅⾯的好处: 降低⾮法操作的可能性 不怕贼偷就怕贼惦记, 在⻚⾯中展示出⼀个 就算点击了也最终会失败 的按钮, 势必会增加有⼼者 ⾮法操作的可能性 尽可能排除不必要请求,减轻服务器压⼒ 没必要的请求, 操作失败的请求, 不具备权限的请求, 应该压根就不需要发送, 请求少了, ⾃然也会减轻服务器的压⼒ 提⾼⽤户体验 根据⽤户具备的权限为该⽤户展现⾃⼰权限范围内的内容,避免在界⾯上给⽤户带来困扰, 让⽤户专注于分内之事 Vue权限管理的代码实现: 菜单 在登录请求中, 会得到权限数据, 当然, 这个需要后端返回数据的⽀持. 前端根据权限数据, 展示对应的菜单.点击菜单,才能查看相关的界⾯. //查看登陆之后获取的数据 { "data": { "id": 500, "rid": 0, "

SpringMVC中的控制器是什么?如何创建一个控制器?

在SpringMVC中,控制器是处理客户端请求的组件。它接收请求并执行相应的业务逻辑,然后返回处理结果和视图信息。 创建一个控制器的步骤如下: 创建一个Java类,并使用@Controller注解标记。 在类中定义一个处理方法,并使用@RequestMapping注解标记。 处理方法接收HTTP请求并执行相应的业务逻辑,然后返回一个ModelAndView对象。 在ModelAndView对象中设置模型数据和视图信息。 例如,下面是一个简单的控制器示例: @Controller public class HelloController { @RequestMapping("/hello") public ModelAndView hello() { ModelAndView modelAndView = new ModelAndView("hello"); modelAndView.addObject("message", "Hello, SpringMVC!"); return modelAndView; } } 在上面的示例中,控制器接收一个HTTP请求,并返回一个ModelAndView对象,其中包含了一个名为“message”的模型数据和一个名为“hello”的视图信息。

Linux重定向输出

1.输出类型: 1)标准输出:在Linux中每当我们敲完一个命令后他会有相对应的提示 例如:echo "123"是将123输出到控制台,这是一条正确的命令所以他会在控制台输出 123 这是系统默认的标准输出,当我们重定向之后它就会输出到我们重定向的位置。 2)标准错误输出:同样在Linux中我们敲完一条不存在或者错误的命令时,系统也会有相应的提示输出到屏幕上 例如: [root@rhcsa ~]# test111 bash: test111: command not found... 他会将错误提示输出到控制台,这就是标准错误输出 2.三种重定向方式 1)将标准输出和标准错误输出重定向到同一文件中 echo "123" &> info.txt test111 &> info.txt echo "123" &> info.txt 表示将echo的标准输出重定向到info.txt文件中, 其中( &> )表示覆盖重定向,就是每次重定向的输出会覆盖上一次的重定向输出 test111 &> info.txt 表示将标准错误输出重定向到文件info.txt中。 echo"123"与test111只是两个例子一个表示标准输出,一个表示标准错误输出 2)将标准输出重定向到文件info.txt中,再将标准错误输出重定向到标准输出中 echo "123" > info.txt 2>&1 test111 > info.txt 2>&1 3)将标准错误输出重定向到文件,再将标准输出重定向到标准错误输出 echo "123" 2> info.txt 1>&2 test111 2> info.txt 1>&2

Sql Server增加字段、修改字段、修改类型、修改默认值

1、修改字段名: alter table 表名 rename column A to B 2、修改字段类型: alter table 表名 alter column 字段名 type not null 3、修改字段默认值 alter table 表名 add default (0) for 字段名 with values 如果字段有默认值,则需要先删除字段的约束,在添加新的默认值, select c.name from sysconstraints a inner join syscolumns b on a.colid=b.colid inner join sysobjects c on a.constid=c.id where a.id=object_id('表名') and b.name='字段名' 根据约束名称删除约束 alter table 表名 drop constraint 约束名 根据表名向字段中增加新的默认值 alter table 表名 add default (0) for 字段名 with values

生成秘钥及配置gitlab

上周入职配置了gitlab拉取项目,当时说要把操作流程记下来,但是后来熟悉需求又忘记了,今天在整理一下,如果有错误希望大家帮忙提出! (开通gitlab账号,先咨询所在公司的gitlab管理员开通后,本地Git仓库和gitlab仓库仍然不能传输项目,原因是要通过SSH加密才能传输,所以需要让gitlab认证本地的SSH Key,认证之前,则先使用Git生成SSH Key) 1.本地修改密码 查看当前用户名、邮箱、密码 git config user.name git config user.email git config user.password 修改用户名、邮箱、密码方式: git config --global user.name "新的用户名" git config --global user.email "新的邮箱" git config --global user.password "新的密码" 2.这时候还不能直接拉取项目,需要生成秘钥信息 ssh秘钥默认在账户主目录下,id_rsa.pub是公钥,id_rsa是秘钥,如果有这两个文件就不需要创建秘钥了,如果没有的话,需要用ssh-keygen来创建 在.ssh目录下右键打开git bash,没有ssh目录可以手动创建,或者在其他目录下操作生成秘钥:ssh-keygen -t rsa -C "123@youxiang.com(这里需要是gitlab中的邮箱)",然后会提示输入密码执行完后,会在.ssh目录下生成秘钥文件 3.在gitlab中添加秘钥 登录gitlab平台(使用申请的gitlab账号登录)添加秘钥,搜索ssh,进入ssh keys,然后点击add ssh key,将前面生成的id_rsa.pub中的内容粘贴到key对应的框中,点击add keys即可 这样就配置好了,接下来可以去拉取代码测试一下 粘贴项目路径,然后git clone 地址即可,第一次拉取需要确认秘钥信息,输入yes即可,项目拉取完成就可以打开使用了

FIFO的工作原理及其设计

1.简介 FIFO( First Input First Output)简单说就是指先进先出。FIFO存储器是一个先入先出的双口缓冲器,即第一个进入其内的数据第一个被移出,其中一个口是存储器的输入口,另一个口是存储器的输出口。 对于单片FIFO来说,主要有两种结构:触发导向结构和零导向传输结构。触发导向传输结构的FIFO是由寄存器阵列构成的,零导向传输结构的FIFO是由具有读和写地址指针的双口RAM构成。 FIFO与普通RAM存储器的区别是没有外部读写地址线(指针),使用方便,但缺点是只能顺序写入数据和读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。 1.1.功能 FIFO存储器是系统的缓冲环节,主要有几方面的功能: 1)对连续的数据流进行缓存,防止在进机和存储操作时丢失数据; 2)数据集中起来进行进栈和存储,可避免频繁的总线操作,减轻CPU的负担; 3)允许系统进行DMA操作,提高数据的传输速度。这是至关重要的一点,如果不采用DMA操作,数据传输将达不到传输要求,而且大大增加CPU的负担,无法同时完成数据的存储工作。 1.2.用途 1.2.1.跨时钟域多bit数据传输 解决一个系统多个时钟所带来的问题:异步时钟之间的接口电路。异步FIFO是解决这个问题的一种便捷简单的方案,使用异步FIFO可以在两个不同时钟系统之间快速方便地传输实时数据。 1.2.2.达到数据匹配问题(读写位宽不一致) 对于不同宽度的数据接口也可以使用FIFO,例如单片机的8位输出而DSP可能是16位输入,在单片机与DSP连接时就可以使用FIFO来达到数据匹配的目的。 1.3.主要参数 宽度(WIDTH):FIFO每个地址的数据位宽(W);深度(DEEPTH):FIFO可以存储多少个W位的数据;满(full)标志:FIFO已满或将满时,会输出一个对写操作的反压信号,以阻止被继续写入数据而溢出;空(empty)标志:FIFO已空或将空时,会输出一个对读操作的反压信号,以避免被继续读出无效数据;读/写时钟:读/写操作所遵循的时钟,每个时钟沿触发。 根据FIFO工作的时钟域分为同步/异步FIFO。同步FIFO是指读时钟和写时钟为同一个时钟在时钟沿来临时同时发生读写。异步FIFO读写时钟不一致,读写相互独立。 读写指针即读写地址,当前读/写操作完成后,指针自动加一指向下一个地址(连续递增)。 写指针:总是指向下一个将要被写入的地址,复位时指向编号0的地址;读指针:总是指向下一个将要被读出的数据地址,复位时也指向编号0的地址且此时数据无效; 2.工作原理 2.1.空满标志 2.1.1.读空信号(rd_empty) 一般情况下当读写指针相等时,表明FIFO已空,这种情况发生在复位操作时或当读指针读出FIFO中最后一个有效数据时(即读指针追赶上写指针),此时读空信号有效,如下左图: 2.1.2.写满信号(wr_full) 当读写指针再次相等时,即写指针转了一圈又折回来(wrapped around)从起始低位追上了读指针(写比读快),此时表明FIFO已满,如上右图: 2.2.空满判断机制 2.2.1.同步fifo空满判断 方案一:extra bit 深度为的FIFO其地址位宽为n,若数据位宽为W则该FIFO的容量为N*W bits。 现在在指针添加1个extra bit即地址的MSB,使其变为n+1 bits,该extra bit用来指示读/写指针是否连续递增并越过了FIFO的最后一个地址,若越过则该MSB加1,其他位清零。例如深度为8的fifo,需要采用1+3bits的地址位宽,MSB作为指针折回标志,低3bits作为地址。 那么判断机制(读指针读出FIFO最后一个有效数据后即会停止递增)为: ①如果两个指针的MSB不同,就说明写指针比读指针多折回一次,此时若除开MSB以外的地址位相等,则表示FIFO已满; ②如果两个指针的MSB相同,就说明读写指针的折回次数相同,若其他地址位相等,则表示读写指针完全相等,FIFO已空。 方案二:设置数据计数器 设置一个data_counter,当写使能有效时数据计数器加1,每读出一个数据时该计数器又减1。如此,当data_counter=0时FIFO为空,data_counter=FIFO深度时表明已满。 缺点:计数器会占用额外资源,当FIFO较大时,可能会降低FIFO的读写速度。 2.2.2.异步fifo空满判断 判断步骤如下: ①地址指针采用二进制(binary)+extra bit ②二进制指针转gray码后跨时钟域同步做比较 当读写指针采用二进制表示且读写操作属于异步时钟时,读写指针做比较前需要先将其中一个指针同步到另一个指针的时钟域后再操作,直接同步这样容易产生亚稳态问题。 可以使用一个二进制转gray码的转换电路,将地址转换为对应的gray码后再同步到另一个时钟域,进行对比产生空满指示,如左下图: 例如1+3bits的二进制地址完全转换为gray后如右上图所示,此时空满标志不能按照原来二进制的方法来判断,gary码指针的空满判断标准如下: 空标志:gray码地址完全相等(包括MSB)。 满标志:高两位(MSB+次高位)不同,其余各位相同。 PS:二进制与格雷码互相转换 。 补充: ①同步方向产生保守的空满机制: 读指针同步到写时钟域:经过一定的同步时间后,此时同步后(写时钟域的)读指针小于或等于真实的(读时钟域)的读指针,而写指针是即时且真实的,空满判断机制可产生保守的“假写满”(正确且安全设计)和错误的“读空”。 反之同理,总结:写时钟域产生正确的“假写满”,读时钟域产生正确的“假读空”。 ②由于读写异步快时钟域同步慢时钟域指针可能会漏采,不会影响空满判断逻辑: 举例读慢写快:写指针同步到读时钟域发生漏采,即读时钟域采样到的写指针小于真实的(写时钟域的)写指针,此时不会导致“读空判断逻辑”错误,也是保守且正确的。反之亦然。 3.FIFO代码设计示例 3.1.同步FIFO代码 同步FIFO由于没有跨时钟的操作,所以只需要使用二进制即可,不用格雷码操作。根据上面的分析,有两种方法进行表示full/empty状态,代码如下: //1、generate full/empty signal by addr assign full = (waddr_ptr == {~raddr_ptr[ADDR_WIDTH-1], radde_ptr[ADDR_WIDTH-2:0]}); assign empty = (waddr_ptr == raddr_ptr); //2、generate full/empty signal by conuter always @(posedge clk or negedge rst_n)begin if(!

Mysql 数据备份(详细教程)

为什么要备份 数据是企业生存的命脉 什么是备份 将数据另外保存一份 备份到哪里 通常采用异地保存 什么时候备份 备份的窗口期,通常是业务压力最低点 如何备份 备份方法 物理备份逻辑备份备份策略 完整备份增量备份差异备份备份三要素 BW:完成备份需要的时间RPO:客户可承受的最大数据丢失量RTO:客户可承受的最长停机时间 容灾级别 级别说明0无异地备份1有异地备份2实现热备份3在线恢复数据4定时备份数据5实时备份数据6零数据丢失 完整备份 物理备份(cp、tar、zip) ##物理备份及恢复测试:使用cp、tar、zip等命令对数据库磁盘文件进行备份 #server51操作 [root@server51 ~]# systemctl stop mysqld #停止MySQL服务 [root@server51 ~]# mkdir /bak #创建备份文件存储目录 [root@server51 ~]# tar -zcPf /bak/db.tar.gz /var/lib/mysql/* #对MySQL磁盘文件打包 [root@server51 ~]# ls /bak/ #确认备份成功 db.tar.gz [root@server51 ~]# rm -rf /var/lib/mysql/* #删除MySQL磁盘文件模拟数据丢失 [root@server51 ~]# tar -zxPf /bak/db.tar.gz -C / #解压备份数据,恢复数据 [root@server51 ~]# ls /var/lib/mysql/ #确认数据目录下有文件 [root@server51 ~]# chown -R mysql.mysql /var/lib/mysql/ #修改文件归属!!! [root@server51 ~]# systemctl start mysqld #启动服务测试数据 [root@server51 ~]# mysql -hlocalhost -uroot -p&apos;123qqq.

JVM黑马版:笔记、应用、速查

前言 由于工作中时常和JVM打交道,但是对JVM的体系缺乏系统深入了解。日前跟随b站上黑马程序猿的课程成体系地学习了JVM,结合工作中的实践写就了此笔记。 黑马原视频地址:https://www.bilibili.com/video/BV1yE411Z7AP 1、概述:什么是JVM 2、内存结构 学习概述图:会根据下图依次介绍之: 2.1 程序计数器 程序计数器线程私有的理解: 2.2 虚拟机栈 栈帧的概念:一次方法调用 每个方法需要的内存存放于栈帧,方法的局部变量也存放于栈帧 问题辨析 1,垃圾回收是否涉及栈内存? ​ 不会,栈内存就是一次次的方法调用所产生的栈帧内存,栈帧内存在每一次的方法调用结束后后被弹出栈,自动的被回收掉,不需要垃圾回收。 2,栈内存分配越大越好么? ​ 栈内存划分的越大会使得线程数变少,因为我们物理内存的大小是一定的 如果是static修饰,会被多个线程使用,需要考虑线程安全问题: 局部变量引用了对象,并逃离方法的作用范围,需要考虑线程安全 栈内存溢出(Stack Overflow) 栈帧过多导致内存溢出(案例:疯狂的递归调用) 栈帧过大导致内存溢出(不易出现,因为局部变量只占一点空间) 可以使用虚拟机参数:Xss 来设置栈区内存大小。 线程运行诊断 2.3 本地方法栈 native关键字 native关键字说明其修饰的方法是一个原生态方法,方法对应的实现不是在当前文件,而是在用其他语言(如C和C++)实现的文件中。Java语言本身不能对操作系统底层进行访问和操作,但是可以通过JNI接口调用其他语言来实现对底层的访问。 JNI是Java本机接口(Java Native Interface),是一个本机编程接口,它是Java软件开发工具箱(java Software Development Kit,SDK)的一部分。JNI允许Java代码使用以其他语言编写的代码和代码库。Invocation API(JNI的一部分)可以用来将Java虚拟机(JVM)嵌入到本机应用程序中,从而允许程序员从本机代码内部调用Java代码。 本地方法栈 其实就是给本地方法运行提供一个内存空间。 本地方法栈用于支持 native 方法的执行,存储了每个 native 方法调用的状态。本地方法栈和虚拟机方法栈运行机制一致,它们唯一的区别就是,虚拟机栈是执行 Java 方法的,而本地方法栈是用来执行 native 方法的,在很多虚拟机中(如 Sun 的 JDK 默认的 HotSpot 虚拟机),会将本地方法栈与虚拟机栈放在一起使用。 2.4 堆 堆概念 堆内存溢出(OutOfMemoryError) 代码示例: 上图例子是对象体积越来越大,最终撑爆了堆内存。 虚拟机参数:-Xmx 用来控制堆内存大小。例:-Xmx8m,指定堆内存为8MB。 堆内存诊断 jmap查看堆内存占用情况: 2.5 方法区 方法区定义: 方法区与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量(const)、静态变量(static)、即时编译器编译后的代码等数据,方法编译出的字节码就是保存在这个区域虚拟机启动时,方法区被创建。方法区内存不足也会抛出OutOfMemoryError在Java1.

websocket的基础使用,心跳机制,断线重连

websocket的基础使用,心跳机制,断线重连 前言主流的技术基础使用1.websoket2.socket.io 心跳机制和断线重连实现代码(基础版-node后端):实现代码(基础版-前端):主要的代码逻辑:最后是模拟重连的截图 最后 前言 websoket出现的原因: 传统的http请求只能是由前端向后台发送一个请求,然后后台把结果返回给前端,前端再进行展示。这里就暴露了一个问题,就是通信只能由前端发起,而后台无法主动与前端通信。而websoket的出现就是为了解决这个问题,让前端可以主动联系后台,后台也可以主动联系前台。 应用场景: 相信大家都知道websoket的应用场景主要是用于即时通讯,比如QQ、微信即时通讯软件,同时在一些实时监控,需要即时暴露问题的地方也需要用到websoket,比如大屏可视化,需要及时的展现商品的成交数量。另外还有就是后台需要某个条件才能触发任务,在触发了任务时需要主动的告诉前端。 主流的技术 1.原生websocket 2.socket.io(推荐) 目前在websocket中应用比较多的就是这两个技术,一个是原生的websoket,另外一个socket.io是在原生websoket的基础上进行了封装了一层后的技术,让程序员更加的好用。 如何进行技术的选择:个人推荐最好还是使用ocket.io这个库, 原因就是更好用。但是很大的原因还是需要取决于后台的选择,如果后台选择了原生websocket,那么前端也需要使用原生websocket。如果后台对socket.io熟悉,那么前端也需要选择 socket.io,这是最好不过的,会让你们的开发更加的顺畅。 基础使用 1.websoket // WebSocket构造函数,创建WebSocket对象 let ws = new WebSocket('ws://localhost:8888') // 连接成功后的回调函数 ws.onopen = function (params) { console.log('客户端连接成功') // 向服务器发送消息 ws.send('hello') }; // 从服务器接受到信息时的回调函数 ws.onmessage = function (e) { console.log('收到服务器响应', e.data) }; // 连接关闭后的回调函数 ws.onclose = function(evt) { console.log("关闭客户端连接"); }; // 连接失败后的回调函数 ws.onerror = function (evt) { console.log("连接失败了"); }; // 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,这样服务端会抛异常。 window.onbeforeunload = function() { ws.

基于SpringBoot+Vue+MybatisPlus的智慧校园系统

智慧校园系统 1. 项目简介2. 项目模块3. 技术栈4. 软件环境4.1 安装数据库4.2 安装数据库客户端Navicat工具4.4 安装IDEA4.4 安装Maven 5. 系统页面5.1 首页登录页5.2 系统功能模块5.3 Swagger2接口文档查阅5.4 运行截图 6. 源代码下载 1. 项目简介 智慧校园管理系统是一个基于年级和班级的信息记录和统计系统,旨在提高学校管理效率。该系统采用了前后端分离的架构,前端使用HTML、CSS和Vue实现页面展示,后端采用Spring Boot和MyBatis Plus框架处理数据存储等服务。系统使用高性能的MySQL数据库作为存储层,服务器采用Spring Boot内置的Tomcat 9.x。项目构建工具使用Maven进行依赖管理和项目构建。通过该系统,教师和学生的信息可以方便地记录和查询,提供了便捷的统计功能,帮助学校管理者更好地了解和分析学生的情况,优化教学和管理策略。 2. 项目模块 3. 技术栈 MVC项目架构是一种常见的软件开发模式,它将应用程序分为三个主要层级:模型(Model)、视图(View)和控制器(Controller)。下面是对各层级的重新描述,并按层级进行划分: 模型层(Model): Vue:Vue是一个渐进式框架,专注于构建用户界面。它的核心库关注于视图层,可以与第三方库或现有项目轻松整合,可用于构建复杂的单页应用。Spring:Spring是一个大型框架,被设计为可以自底向上逐层应用。它的核心思想是控制反转(IoC),负责装配bean并管理对象的生命周期。Spring负责处理和存储数据,作为后端的核心。 视图层(View): Vue:Vue负责显示数据,并提供了丰富的界面组件和交互功能,使用户界面的构建更加简单和灵活。SpringMVC:SpringMVC是基于Servlet的框架,拦截用户请求,并通过DispatcherServlet进行中介处理。它将用户请求与相应的控制器(Controller)进行匹配,控制器负责处理请求并返回相应的视图,以展示数据。 控制器层(Controller): SpringMVC:SpringMVC的核心部分是DispatcherServlet,它作为中介接收用户请求,并根据配置的HandlerMapping将请求分发给相应的控制器。控制器根据业务逻辑处理请求,并调用适当的服务层和持久层完成数据处理和交互。 持久层(Persistence): Spring:Spring作为整个项目的粘合剂,负责整合各个层级的组件和模块。在持久层,Spring可以通过配置文件指定参数调用实体类的构造方法来实例化对象,或者通过IoC容器管理数据库操作对象。MyBatis-Plus:MyBatis是一个基于JDBC的数据库访问框架,提供了对SQL的封装和映射。MyBatis-Plus是在MyBatis基础上的增强版本,为Mapper接口和Service层提供了更全面的CURD(增删改查)业务逻辑功能,简化了开发人员在Mapper和Service层的代码编写。 通过MVC项目架构,页面发送请求给控制器,控制器调用业务层处理逻辑,逻辑层向持久层发送请求,持久层与数据库交互,并将结果返回给业务层。业务层将处理逻辑发送给控制器,最后控制器调用视图展现数据给用户。这种分层架构能够使项目的各个模块分工明确,提高代码的可维护性和可扩展性。 4. 软件环境 4.1 安装数据库 参考之前我的博客文章: 安装 MySql5.7 详细教程,操作简单(Windows版本) 4.2 安装数据库客户端Navicat工具 有需要的可评论留言、提供对应接收的email地址,对应安装包以及注册方式会发送。 Navicat版本 15.0.17 - Premium 4.4 安装IDEA 有需要的可评论留言、提供对应接收的email地址,对应安装包以及注册方式会发送。 Idea版本 - Ultimate 2020.2 4.4 安装Maven 参考之前我的博客文章: 安装Maven 3.6.1:图文详细教程(适用于Windows系统) 5. 系统页面 5.1 首页登录页 5.

Ubuntu 开机显示 initramfs 进不了系统

Ubuntu 开机显示 initramfs 进不了系统 通常出现进入initramfs,是因为关机不当导致磁盘文件受损还是什么引起的,所以:我们要把主分区修复 //输入以下命令修复 fsck /dev/sdb4 下面出现的所有需要按y的地方均按按键y,直至出现initramfs 之后在initramfs后面输入 exit ,即退出initramfs;之后等待就可以正常打开ubuntu **fsck 命令记录:** 检查并且试图修复文件系统中的错误 补充说明 fsck命令 被用于检查并且试图修复文件系统中的错误。当文件系统发生错误四化,可用fsck指令尝试加以修复。 语法 fsck (选项) (参数) 选项 -a:自动修复文件系统,不询问任何问题; -A:依照/etc/fstab配置文件的内容,检查文件内所列的全部文件系统; -N:不执行指令,仅列出实际执行会进行的动作; -P:当搭配"-A"参数使用时,则会同时检查所有的文件系统; -r:采用互动模式,在执行修复时询问问题,让用户得以确认并决定处理方式; -R:当搭配"-A"参数使用时,则会略过/目录的文件系统不予检查; -s:依序执行检查作业,而非同时执行; -t<文件系统类型>:指定要检查的文件系统类型; -T:执行fsck指令时,不显示标题信息; -V:显示指令执行过程。 参数 文件系统:指定要查看信息的文件系统。 个人纪录: fsck /dev/nvme0n1p5

Python爬虫实战——获取指定博主所有专栏链接及博文链接

Python爬虫实战——获取指定博主所有专栏链接及博文链接 0. 前言1. 第三方库的安装2. 代码3. 演示效果 0. 前言 本节学习使用爬虫来爬取指定csdn用户的所有专栏下的文章 操作系统:Windows10 专业版 开发环境:Pycahrm Comunity 2022.3 Python解释器版本:Python3.8 第三方库:requests bs4 1. 第三方库的安装 参考以下文章安装第三方库: Python第三方库安装——使用vscode、pycharm安装Python第三方库 2. 代码 import requests from bs4 import BeautifulSoup import datetime def printk(value): print(value) exit() user = "qq_53381910" url = "https://blog.csdn.net/{}".format(user) # 构造请求头 headers={ 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36' } # 发送get请求 r=requests.get(url = url,headers=headers,timeout = 5) # 处理 soup=BeautifulSoup(r.text,'html.parser') # 获取用户名 div = soup.

【新星计划·2023】网络技术——VTP技术/协议讲解

前言 在工作中,我们可能会遇到这样一个这样的问题,在公司内部有很多的交换机,而基本上每个交换机上面都需要配置相同的VLAN进行互通,在VLAN很多的情况下,这样的工作量是非常大的,那么就要用到今天所说的VTP技术,只需要在一台交换机上配置可以同步到其他交换机上面去,大大减少了交换机的配置量! 注:VTP协议是思科的私有协议 一、什么是VTP? VTP(VLAN Trunking Protocol:虚拟局域网干道协议),它是思科私有协议。在大型网络中,会有多台交换机,同时也会有多个VLAN,如果在每个交换机上分别把VLAN创建一遍,这会是一个工作量很大的任务。VTP协议可以帮助管理员减少这些枯燥繁重的工作。管理员在网络中设置一个或者多个VTP Server,然后在Server上创建和修改VLAN,VTP协议会将这些修改通告其它交换机上,这些交换机自动更新VLAN信息(VLAN ID和VLAN Name)。 二、VTP的作用 通常情况下,我们需要在整个企业网中的一组的交换机中保持VLAN数据库的同步,以保证所有交换机都能从数据帧中读取相关的VLAN信息进行正确的数据转发,然而对于大型网络来说,可能有成百上千台交换机,而一台交换机上都可能存在几十乃至数百个VLAN,如果仅凭网络工程师手工配置的话是一个非常大的工作量,并且也不利于日后维护——每一次添加修改或删除VLAN都需要在所有的交换机上部署。在这种情况下就可以使用VTP技术来解决。 要使用VTP,首先必须建立一个VTP管理域,在同一管理域中的交换机共享vlan信息,并且一个交换机只能参加一个管理域。不同域中的交换机不能共享vlan信息。 三、VTP的工作原理 VTP是一种消息协议,它使用第二层帧,在交换机之间传递VLAN信息,被称为VTP通告。有了VTP,就可以在一台交换机上集中修改VLAN配置,所做的修改会被自动传播到网络中的其他交换机上,从而实现VLAN配置的一致性。实现此功能的前提是这些交换机属于同一个VTP域。 1. VTP域 VTP域也称为VLAN管理域,由一个以上共享VTP域名的相互连接的交换机组成。也就是说,VTP域是一组VTP域名相同并通过中继链路相互连接的交换机。 使用VTP的条件:首先必须建立一个VTP域,在同一管理域中的交换机共享它们的VLAN信息,并且一个交换机只能参加一个VTP域。 不同域中的交换机不能共享VTP信息。 VTP域的要求:域内的每台交换机都必须使用相同的VTP域名,无论是通过配置实现,还是由交换机自动学到,Catalyst交换机必须是相邻的,即相邻的交换机需要具有相同的域名。在所有的Catalyst交换机之间,必须配置为中继链路。 如果上述条件中的任何一项不满足,则VTP域不能连通,信息也就无法跨越分离部分进行传送。 2、VTP模式 VTP模式决定了交换机处理和通告VTP信息的方式。 VTP模式有三种:服务器模式、客户机模式和透明模式。 ①服务器模式( Server )充当VTP服务器的交换机负责它所在域中VLAN信息的管理工作,VTP服务器可以创建、删除或修改VLAN,并向外发送VTP通告,同时,VTP服务器也会学习域名相同的VTP通告信息。默认情况下,交换机处于VTP服务器模式。每个VTP域至少有一个服务器,以便创建,删除或修改VLAN及提供VLAN信息。 ②客户机模式( Client )处于此模式的交换机不允许管理员创建,删除或修改VLAN,它们监听本域中其他交换机的VTP通告,并相应修改自己的VTP配置。 ③透明模式(Transparent) VTP透明模式中的交换机不参与VTP,当交换机处于透明模式时,它可以创建,删除或修改本地的VLAN,但它不向外通告自己的VLAN配置信息,对收到的VTP通告只转发而不会学习与更改自己的VLAN信息。 四、VTP管理的优点 1、简化管理 使用VTP可以简化VLAN的管理,因为它可以自动将VLAN信息传递到整个网络中,使得管理员可以更加高效地管理和配置VLAN。 2、减少误操作 通过VTP,管理员可以避免在不同交换机上手动配置VLAN信息时出现的误操作,从而提高了网络的可靠性和稳定性。 3、提高扩展性 VTP可以帮助管理员快速扩展网络规模,当新增交换机加入网络时,它们会自动获取到VLAN信息,而无需手动进行配置。 4、减少网络流量 通过使用VTP,管理员可以避免不必要的广播流量,因为只有VLAN信息发生变化时才会发送VTP报文,这可以有效地减少网络流量。

Java基础(七):面向对象编程-类和对象

Java基础系列文章 Java基础(一):语言概述 Java基础(二):原码、反码、补码及进制之间的运算 Java基础(三):数据类型与进制 Java基础(四):逻辑运算符和位运算符 Java基础(五):流程控制语句 Java基础(六):数组 Java基础(七):面向对象编程 Java基础(八):封装、继承、多态性 Java基础(九):Object 类的使用 Java基础(十):关键字static、代码块、关键字final Java基础(十一):抽象类、接口、内部类 Java基础(十二):枚举类 Java基础(十三):注解(Annotation) Java基础(十四):包装类 Java基础(十五):异常处理 Java基础(十六):String的常用API Java基础(十七):日期时间API Java基础(十八):java比较器、系统相关类、数学相关类 Java基础(十九):集合框架 Java基础(二十):泛型 Java基础(二十一):集合源码 Java基础(二十二):File类与IO流 Java基础(二十三):反射机制 目录 一、面向对象编程概述二、类和对象1、类和对象概述2、成员变量(field)3、成员变量 vs 局部变量 三、方法(method)1、方法的概述2、方法调用内存分析3、方法的重载(overload)4、方法的参数传递机制 四、构造器(Constructor) 一、面向对象编程概述 早期先有面向过程思想,随着软件规模的扩大,问题复杂性的提高面向过程的弊端越来越明显,出现了面向对象思想并成为目前主流的方式 面向过程的程序设计思想(Process-Oriented Programming),简称POP 关注的焦点是过程:过程就是操作数据的步骤 如果某个过程的实现代码重复出现,那么就可以把这个过程抽取为一个函数这样就可以大大简化冗余代码,便于维护 典型的语言:C语言代码结构:以函数为组织单位是一种“执行者思维”,适合解决简单问题。扩展能力差、后期维护难度较大 面向对象的程序设计思想( Object Oriented Programming),简称OOP 关注的焦点是类:在计算机程序设计过程中,参照现实中事物 将事物的属性特征、行为特征抽象出来,用类来表示 典型的语言:Java、C#、C++、Python、Ruby和PHP等代码结构:以类为组织单位。每种事物都具备自己的属性和行为/功能是一种“设计者思维”,适合解决复杂问题。代码扩展性强、可维护性高 类比举例:人把大象装进冰箱 面向过程 1.打开冰箱 2.把大象装进冰箱 3.把冰箱门关住 面向对象:把这些步骤和功能进行封装,封装时根据不同的功能,进行不同的封装 人{ 打开(冰箱){ 冰箱.开门(); } 操作(大象){ 大象.进入(冰箱); } 关闭(冰箱){ 冰箱.关门(); } } 冰箱{ 开门(){ } 关门(){ } } 大象{ 进入(冰箱){ } } 二、类和对象 1、类和对象概述 类(Class)和对象(Object)是面向对象的核心概念类:具有相同特征的事物的抽象描述,是抽象的、概念上的定义对象:实际存在的该类事物的每个个体,是具体的,因而也称为实例(instance) 可以理解为:类 => 抽象概念的人;对象 => 实实在在的某个人

Linux存储系统、文件系统

计算机操作系统可以看作是一个数据共生的世界,存储系统的主要任务就是存储数据和检索数据。这个过程必然复杂的、也是严谨的,Linux存储系统也是围绕此设计目的展开的 Linux存储系统 Linux存储系统包括两个部分,其一,站在用户角度提供读/写接口,数据以流为表现形式;其二,站在存储设备的角度提供读/写接口,数据以块为表现形式。文件系统则位于两者之间,起到承上启下的作用,见The Linux Storage Stack Diagram 应用程序通过系统调用发送读/写请求,最终目的是把数据写到磁盘上,文件系统负责读/写请求的位置并将其转换成块设备需要的块,然后把请求发到设备上。内存在这个过程中扮演了一个磁盘缓存的作用,把前后两个部分分离成异步的两个过程,对于前半部分让数据留在内存是最高效的。对于后一部分数据从内存同步到磁盘,请求被封装成一个个request,每一个request都包含一组bio,每个bio包含需要同步的数据页 Linux系统调用 一个稳定运行的Linux操作系统,需要内核与用户应用程序之间的完美配合协作,内核提供通用性的服务,用户应用程序通过系统调用接口,访问系统硬件和各种操作系统资源,内核提供的这组系统调用也被称为系统调用接口层。 文件系统 Linux文件系统的体系结构是一个对复杂系统抽象化的例子,通过使用一组通用的API函数,Linux就可以在多种存储设备上支持多种文件系统 文件 Linux中,一切皆文件,而并不是局限于普通的磁盘文件,泛指由字节序列构成的信息载体,包括I/O设备、socket等,都被作为文件挂载在文件系统之上来进行访问和管理。 文件系统概述 文件系统是一种对存储设备上的文件、数据进行存储与组织的机制。组织方式不同就形成了不同的文件系统 那么Linux 文件系统是如何工作的呢?为了方便管理,Linux 文件系统为每个文件都分配两个数据结构,索引节点(index node)和目录项(directory entry),它们主要用来记录文件的元信息和目录结构。 索引节点,简称为 inode,记录文件的元数据,包括inode 编号、文件大小、修改日期等。索引节点和文件一一对应,被持久化存储到磁盘中。 目录项,简称为 dentry,用来记录文件的名字、索引节点指针以及与其他目录项的关联关系。多个关联的目录项,就构成了文件系统的目录结构。不同于索引节点,目录项是由内核维护的一个内存数据结构。 索引节点纪录了文件的元数据,目录项维护文件系统的目录结构,那么,文件数据到底是怎么存储的呢?实际上,文件系统是按逻辑块来管理数据,逻辑块为最小操作单元,通常情况下逻辑块大小为 4KB,但是磁盘读写的最小单位是扇区,每个扇区大小是512字节,所以逻辑块由连续8个扇区组成。磁盘在执行文件系统格式化时,会被分成三个存储区域,超级块(存储文件系统信息)、索引节点区(存储索引节点)和数据块区(存储文件数据) 虚拟文件系统 目录项、索引节点、逻辑块以及超级块,构成了 Linux 文件系统的四大基本要素。为了简化整体复杂性,对应用层屏蔽不同文件系统的差异,Linux 内核引入了一个抽象层,就是虚拟文件系统 VFS(Virtual File System),对于应用程序而言,VFS定义了一组所有文件系统都支持的数据结构和标准接口。这样,应用层和内核中的其他子系统,只需要跟 VFS 提供的统一接口进行交互就可以了,而不需要再关心底层各种文件系统的实现细节。 VFS之下就是文件系统,按存储位置的不同,这些文件系统可以分为三类,其一,基于磁盘的文件系统,如ext4、xfs;其二,基于网络的文件系统,如nfs、iscsi等;其三,基于内存的文件系统,如/proc、/sys等,基于内存的文件系统不需要磁盘空间,但会占用一定的内存 这些文件系统,要先挂载到 VFS 目录树中的某个子目录(称为挂载点),然后才能访问其中的文件。 Linux 一切皆文件,无论是普通文件、I/O设备、还是网络套接字等,都通过统一的 VFS 接口访问

v-model使用及原理

关于v-model,vue2与vue3用法不一致,本文学习采用了vue3官网文档。与vue2区别写在本文末尾。 一、为什么使用v-model? v-model指令可以在表单input、textarea以及select元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。本质上是语法糖,负责监听用户的输入事件来更新数据。 二、什么场景下会使用v-model? ①表单提交。比如用户在检索、创建、更新信息时,需要提交一些数据。 ②组件通信。 三、v-model原理 1、v-bind绑定value属性的值。 2、v-on绑定input事件监听到函数中,函数会获取最新的值赋值到绑定的属性中。 在原生元素上使用: <input v-model=”searchText” /> //模板编译器会对v-model进行更冗长的等价展开 <input :value=”searchText” @input=”searchText = $event.target.value”> 在组件上使用: <CustomInput :modelValue="searchText" @update:modelValue="newValue => searchText = newValue" /> //注:子组件默认接收和更新modelValue,modelvalue也可以自定义,如 <input v-model:newValue=”searhText” /> CustomInput.vue组件有两种实现方式,如下: //方式一:<!-- CustomInput.vue --> <script> export default { props: ['modelValue'], emits: ['update:modelValue'] } </script> <template> <input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" /> </template> //方式二:<!-- CustomInput.vue --> <script> export default { props: ['modelValue'], emits: ['update:modelValue'], computed: { value: { get() { return this.

2023年福建农林大学程序设计校赛个人题解(无D解析)

2023年福建农林大学程序设计校赛个人题解(无D解析) A-这是一道原题 问题解析 从绿色材料合成到金色材料。 用 w h i l e while while 循环判断材料数是否能合成,能就合,合成后下一级材料数增加,原料数加上合成出的材料数。 AC代码 #include<iostream> using namespace std; #include<vector> #include<algorithm> #include<iostream> using namespace std; #include<vector> #include<algorithm> #include<math.h> #include<set> #include <random> #include<numeric> #include<string> #include<string.h> #include<iterator> #include<fstream> #include<map> #include<unordered_map> #include<stack> #include<list> #include<queue> #include<iomanip> #include<bitset> //#pragma GCC optimize(2) //#pragma GCC optimize(3) #define endl '\n' #define int ll #define PI acos(-1) #define INF 0x3f3f3f3f typedef long long ll; typedef long double ld; typedef unsigned long long ull; typedef pair<ll, ll>PII; const int N = 2e5 + 50, MOD = 1e9 + 7; void hecheng(int&a, int&b) { while (a >= 3) { int x = a / 3; a %= 3; a += x; b += x; } } void solve() { int a, b, c, d; cin >> a >> b >> c >> d; hecheng(a, b); hecheng(b, c); hecheng(c, d); cout << a << "

linux运维进阶:git安装

一、系统环境准备 root@git-git~]# cat /etc/redhat-release #查看系统版本 CentOS Linux release 7.1.1503 (Core) [root@git-git ~]# uname -r #查看内核版本 3.10.0-229.el7.x86_64 [root@git-git ~]# getenforce #确认Selinux关闭状态 Disabled [root@git-git ~]# systemctl stop firewalld #关闭防火墙 二、git安装部署 [root@git-git ~]# yum install git # 安装Git [root@git ~]# git config --global 使用全局配置文件 --system 使用系统级配置文件 --local 使用版本库级配置文件 [root@git-git ~]# git config –-global user.name “lizhenya” # 配置git使用用户 [root@git-git ~]# git config –-global user.email “lizhenya@mail.com” # 配置git使用邮箱 [root@git-git ~]# git config –-global color.ui true # 语法高亮 [root@git-git ~]# git config –-list user.

在Ubuntu 20.04上安装和配置TFTP服务器

Trivial File Transfer Protocol(TFTP)是一种简单的文件传输协议,常用于网络设备的固件更新、系统安装和配置文件的传输。在Ubuntu 20.04操作系统中,安装和配置TFTP服务器是一个相对简单的过程。本文将提供详细的步骤指导,帮助您在Ubuntu 20.04上成功安装和配置TFTP服务器。 步骤1:安装TFTP服务器软件包 要开始安装TFTP服务器,在终端(Terminal)中执行以下命令,以确保系统软件包列表是最新的,并安装tftpd-hpa软件包: sudo apt update sudo apt install tftpd-hpa 步骤2:配置TFTP服务器 安装完成后,我们需要对TFTP服务器进行一些配置。打开TFTP配置文件 /etc/default/tftpd-hpa: sudo vim /etc/default/tftpd-hpa 在打开的文件中,您可以看到一些可配置的参数。确保以下行没有被注释掉(即没有以 # 开头): TFTP_USERNAME="tftp" TFTP_DIRECTORY="/var/lib/tftpboot" TFTP_ADDRESS="0.0.0.0:69" TFTP_OPTIONS="--secure" 这些参数用于指定TFTP服务器的用户名、TFTP文件存储目录、监听地址和其他选项。请确保 /var/lib/tftpboot 目录存在,如果不存在,您可以使用以下命令进行创建: sudo mkdir /var/lib/tftpboot sudo chmod -R 777 /var/lib/tftpboot 上述命令将创建 /var/lib/tftpboot 目录并设置适当的权限。 步骤3:重启TFTP服务器 保存并关闭配置文件后,使用以下命令重启TFTP服务器,以使新的配置生效: sudo systemctl restart tftpd-hpa TFTP服务器将重新启动,并使用新的配置。 步骤4:验证TFTP服务器 要验证TFTP服务器是否正常工作,可以使用tftp命令进行文件传输。例如,尝试从TFTP服务器下载一个文件: tftp 127.0.0.1 tftp> get filename 请将 filename 替换为您在TFTP服务器上存在的文件名。如果文件成功下载,那么TFTP服务器已经正确配置并且可以正常使用。

echarts 地图制作 自定义标点

echarts 地图制作 echarts geo 地图,以绘制浙江省地图为案例(没有下转) 浙江省数据获取 json 地址:https://datav.aliyun.com/portal/school/atlas/area_selector 点击需要省份地图,下载坐标 目录下新建一个zhengjiang.js文件 代码片段 <template> <div class="content"> <div ref="charts" :style="{ width: styleList.width, height: styleList.height }" ></div> </div> </template> <script> 引入echarts 和 创建好的坐标文件 import * as echarts from "echarts"; import zjData from "../../assets/js/zhejiang"; export default { props: ["styleList"], // 根据不同地图的需求传入不同的值 data() { return { }; }, created() { this.$nextTick(() => { this.initCharts(); }); }, watch: {}, methods: { initCharts() { const that = this; const charts = echarts.

物理机迁移至proxmox的步骤

在线虚拟化工具,目前比较好用工具是VMware的VMware vCenter Converter Standalone Client 可以在不影响业务系统的情况下,将物理机虚拟化,在物理机存储较小情况下虚拟化较为顺利但是在存储较大情况下会出现失败的情况。在此过程中遇到的一些问题以及解决方法记录如下。 1 VMware vCenter Convert是VMware公司的虚拟机迁移、转换工具,可以直接将(运行或不运行的)Windows、Linux的物理机、虚拟机迁移到VMware ESX Server虚拟机中,也可以在不同的VMware版本之间进行转换。软件为图形界面使用较为简单,下面注意事项: 1.1 虚拟化Linux物理机时一定需要知道Linux主机的SSH密码,由于VMware vCenter Convert默认是22端口而且无法修改,所以Linux主机的ssh要是22端口。 1.2虚拟化linux系统必须有exsi服务器,使用VMware work station将无法虚拟化,需要在知道exsi服务的用户名和密码。还需要一个辅助的IP地址,找一个不用ip地址即可。 1.3在虚拟化数据库时,最好时数据库服务关闭,避免虚拟化后数据库无法启动。 1.4尽量使用最新版的VMware vCenter Convert,否则经常会出现导出失败,一旦失败就需要从头开始,比较费时。安装好运行界面如下图: 2 VMware vCenter Convert完成虚拟化后我们登录至Exsi服务器我们可看到虚拟化完成的机器,可以直接启动看系统是否正常。下来我们就要将在exsi上的虚拟机导出。 2.1 建议在导出的客户端机器上安装NFS服务,避免将VMDK磁盘镜像来回传输。导出方式1 关闭虚拟机,按鼠标右键,选择导出即可,就会导出xxx.ovf和xxx-0.vmdk等文件。在笔者导出时经常出现已经完成一大半了浏览器报网络而中断错误,特别是大于300G以上的镜像时,可能是VMware软件的bug。 2.2 使用ovf tools 工具进行导出,双击下载的安装包即可,由于ovf tools是命令行工具,记住你安装的位置,使用cmd进入dos命令行,使用ovftools可以导出虚拟机镜像。 ovftool.exe vi://root:@192.168.xx.xx/xxx D:\vm_backup\ ovftool.exe vi://root:@192.168.xx.xx/xxx D:\vm_backup\xxx.ova 3 将ovf 镜像导入到proxmox qm importovf 5011253 /mnt/pve/winnfs/clone/8523.ovf pve5-lvm-thin --format qcow2 qm importdisk 5011253 8253-disk1.vmdk pve5-lvm-thin --format qcow2 导入到proxmox后,由于网卡MAC变化需要增加新的虚机网卡,使用以下命令可以增加IP但是系统重启后就需要重新配置ip,原因是在/etc/sysconfig/network-scripts下没有相关配置文件,这时可以使用nmtui配置地址,但是许多系统并无nmtui工具,这时可以使用/etc/sysconfig/network-scripts下的随便一个配置文件,将MAC地址替换为新加的虚拟机地址,并将ip配置好,见下一个配置文件,重启系统即可。 ip addr add 192.168.11.253/24 dev eth0 ip link set eth0 up ip route add default via 192.

SolidWorks装配体中让弹簧随装配体运动的方法

弹簧是我们日常设计中最常用的几种零部件之一,但是弹簧不跟螺栓一样装好之后是相对静止的,弹簧在装配好后需要进行运动,在SolidWorks装配体中可以让弹簧跟随其他物体运动,操作分为三大步: 一、创建弹簧(使用此方法创建的弹簧才能随转配体运动) 二、修改装配体 三、限制行程 具体方法如下(以SolidWorks 2015为例): 一、创建弹簧 1.确定弹簧的尺寸参数,包括圈数、外径、线径、行程。 在这里小编以圈数8、外径35、线径5、行程40~100为例进行分享,单位:mm。 2.打开SolidWorks,新建一个零件,点击绘制草图,画一条直线,长度设为弹簧的最大行程,然后退出草图绘制。 3.新建一个草图,在弹簧起点处绘制出弹簧截面轮廓,具体尺寸如下,然后退出草图。 4.在“特征”工具栏中点击“扫描”,“轮廓”选中第二个草图,“路径”选择第一个草图,点击“选项”,在其下拉框中把“方向/扭转控制”改为“沿路径扭转”,“定义方式”为“度数”,然后填入度数,度数的值为“圈数×360°”,然后点击“√”生成弹簧并保存文件。 二、修改装配体 1.将此弹簧装配到相应的装配体中,添加非弹簧运动方向的配合关系,使弹簧只能在其运动方向上进行运动。 2.将弹簧的第一个草图显示出来。 3.让此草图的一端与弹簧在装配体中的一个接触面重合。 4.保存装配体文件,然后鼠标右击弹簧,在弹出的菜单栏中点击“编辑”,进入编辑零部件模式 。 5.鼠标右击弹簧的第一个草图,在弹出的菜单栏中点击“编辑草图”,进入编辑草图模式。 6.删掉草图中的长度定义,然后正对视图。 7.在此视角下,将弹簧第一个草图的另一端与弹簧的另一个接触面的边线重合,然后退出草图。 注意:不要直接点接触面操作,否则不会出现重合的命令,如图: 8.然后点击“退出编辑零部件”。 9.这时候拖动装配体零件,然后点击“重建装配体”,弹簧就会随零件位置运动了。 三、限制行程 1.同时选中弹簧接触的两个面,点击“配合”,在左侧对话框中点击“高级配合”,然后点击“距离”,在“最大距离”和“最小距离”输入框中分别输入弹簧的最大行程和最小行程即可,然后点击“√” 。此时装配体中的零件就能在弹簧的行程内运动了。

HiveCatalog 介绍与使用

作者:苏文鹏,腾讯 CSIG 工程师 一、背景 Apache Hive 已经成为了数据仓库生态系统中的核心。它不仅仅是一个用于大数据分析和 ETL 场景的 SQL 引擎,同样它也是一个数据管理平台,可用于发现、定义和演化数据。Flink 与 Hive 的集成包含两个层面: 一是利用了 Hive 的 Metastore 作为持久化的 Catalog,用户可通过 HiveCatalog 将不同会话中的 Flink 元数据存储到 Hive Metastore 中。例如,用户可以使用 HiveCatalog 将其 Kafka 表或 Elasticsearch 表存储在 Hive Metastore 中,并后续在 SQL 查询中重新使用它们。 二是利用 Flink 来读写 Hive 的表。 HiveCatalog 的设计提供了与 Hive 良好的兼容性,用户可以"开箱即用"的访问其已有的 Hive 数仓。您不需要修改现有的 Hive Metastore,也不需要更改表的数据位置或分区。 二、前置准备 创建私有网络 VPC 私有网络(VPC)是一块在腾讯云上自定义的逻辑隔离网络空间,在构建 Oceanus 集群、Hive 组件等服务时选择的网络建议选择同一个 VPC,网络才能互通。否则需要使用对等连接、NAT 网关、VPN 等方式打通网络。私有网络创建步骤请参考 帮助文档 [1]。 创建流计算 Oceanus 集群 流计算 Oceanus 是大数据产品生态体系的实时化分析利器,是基于 Apache Flink 构建的具备一站开发、无缝连接、亚秒延时、低廉成本、安全稳定等特点的企业级实时大数据分析平台。流计算 Oceanus 以实现企业数据价值最大化为目标,加速企业实时化数字化的建设进程。

电动力学专题:计算电磁学简介

数值计算的不可能三角 计算用时少 程序编写易 结果精度高数值计算名言: 只有猜到正确的结果,才能假定正确的输出计算电磁学是现代电磁学的一个重要分支,广泛应用于电磁场的仿真、物理场的数值计算、电磁波传播的模拟等领域。在计算电磁学中,常用的数值算法包括有限元方法、有限差分方法、矩量法等。这些方法可以帮助我们更好地理解和描述电磁场的特性,为电磁场的应用提供更加精确和可靠的模型基础。 发展: 数值模拟:随着电子计算机等计算机技术的进步,人们开始尝试将电磁理论与计算机技术结合,开发了一系列电磁计算软件,并逐渐深入地探索电磁场的数值模拟方法。多物理场耦合:为了更加真实地模拟电磁场的物理过程,人们开始探索多物理场的耦合模拟方法,如电磁-热学耦合、电磁-结构耦合、电磁-流体耦合等应用扩展:随着计算电磁学理论的不断完善和计算机技术的飞速发展,计算电磁学的应用领域也不断扩展,如电磁兼容与干扰、微波技术、雷达系统等。 传说 有限元法的发明:在20世纪50年代,数学家理查德·库克提出了有限元法,在70年代,工程师们开始将有限元法应用到电磁理论中,能够精确解决很多实际问题,因此有限元法成为电磁问题求解中重要的数值方法。GPU加速的推广:在计算电磁学中,巨量的计算量导致问题往往需要进行高性能计算,而GPU加速技术的发展使得电磁计算变得更加高效,这也为电磁理论研究和应用提供了强有力的支撑。 常用方法 有限元法有限差分法边界元法时域积分方程法频域积分方程法 如果购买GPU您需要考虑的因素: 处理器:有很多不同的GPU品牌和型号可供选择,但您需要选择一款适用于您的计算机和您的需求的GPU。一些常见的GPU品牌包括AMD和NVIDIA。内存:GPU的内存越多,您就能够处理更大的数据集。如果您计划处理大型数据集或运行大量的程序,则需要寻找更大的内存容量。功耗:不同的GPU型号可能需要不同的功率供应,因此您需要确保您的计算机配备了足够的电源。价格:GPU的价格有很大的差异,从低端型号到高端型号都有。在购买GPU时,您需要平衡价格和性能之间的关系。 三种主要的数值方法: 时域有限差分法FDTD(Finite-Difference in Tmain Domain) Advantages: 适用范围广:可以用于处理各种类型的电磁问题,包括二维、三维、各向异性、介质等多种情况。算法简单:实现比较容易,计算效率高,能够有效地处理大规模计算。对于高频电磁波的传播和散射问题有较好的解决能力。Shortcomings 需要完美匹配层来模拟无穷大空间,较大的计算开销。精度受空间和时间步长的限制,选择不当会导致结果误差。计算量大 有限元方法FEM(Finite Element Method) Advantages 适用广泛,可用于处理各种几何形状的问题计算结果高精度Shorcomings 计算量较大 矩量法MOM(Method of Moment) 优点 MOM算法的模型建立简单,只需要将边界离散化为有限数量的电荷和电流,不需要对整个空间进行网格划分。MOM算法适用于对复杂物体的电磁场进行数值求解。对于大规模的计算问题,MOM算法计算量较小,适用于处理大型电磁计算。缺点 MOM算法的计算精度受到边界离散化的影响,当离散化步长较大时,精度会有所下降对于具有细节的复杂模型,需要进行更精细的离散化处理,从而导致计算时间增加MOM算法需要处理大量的矩阵计算,因此在计算复杂模型时,需要较大的内存空间和计算能力。 去github或者。。。搜着玩儿吧 反正也不考反正封装好的软件已经出现了。。。。。。 参考文献简述 计算电磁学 Jian-Ming Jin

Python OCR工具pytesseract详解

pytesseract是基于Python的OCR工具, 底层使用的是Google的Tesseract-OCR 引擎,支持识别图片中的文字,支持jpeg, png, gif, bmp, tiff等图片格式。本文介绍如何使用pytesseract 实现图片文字识别。 目录 引言环境配置1. 安装Google Tesseract2. 安装pytesseract 文字识别小例子获取文字位置信息多语言识别使用方法训练数据 OCR选项图片分割模式(PSM)OCR引擎模式(OEM) 方向及语言检测OSD提取数字字符白名单字符黑名单格式转换 引言 OCR(Optical character recognition,光学字符识别)是一种将图像中的手写字或者印刷文本转换为机器编码文本的技术。通过数字方式存储文本数据更容易保存和编辑,可以存储大量数据,比如1G的硬盘可以存储数百万本书。 OCR技术可以将图片,纸质文档中的文本转换为数字形式的文本。OCR过程一般包括以下步骤: 图像预处理文本定位字符分割字符识别后处理 最初由惠普开发,后来Google赞助的开源OCR引擎 tesseract 提供了比较精确的文字识别API,支持100多种语言,本文将要介绍的Python库Pytesseract就是基于Tesseract-OCR 引擎。 环境配置 环境要求: Python 3.6+PIL库安装Google Tesseract OCR系统:windows/mac/linux,我的系统是Windows10 1. 安装Google Tesseract Tesseract OCR github地址:https://github.com/tesseract-ocr/tesseract Windows Tesseract下载地址:https://digi.bib.uni-mannheim.de/tesseract/ Mac和Linux安装方法参考:https://tesseract-ocr.github.io/tessdoc/Installation.html 安装时可以选择需要的语言包: 安装完成后,添加到环境变量PATH中,我的安装路径是:C:\Program Files\Tesseract-OCR 。 命令行窗口输入:tesseract ,查看是否安装成功。 $ tesseract Usage: tesseract --help | --help-extra | --version tesseract --list-langs tesseract imagename outputbase [options...] [configfile...] OCR options: -l LANG[+LANG] Specify language(s) used for OCR.

学生成绩管理系统(可直接使用!!!)

前言: 对于此系统我采取的方式通过函数将代码块进行打包,将每一个操作作为一个代码块,清晰明了。所用的编辑器为Pycharm,解释器是Python3.10版本。基于对Python基础知识的掌握,希望能够给大家带来帮助。 1、需求分析: 1.1 录入学生信息: 我们需要将学生的学号,姓名,C语言成绩,java成绩以及高数成绩录入到我们的学生表里面,以便我们进行后续操作。 1.2 查找学生信息: 查找方式:(1) 学号 (2)姓名 。通过这两种查找方式我们可以将该学生的全部信息查找出来。 1.3 删除学生信息: 删除方式:学号 。通过对删除指定学生学号将这个学生信息从学生表当中删除。 1.4 修改学生信息: 修改方式:学号。通过对指定学号将该学生的姓名,C语言成绩,java成绩以及高数成绩修改。 1.5 排序: 排序方式:(1)学号,(2)C语言成绩,(3)java成绩,(4)高数成绩。通过指定这4种排序方式,然后选择降序或者升序排序。 1.6 统计学生的总人数: 统计方式:统计学生表的学生信息个数即可。 1.7 显示所有学生信息: 显示方式:将学生表的所有学生信息遍历输出即可。 2、功能实现: 2.1 主函数实现: 由于我们在进行操作的时候我们并不是只进行一次操作,而是一直操作直到我们操作完毕,因此我们就需要一个主函数来让系统明确我们现在准备进行什么操作。 2.11 功能实现: 实现思路:由于我们需要一直进行操作直到我们操作完毕,因此我们需要将主函数放入一个死循环当中去,那么就可能有人在想,死循环不是一个我们需要回避的问题吗,这玩意一用代码不就跑死了吗。其实我们是可以人为的将死循环变成活循环的(使用一个break就得了)。由于我们的死循环是跟主界面挂钩的,因此我们每次操作一次我们都要将主界面函数调用,然后通过主界面上的指示操作实现本次系统。 if __name__ == '__main__': list_data = [] # 学生表,用于存储学生信息 while True: Menu() # 菜单 choice = input("请输入您要执行的操作:") if choice == '1': # 由于input输入的是一个字符串,因此这里为字符1 Add_student() # 调用录入学生信息函数 elif choice == '2': Query_student() # 调用查找学生信息函数 elif choice == '3': Del_student() # 调用删除学生信息函数 elif choice == '4': Modify_student() # 调用修改学生信息函数 elif choice == '5': sort_data() # 调用排序函数 elif choice == '6': Count_data() # 调用统计学生信息函数 elif choice == '7': Show_all() # 调用显示全部学生信息函数 elif choice == '0': Exit() # 调用退出系统函数 time.