编码问题(Java的IO流为什么会有字节流和字符流)

Java的IO流为什么会有字节流和字符流 首先明确字节流适用于任何场景,而且有字节缓冲流,能提高读取和输入的效率,也就是BufferedOutputStream/BufferedInputStream。其操作与字节流基本都一样。 而字符流是为了应对汉字出现的情况。在GBK中汉字占2个字节,在UTF-8中汉字占3个字节,所以我们通过字节流读取文件的时候一般都是逐个字节转换就会导致乱码,而手动去根据不同编码去拼接则不方便,所以有字符流。 这边再解释一下为什么使用字节流复制粘贴中文文件时不会乱码的原因: 不论是使用GBK还是UTF-8编码,中文的第一个字节都是负数,逐个字节读取后文件会根据不同的编码自动进行拼接。而当我们手动向文件输入数据时,使用 write(“中国”.getBytes()),其实getBytes默认是UTF-8编码,如果文件也是UTF-8编码那自然也不会乱码。 (getBytes(“指定编码类型”)) 在Java中将字节数组转换为字符串使用String(字节数组),默认的编码也是UTF-8,当然也可以自己指定编码,String(字节数组,“指定编码类型”)。 使用字符流时,OutputStreamWriter/InputStreamReader都可以在第二个参数处添加编码方式,默认还是UTF-8,这样在操作中文文件时就避免了在控制台输出时乱码或者需要手动拼接的麻烦。

echarts图表超出宽度添加横向滚动条

最近项目中使用到echarts图表,当数据过多时需要添加横向滚动条,经过摸索和踩坑,终于!!!!完美填坑!! 注意echarts的版本问题,我这里使用的是5.0版本以上 dataZoom: [ { xAxisIndex: 0, //这里是从X轴的0刻度开始 show: true, //是否显示滑动条,不影响使用 type: 'slider', // 这个 dataZoom 组件是 slider 型 dataZoom 组件 startValue: 0, // 从头开始。 endValue: 7, // 一次性展示6个 height: 8, //组件高度 bottom: 10, borderColor: 'rgba(43,48,67,.1)', fillerColor: 'rgb(36,71,141)', zoomLock: true, showDataShadow: false, //是否显示数据阴影 默认auto backgroundColor: '#051A3B', showDetail: false, //即拖拽时候是否显示详细数值信息 默认true realtime: true, //是否实时更新 filterMode: 'filter', handleIcon: 'M-9.35,34.56V42m0-40V9.5m-2,0h4a2,2,0,0,1,2,2v21a2,2,0,0,1-2,2h-4a2,2,0,0,1-2-2v-21A2,2,0,0,1-11.35,9.5Z', handleStyle: { color: 'rgb(36,71,141)', borderColor: 'rgb(36,71,141)', }, moveHandleSize: 20, moveOnMouseMove: true, maxValueSpan: 7, minValueSpan: 7, moveHandleSize: 0, brushSelect: false, //刷选功能,设为false可以防止拖动条长度改变 ************(这是一个坑) }, ],

armlink 第四章 scatter文件举例

armlink 第四章 scatter文件举例 在前面学习了基本术语和概念之后,本章是加强scatter编写能力的章节。 4.1 什么时候使用scatter文件 scatter文件通常用于嵌入式系统中,因为这些系统含有ROM,RAM,还有一些内存映射的外设。下面的场景常使用scatter文件: 复杂的内存映射:放在不同内存区域的section,需要使用scatter文件来更精细的操控放置的位置 不同的存储类型:许多系统包含各种各样的存储设备,如flash,ROM,SDRAM,SRAM等。这时可以使用scatter文件,将更适合的存储区域放置更适合的代码。例如:中断代码放置在SRAM中,已达到快速响应的目的;而不频繁访问的配置信息可以放置在flash存储中。 内存映射的外设:在内存映射机制下,scatter文件可以在一个精确的地址放置数据section。这样访问这个数据section就相当于访问对应的外设。 在固定地址存放函数:即使修改并重新编译了应用程序,而跟应用程序紧密相关的函数还是可以放置在一个固定的位置。这个对于跳转表的实现非常有用。 使用符号标记堆和栈:当应用被链接时,可以为堆和栈定义符号 4.2 在scatter文件中指定堆和栈 在c语言中,常常需要两个存储区域,堆和栈。在所有的内存都由我们分配的情况下,堆和栈也需要我们进行分配。 在程序开始运行之前,会调用__user_setup_stackheap()函数,它负责初始化堆和栈。而这个函数根据我们在scatter文件中的设置来初始化。 要想正确的初始化堆和栈。我们需要在scatter文件中定义两个特殊的执行region。分别叫做ARM_LIB_HEAP 和ARM_LIB_STACK。这两段内存由c库进行初始化,所以不能放置任何输入section,此时应该设置EMPTY属性。同时也可以给这两个内存区域设置基址和大小。如下: LOAD_FLASH … { … ARM_LIB_STACK 0x40000 EMPTY -0x20000 ; 栈区,向下增长 { } ARM_LIB_HEAP 0x28000000 EMPTY 0x80000 ; 堆区向上增长 { } … } 当然还有更简单的用法,只需要定义一个特殊的执行region,叫做ARM_LIB_STACKHEAP,同样他需要有EMPTY属性,并设置基址和大小 4.3 使用scatter文件描述一个简单的镜像 如下图,是一个简单的镜像内存视图。 下面根据这个图,来写一个scatter文件 LOAD_ROM 0x0000 0x8000 ; 加载region的名字叫LOAD_ROM ; 基址0x0000 ; 最大大小0x8000 { EXEC_ROM 0x0000 0x8000 ; 第一执行region的名字叫做EXEC_ROM ; 基址0x000 ; 最大大小0x8000 { * (+RO) ; 放置所有的代码和RO数据 } SRAM 0x10000 0x6000 ; 第二个执行region叫SRAM ; 基址 0x10000 ; 最大大小 0x6000 { * (+RW, +ZI) ; 放置所有的RW数据和ZI数据 } } 4.

postman传大写字母后端收不到

可见我在postman传值为pId,但是idea端却收不到,但是我尝试将pId改成pid,I改成小写却可以收到。 但是我的实体类定义的就是大写的I,pId。 解决:使用注解:@JsonProperty("pId"),这里的" "填写想要前端和后端交互用的键名。也就是json语句中的key值,后端接收之后能对应到注解下面的属性。 例如 这里就是前端可以用1处定义的名字,对应到后端2处对应的属性。

Windows安装GPU版pytorch报错: UserWarning: CUDA initialization: CUDA unknown error - this may be due to an

验证GPU版pytorch是否安装成功: 1.打开Anaconda prompt,输入如下代码。 import torch import torchvision torch.cuda.is_available() 出现False,报错内容如下: UserWarning: CUDA initialization: CUDA unknown error - this may be due to an incorrectly set up environment, e.g. changing env variable CUDA_VISIBLE_DEVICES after program start. Setting the available devices to be zero. (Triggered internally at /opt/conda/conda-bld/pytorch_1614378083779/work/c10/cuda/CUDAFunctions.cpp:109.) return torch._C._cuda_getDeviceCount() > 0 原因: nvidia-modprobe 版本过低或未安裝,与显卡驱动的版本不匹配。 解决方法: 1.以Win10为例,首先我们鼠标右键点击“此电脑”,选择“管理”,在计算机管理中,我们点击“设备管理器”,展开“显示适配器”,找到并右键您的显卡设备,选择“更新驱动程序”(也可以选择属性–驱动程序–更新驱动程序),如下图所示。 2.选择第一个“自动搜索驱动程序” 3.等待片刻,就可以更新显卡驱动程序,会提示正在联机搜索驱动程序,更新好了之后,会提示“你的设备的最佳驱动程序已安装”。 4.更新好之后,再次验证pytorch,出现True即表示安装成功。

【Spring Security】基本功能介绍

文章目录 1、spring security 简介spring security 基本原理 2 入门项目2.1 web工程配置2.1 加入Spring Security 3. 参数详解3.1、注解 @EnableWebSecurity3.2、抽象类 WebSecurityConfigurerAdapter3.2.1 、configure(AuthenticationManagerBuilder auth)方法3.2.2 configure(HttpSecurity http)方法 4. 原理讲解4.1、校验流程图4.2 源码 参考 1、spring security 简介 spring security 的核心功能主要包括: 认证 (你是谁) 通过注解 @EnableWebSecurity开启 简单来说,就是需要登录,你需要输入用户名和密码,才能访问某个url。 授权 (你能干什么) 不需要通过指定的开关开启,而是通过配置来增加授权规则来生效,不增加授权规则就不生效 授权的目的是可以把资源进行划分,例如公司有不同的资料,有普通级别和机密级别,只有公司高层才能看到机密级别的子类,而普通级别的资料大家都可以看到! 那么授权就是允许你查看某个资源,当然,如果你没有权限,就拒绝你查看! 认证可以单独使用,即不划分资源的级别,所有人只要登录都可以查看 spring security 基本原理 spring security的核心就是一组过滤器链,项目启动后将会自动配置。最核心的就是 Basic Authentication Filter 用来认证用户的身份,一个在spring security中一种过滤器处理一种认证方式。 如下图所示,这是一组链式处理器类,请求从做往右依次经过多个过滤器类处理: 比如,对于username password认证过滤器来说: 会检查是否是一个登录请求; 是否包含username 和 password (也就是该过滤器需要的一些认证信息) ; 如果不满足则放行给下一个。 下一个按照自身职责判定是否是自身需要的信息,basic的特征就是在请求头中有 Authorization:Basic eHh4Onh4 的信息。中间可能还有更多的认证过滤器。最后一环是 FilterSecurityInterceptor,这里会判定该请求是否能进行访问rest服务,判断的依据是 BrowserSecurityConfig中的配置,如果被拒绝了就会抛出不同的异常(根据具体的原因)。Exception Translation Filter 会捕获抛出的错误,然后根据不同的认证方式进行信息的返回提示。

备考华为机试

1.去除重复字母(力扣316) 本题要求按照最小字典序返回,因此采用单调栈。 public String removeDuplicateLetters(String s) { Deque<Character> deque = new ArrayDeque<>(); for (int i = 0; i < s.length(); i++) { if(deque.contains(s.charAt(i))){ continue; } else { while (!deque.isEmpty() && deque.peek()>s.charAt(i) && s.indexOf(deque.peek(),i)!=-1) deque.pop(); deque.push(s.charAt(i)); } } StringBuilder sb = new StringBuilder(); while (!deque.isEmpty()){ sb.append(deque.pop()); } return sb.reverse().toString(); } 2.下一个更大元素1(力扣496) public int[] nextGreaterElement(int[] nums1, int[] nums2) { // int[] res = new int[nums1.length]; // for (int i = 0; i < nums1.

5G+工业互联网丨DolphinDB携手诺基亚贝尔打造高精度实时计算平台

近日,由智臾科技(DolphinDB)承担、诺基亚贝尔参与,双方共同申报的「基于5G Pre-TSN 网络的高精度时间同步实时计算平台」项目,成功入围浙江省“尖兵”、“领雁”研发攻关计划项目,时序数据库技术将尝试用于解决"5G+工业互联网"中低成本终端缺少高精度时间支持的难题。 项目简介 在工业互联网和工业制造领域,5G 凭借着大带宽、高可靠、低时延、广连接等特性,促成了云计算、大数据、人工智能、物联网、区块链与工业互联网等新一代信息技术的无缝融合,打通了数据从采集、存储、传送、处理、分析到决策的全过程,数据已经成为新一代生产要素,其中针对典型的异常检测问题,基于丰富的传感器采集的数据,引入了大数据分析和机器学习,带来了对数据时间相关性和海量实时数据存储和计算、分析处理的问题。 本项目计划引入 4G/5G 系统(用户设备+无线接入网+核心网),以及 ORAN 无线智能控制平台(RIC)和 ETSI MEC API 框架,搭建一个边缘计算平台,以找到能用更低成本、更轻量的方法来满足使用 5G 系统的大数据分析和机器学习算法中对于数据时间相关性的要求。ORAN 架构定义了近实时的无线智能控制平台和可编程的对无线接入网的增强,它提供了一个标准框架来解决这个问题。 同时将开发一个集数据库和数据计算功能于一体的实时计算平台,以满足对海量数据进行低时延异常检测、实时计算和机器学习的需求。其主要功能模块包含:高性能高压缩的数据存储引擎,支持海量数据的高速读写;多范式编程语言,支持丰富的计算函数与统计分析和机器学习功能;实时数据流计算,内置流数据时间序列聚合引擎,横截面聚合引擎和异常检测引擎可实现高性能流计算,支持亚毫秒级的信息延迟。 DolphinDB将和诺基亚贝尔携手合作,充分发挥DolphinDB高性能分布式时序数据库在海量数据存储、内置编程脚本语言和高速实时计算上的领先优势,依托诺基亚贝尔在5G 上行数据上的先进赋时技术,共同研发低成本、高精度的多终端时间戳同步系统,将时间戳精度从目前的几十到几百毫秒降低到低于 5毫秒,从而打造"弱终端、强基站"的增强 5G 系统。 行业痛点 目前5G+工业互联网在推动制造业向数字化、网络化、智能化转变过程中正发挥越来越重要的作用,但在推广过程中也遇到一些痛点问题: 因为精准授时需要北斗/GPS等授时设备或同步时钟源,室内环境还需光纤网络,投资巨大,所以很多行业都没有用高精度授时的传感设备,时间精度低。虽然目前5G 网络号称低时延,但实际网络时延抖动能高达几十毫秒;实时计算分析软件无法实现毫秒级响应。 这些问题导致不同数据源的数据时间戳不准且难以对齐,制约了高端制造业数据要素的挖掘效力。 图1 多源头的数据存在时间同步问题 研发重点 本项目拟基于开放无线接入网ORAN 架构,实现弱终端、强基站,用低成本方式提高传感器的时间精度,确保时间精度误差小于5ms,主要开发内容包括如下三个方面: 图2 系统架构图 用5G基站收到数据的时间,加上智能补偿来取代发送方的绝对时间,实现弱终端、强基站。基于无线接入网智能控制器(RIC),对传统5G基站进行增强,对带有特定识别号(如IP或者切片ID等)的上行数据增加高精度的时间戳,同时报告上行传输中可能发生数据丢失时的异常事件。采用集数据存储和计算于一体的DolphinDB实时计算平台进行数据分析。针对时序数据的流数据处理,历史数据处理,机器学习建模,均可以在分布式数据库内完成。优化基础算法、内存管理与系统架构,实现毫秒级SQL和计算响应速度。 应用场景 本项目高精度时间戳的获得,将从根本上解决多源头数据存在的时间同步精度低的难题,为工业互联网和工业制造领域的大数据分析和机器学习提供高精度的可用数据,从而显著提升数据分析和预测的精度。 项目成果将首先应用于电缆、半导体等高速生产线的设备状态实时异常检测领域,比如某公司的射频电缆生产场景,其生产工序包含一条连续的流水线,和几个离散的生产步骤,各自使用独立的设备。这种依赖于独立的分散过程检测有一个缺陷,门限设置过低,容易产生误报;门限设置过高,则成品率低。因此需要对相关的数据进行关联分析,并更精准地识别是否存在生产质量问题,以及生产工序是否存在系统性误差等深度问题。本项目成果应用于这套异常检测系统,将显著提高产品的成品率。 关于我们 DolphinDB是一款专为海量时序数据设计的数据库产品,将编程语言、数据库和分布式计算从底层进行一体化设计,开创性地解决了快速开发、高速运行和简单部署三者难以兼顾的难题,为海量结构化数据的快速存储、检索、 分析及计算量身订做一站式解决方案。 DolphinDB目前被广泛应用于金融市场全域(低频、中频和高频)的数据存储、数据清洗、因子分析、策略回测、实时计算等场景中。在物联网领域,尤其是化工、电力、能源、水务等行业,DolphinDB通过联合各行业头部集成商,将DolphinDB集成到行业解决方案中,实现海量数据的存储和实时计算,为用户提供性能优异的整体解决方案。

基于seed数据集的脑电情绪识别(附论文和源码)(改进的循环神经网络(简单循环单元神经网络)和集成学习)并提取了微分熵、功率谱等特征

论文和源码链接见个人主页:基于seed数据集的脑电情绪识别(附论文和源码)(改进的循环神经网络和集成学习)并提取了微分熵、功率谱等特征。 https://download.csdn.net/download/qq_45874683/83935782 介绍一篇2020年的基于seed数据集的脑电情绪识别的论文 摘要 本研究的目的是开发一个基于脑电图的情绪识别系统,用于识别三种情绪:积极情绪、中性情绪和消极情绪。到目前为止,各种用于自动情感识别的建模方法已经被报道。然而,情感过程中的时间依赖性并没有得到充分考虑。为了掌握脑电的时间信息,我们采用了深度循环(SRU)神经网络,该网络不仅能够处理序列数据,而且能够解决常规循环神经网络(RNN)中长期依赖的问题。在训练情绪模型之前,采用双树复小波变换(DT-CWT)将原始脑电信号分解为五个子带,然后利用时间、频率和非线性分析从中提取特征。接下来,利用五个频带上的四种不同特征(功率谱密度和微分熵等特征)建立了深层SRU模型,发现良好的结果与更高的频带有关。最后,采用三种集成策略对基本SRU模型进行集成,以获得更理想的分类性能。我们评估和比较了浅层模型、深层模型和集成模型的性能。实验结果表明,基于SRU网络和集成学习的情感识别系统能够以相对经济的计算成本获得满意的识别性能。最终准确率达到80%。 首先将seed数据集划分为三种情绪类型,积极、中性和消极。(SEED数据集包含15名受试者观看4分钟电影片段时的脑电信号) 本论文使用的主要方法: ● 使用DT-CWT进行脑电信号数据预处理。 ● 利用分解后的脑电信号进行特征提取。 ● 使用SRU建立模型。 ● 整体学习 本论文所提取的特征: 1.时域特征:时间分析(平均绝对值)(MAV) 2.频域特征:频率分析(功率谱密度)(PSD) 3.时频域特征:复杂性分析(分形维数和微分熵)(FD 和 DE) 训练方法: ● 每个特征提取以19个时间间隔进行,为每个EEG信号生成19个时间步长。 ● 每个EEG信号的62个通道作为模型的特征。 ● 对每个DTCWT分解信号提取四种特征,并将其转换为19个序列长度。 ● 每个样本的数据分为15部分,前9部分用于训练集,后面6部分用于测试, 数据维度:训练数据(19,9,62)和测试数据(19,6,62)(时间步、样本、特征) 模型图: 循环神经网络(RNN): 改进的循环神经网络: 二重的改进模型: 实验的完整步骤: 最终结果: 部分代码解析: DC-TWT: transform = dtcwt.Transform1d() for row in range(data.shape[0]): for col in data.columns: #checking if size of eeg_data is even if(len(data.loc[row,col])%2!=0): eeg_data=np.array(data.loc[row,col][:-1]) else: eeg_data=np.array(data.loc[row,col]) vecs_t = transform.forward(eeg_data, nlevels=5) data_dtcwt_delta.loc[row,col]=vecs_t.highpasses[0] data_dtcwt_theta.loc[row,col]=vecs_t.highpasses[1] data_dtcwt_alpha.loc[row,col]=vecs_t.highpasses[2] data_dtcwt_beta.loc[row,col]=vecs_t.highpasses[3] data_dtcwt_gamma.

解析Python requests响应内容编码规则

1.发现问题 我们在使用requests发送请求时,响应的内容有时候会出现乱码的情况,下面我举一个例子: import requests r = requests.get('http://www.baidu.com') print(r.text) # 打印发现内容为乱码 我们可以使用r.encoding来查看编码解析text时我们的字符集编码是什么: print(r.encoding) 打印结果: 然后我们在通过r.text查看到HTML本身的字符集编码是utf-8,所以这里才会出现乱码的情况 2.解决问题 2.1方式一 我们通过r.text查看到HTML或XML文本自身的字符集编码,然后通过r.encoding设置就行了 import requests r = requests.get('http://www.baidu.com') r.encoding = 'utf-8' print(r.text) # 此时发现打印的内容就不是乱码了 2.2方式二 我们可以通过r.apparent_encoding去拿到字符集编码(由 charset_normalizer 或 chardet 库提供的表观编码)。 import requests r = requests.get('http://www.baidu.com') r.encoding = r.apparent_encoding print(r.text) # 此时发现打印的内容就不是乱码了 3.分析问题 3.1 requests响应内容编码规则 我这里用的Pycharm,所以大家看步骤就好,有些快捷键可能不同的IDE不同。 按两下Shift键,打开搜索搜索框输入utils,点击Classes选择requests下的utils,并点击 Ctrl+F,搜索输入:get_encoding_from_headers 这个函数就是requests的字符集编码规则获取方法,接下来我们分析一下里面的步骤(我用注释的方式来写): def get_encoding_from_headers(headers): """Returns encodings from given HTTP Header Dict. :param headers: dictionary to extract encoding from. :rtype: str "

etcd原理

etcd简介 ETCD是用于共享配置和服务发现的分布式,一致性的KV存储系统。它是一个优秀的高可用分布式键值对存储数据库。etcd内部采用了Raft协议作为一致性算法,且使用Go实现。 ETCD作为一个受到ZooKeeper与docker启发而催生的项目,除了拥有与之类似的功能外,更专注于以下四点: 简单:基于HTTP+JSON的API让你用curl就可以轻松使用。安全:可选SSL客户认证机制。快速:每个实例每秒支持一千次写操作。可信:使用Raft算法充分实现了分布式。 分布式系统中的数据分为控制数据和应用数据。etcd的使用场景默认处理的数据都是控制数据,对于应用数据,只推荐数据量很小,但是更新访问频繁的情况。 应用场景有如下几类: 场景一:服务发现(Service Discovery)场景二:消息发布与订阅场景三:负载均衡场景四:分布式通知与协调场景五:分布式锁、分布式队列场景六:集群监控与Leader竞选 举个最简单的例子,如果你需要一个分布式存储仓库来存储配置信息,并且希望这个仓库读写速度快、支持高可用、部署简单、支持http接口,那么就可以使用etcd。 etcd工作原理 ETCD使用Raft协议来维护集群内各个节点状态的一致性。简单说,ETCD集群是一个分布式系统,由多个节点相互通信构成整体对外服务,每个节点都存储了完整的数据,并且通过Raft协议保证每个节点维护的数据是一致的。 每个ETCD节点都维护了一个状态机,并且,任意时刻至多存在一个有效的主节点。主节点处理所有来自客户端写操作,通过Raft协议保证写操作对状态机的改动会可靠的同步到其他节点。 ETCD工作原理核心部分在于Raft协议和watch机制。 Raft协议 Raft协议主要分为三个部分:选主,日志复制,安全性。 选主 Raft协议是用于维护一组服务节点数据一致性的协议。这一组服务节点构成一个集群,并且有一个主节点来对外提供服务。当集群初始化,或者主节点挂掉后,面临一个选主问题。集群中每个节点,任意时刻处于Leader, Follower, Candidate这三个角色之一。选举特点如下: 当集群初始化时候,每个节点都是Follower角色;集群中存在至多1个有效的主节点,通过心跳与其他节点同步数据;当Follower在一定时间内没有收到来自主节点的心跳,会将自己角色改变为Candidate,并发起一次选主投票;当收到包括自己在内超过半数节点赞成后,选举成功;当收到票数不足半数选举失败,或者选举超时。若本轮未选出主节点,将进行下一轮选举(出现这种情况,是由于多个节点同时选举,所有节点均为获得过半选票)。Candidate节点收到来自主节点的信息后,会立即终止选举过程,进入Follower角色。 为了避免陷入选主失败循环,每个节点未收到心跳发起选举的时间是一定范围内的随机值,这样能够避免2个节点同时发起选主。 日志复制 所谓日志复制,是指主节点将每次操作形成日志条目,并持久化到本地磁盘,然后通过网络IO发送给其他节点。其他节点根据日志的逻辑时钟(TERM)和日志编号(INDEX)来判断是否将该日志记录持久化到本地。当主节点收到包括自己在内超过半数节点成功返回,那么认为该日志是可提交的(committed),并将日志输入到状态机,将结果返回给客户端。 这里需要注意的是,每次选主都会形成一个唯一的TERM编号,相当于逻辑时钟。每一条日志都有全局唯一的编号。 主节点通过网络IO向其他节点追加日志。若某节点收到日志追加的消息,首先判断该日志的TERM是否过期,以及该日志条目的INDEX是否比当前以及提交的日志的INDEX跟早。若已过期,或者比提交的日志更早,那么就拒绝追加,并返回该节点当前的已提交的日志的编号。否则,将日志追加,并返回成功。 当主节点收到其他节点关于日志追加的回复后,若发现有拒绝,则根据该节点返回的已提交日志编号,发生其编号下一条日志。 主节点像其他节点同步日志,还作了拥塞控制。具体地说,主节点发现日志复制的目标节点拒绝了某次日志追加消息,将进入日志探测阶段,一条一条发送日志,直到目标节点接受日志,然后进入快速复制阶段,可进行批量日志追加。 按照日志复制的逻辑,我们可以看到,集群中慢节点不影响整个集群的性能。另外一个特点是,数据只从主节点复制到Follower节点,这样大大简化了逻辑流程。 安全性 截止此刻,选主以及日志复制并不能保证节点间数据一致。试想,当一个某个节点挂掉了,一段时间后再次重启,并当选为主节点。而在其挂掉这段时间内,集群若有超过半数节点存活,集群会正常工作,那么会有日志提交。这些提交的日志无法传递给挂掉的节点。当挂掉的节点再次当选主节点,它将缺失部分已提交的日志。在这样场景下,按Raft协议,它将自己日志复制给其他节点,会将集群已经提交的日志给覆盖掉。 这显然是不可接受的。 其他协议解决这个问题的办法是,新当选的主节点会询问其他节点,和自己数据对比,确定出集群已提交数据,然后将缺失的数据同步过来。这个方案有明显缺陷,增加了集群恢复服务的时间(集群在选举阶段不可服务),并且增加了协议的复杂度。 Raft解决的办法是,在选主逻辑中,对能够成为主的节点加以限制,确保选出的节点已定包含了集群已经提交的所有日志。如果新选出的主节点已经包含了集群所有提交的日志,那就不需要从和其他节点比对数据了。简化了流程,缩短了集群恢复服务的时间。 这里存在一个问题,加以这样限制之后,还能否选出主呢?答案是:只要仍然有超过半数节点存活,这样的主一定能够选出。因为已经提交的日志必然被集群中超过半数节点持久化,显然前一个主节点提交的最后一条日志也被集群中大部分节点持久化。当主节点挂掉后,集群中仍有大部分节点存活,那这存活的节点中一定存在一个节点包含了已经提交的日志了。 etcd和zk的区别 etcd和zk的区别如下所示: 除了以上区别之外,两者区别还包括: 运维方面:ETCD方便运维,ZK难以运维;项目活跃度:ETCD社区与开发活跃,ZK已经快死了;API:ETCD提供HTTP+JSON, gRPC接口,跨平台跨语言,ZK需要使用其客户端;访问安全方面:ETCD支持HTTPS访问,ZK在这方面缺失;ETCD主要用于存储关键数据的键值存储,zk用于管理配置等信息的中心化服务;ETCD更轻量级、更易用; watch机制 这里重点提一下watch机制,watcher指的是订阅/通知,当一个值改变时,通知订阅过的节点,在etcd中是K/V值对的改变,在Zookeeper中是znode的改变(值改变、节点删除等)。 ZooKeeper watch children只能watch子节点,不能递归watch孙节点watch children只能watch子节点的创建和删除,不能watch子节点值的变化watch node只能对已经存在的node进行watch,对不存在的node需要watch existence。 除了上述的这些不足以外,在其官网文档中自己也提到,在watch被触发和重新设置之间发生的事件将被丢弃,无法被捕捉。 Etcd Etcd支持单点watch,prefix watch以及ranged watch。和ZooKeeper不同,Etcd不会根据事件的不同而要求调用不同的watch API,三类watch的区别仅在于对key的处理不同: 单点watch仅对传入的单个key进行watch;ranged watch可以对传入的key的范围进行watch,范围内的key的事件都会被捕捉;prefix则可以对所有具有给定prefix的key进行watch。 zookeeper可以作为分布式存储吗? 在应用场景上,etcd和Zookeeper也很一致,难道Zookeeper本质上是分布式存储组件,为此,我查了下 Zookeeper是否可以作为分布式存储系统? 在知乎上的答案为 zookeeper只存元数据,总结几点原因如下: znode只能存1M以内的数据写入性能低,为保证一致性,每次需要n/2+1的写入完成才算完成zookeeper的数据是全部存储在内存,只适合存元数据Zookeeper的使用场景是有高一致性的 zookeeper与etcd的对比 ETCD相关介绍–整体概念及原理方面 从零开始入门 K8s | 手把手带你理解 etcd etcd命令行和客户端 etcd在键的组织上采用了层次化的空间结构(类似于文件系统中目录的概念),用户指定的键可以为单独的名字,如:testkey,此时实际上放在根目录/下面,也可以为指定目录结构,如/cluster1/node2/testkey,则将创建相应的目录结构。

大学生C语言期末必背题目,考研必背题目,找工作基础题目

1、输出9*9口诀。共9行9列,i控制行,j控制列。 //99乘法表 int main() { for (int i = 1; i <= 9; i++) { for (int j = 1; j <= i; j++) { printf("%d x %d = %-4d",i,j,i*j); } printf("\n"); } } 运行结果: 2、古典问题:有一对兔子,从出生后第3个月起每个闯都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?(斐波那契数列) //兔子繁殖问题 #define month 20 int main() { long x1 = 1, x2 = 1; for (int i = 1; i <= month; i++) { printf("%-12ld%-12ld", x1, x2); if (i % 2 == 0) { printf("

vue 父子组件传参

1.父传子 父组件里面获取的一些属性,子组件也想使用。 父组件在使用子组件是给调用的子组件设置字段并把要传的值赋值过去 <template> <div> <!-- 这里是父组件 --> <h1>这里是父组件</h1> <B :msg="msgs" :arr="items"></B> </div> </template> <script> import B from './B.vue' export default { components: { B }, data() { return { msgs:'父组件的内容被子组件调用', items:[ {id:1,name:'语文'}, {id:2,name:'数学'}, {id:3,name:'生物'}, {id:4,name:'化学'} ] } }, } </script> <style lang="scss" scoped> </style> 这里的子组件在data里面定义props来接受传过来的值 拿到的数据,可以直接遍历展示 <template> <div> <!-- 这里是子组件 --> <h1>这里是子组件</h1> <h3>{{msg}}</h3> <h3 v-for="item in arr" :key="item.id"> {{item.id}},,,,{{item.name}} </h3> </div> </template> <script> export default { props:['msg',"arr"], } </script> <style lang="

python判定两个列表list是否具有完全相同的元素

判断两个列表list是否具有完全相同的元素,不考虑元素的顺序,两个list中的每一个list中都可能有相同的元素,所以这个算法应该是比较通用的。 def two_list_have_same_element(l1, l2): if len(l1) != len(l2): return False else: n = len(l1) matched = [False for i in range(n)] for i1 in range(n): flag = 1 for i2 in range(n): if matched[i2] == False and l1[i1] == l2[i2]: flag = 0 matched[i2] = True break if flag == 1: return False return True

【翻译】Graphlib API 指南

github - raphlib 文章目录 安装npm Install 介绍API 指南图像概念展现节点和边线Multigraphs复合图默认标签Graph APIgraph.isDirected()graph.isMultigraph()graph.isCompound()graph.graph()graph.setGraph(label)graph.nodeCount()graph.edgeCount()graph.setDefaultNodeLabel(val)graph.setDefaultEdgeLabel(val)graph.nodes()graph.edges()graph.sources()graph.sinks()graph.hasNode(v)graph.node(v)graph.setNode(v, [label])graph.removeNode(v)graph.predecessors(v)graph.successors(v)graph.neighbors(v)graph.inEdges(v, [u])graph.outEdges(v, [w])graph.nodeEdges(v, [w])graph.parent(v)graph.children(v)graph.setParent(v, parent)graph.hasEdge(v, w, [name]) / graph.hasEdge(edgeObj)graph.edge(v, w, [name]) / graph.edge(edgeObj)graph.setEdge(v, w, [label], [name]) / graph.setEdge(edgeObj, [label])graph.removeEdge(v, w, [name]) 序列化json.write(g)json.read(json) 算法alg.components(graph)alg.dijkstra(graph, source, weightFn, edgeFn)alg.dijkstraAll(graph, weightFn, edgeFn)alg.findCycles(graph)alg.isAcyclic(graph)alg.postorder(graph, vs)alg.preorder(graph, vs)alg.prim(graph, weightFn)alg.tarjan(graph)alg.topsort(graph) 安装 npm Install $ npm install @dagrejs/graphlib 介绍 Graphlib是一个JavaScript Lib库,为无向和有向多变图提供数据结构,以及可以一起使用的算法。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7YWcTEXZ-1648378764148)(https://secure.travis-ci.org/dagrejs/graphlib.svg)] 更多学习内容, 查看wiki。 API 指南 本部分主要阐述graphlib的概念并提供API指南。默认情况下,graphlib函数和对象暴露在graphlib的命名空间下。 图像概念 Graphlib有一种图类型: Graph。 创建一个新的实例: var g = new Graph(); 默认情况下,将会创建一个不允许多边或者复合节点的有向图。以下则是参数选项: directed:设置为true时, 得到一个有向图。false时, 得到一个无向图。无向图不会把节点的顺序视为第一要务。换句话说, 对无向图来说g.

java实现Treap

Treap树(笛卡尔树)= Heap (堆)+BST (二叉搜索树 binary search trea)。这是一颗既满足堆的性质与BST的性质的树。 当我们只知道一颗二叉查找树(BST)的 valval 的时候,我们可以将任意一个点作为根节点,任意一个比此点 valval 小的点作为左儿子,任意一个比此点 valval 大的点作为右儿子,按照此种方法建树后,如果我们进行中序遍历,会发现遍历出的序列是有序且一定的。 那么小顶堆(Heap)的性质是修正值最小的点一定在最上方,也就是根,左儿子和右儿子的 rndrnd 是左子树和右子树分别的最小值,由于有BST的性质限制,又有了Heap的性质限制后我们就发现这棵树的结构也是一定的。 public class Treap{ class Node{ Node right; Node left; Object data; Node parent; int priority; public Node(Object d,int pro,Node p){ data=d;priority=pro;parent=p; } public void printTree(Node root){ if(root!=null){ printTree(root.left); System.out.println(root.data); printTree(root.right); } } /** *查找 */ public Node query(Node root,int value){ Node node=root; while(node!=null){ if((int)node.data>value){ node=node.left; }else if((int)node.data<value){ node=node.right; }else{ return node; } } return null; } public Node insert(Object value,Node root,Node p){ if(root==null) return new Node(value,(int)(Math.

java zip工具类

<dependency> <groupId>org.apache.ant</groupId> <artifactId>ant</artifactId> <version>1.8.2</version> </dependency> package com.test.util; import org.apache.tools.zip.ZipEntry; import org.apache.tools.zip.ZipFile; import org.apache.tools.zip.ZipOutputStream; import java.io.*; import java.util.Enumeration; import java.util.zip.CRC32; import java.util.zip.CheckedOutputStream; public class ZipUtil { private static final int BUFSIZE = 1024; private static void compressbyType(File src, ZipOutputStream zos, String baseDir) { if (!src.exists()) return; if (src.isFile()) { compressFile(src, zos, baseDir); } else if (src.isDirectory()) { compressDir(src, zos, baseDir); } } public static void compress(String srcFilePath, String destFilePath) { File src = new File(srcFilePath); if (!

力扣每日一题(难的我也不会)2028. 找出缺失的观测数据(2022.3.27)

2028. 找出缺失的观测数据 现有一份 n + m 次投掷单个 六面 骰子的观测数据,骰子的每个面从 1 到 6 编号。观测数据中缺失了 n 份,你手上只拿到剩余 m 次投掷的数据。幸好你有之前计算过的这 n + m 次投掷数据的 平均值 。 给你一个长度为 m 的整数数组 rolls ,其中 rolls[i] 是第 i 次观测的值。同时给你两个整数 mean 和 n 。 返回一个长度为 n 的数组,包含所有缺失的观测数据,且满足这 n + m 次投掷的 平均值 是 mean 。如果存在多组符合要求的答案,只需要返回其中任意一组即可。如果不存在答案,返回一个空数组。 k 个数字的 平均值 为这些数字求和后再除以 k 。 注意 mean 是一个整数,所以 n + m 次投掷的总和需要被 n + m 整除。 今天的题简单,小学数学学的可以就能过 直接模拟,计算出长度为n的数组的总和,除以n得到每个位置上的数,如果不是整除,记录下差了多少个整除,并将他们的值加一即可,最后对数据边界做一些整理 代码如下 class Solution { public int[] missingRolls(int[] rolls, int mean, int n) { int len = rolls.

字符转换-PTA

本题要求提取一个字符串中的所有数字字符('0'……'9'),将其转换为一个整数输出。 输入格式: 输入在一行中给出一个不超过80个字符且以回车结束的字符串。 输出格式: 在一行中输出转换后的整数。题目保证输出不超过长整型范围。 输入样例: free82jeep5 输出样例: 825 解析:遍历输入的字符串,把字符串中的数字筛选出来 int main() { char str[81] = { 0 }; gets(str); int count = 0; for (int i = 0; i < 81; ++i) { if (str[i] >= '0' && str[i] <= '9') { count = count*10 + str[i] - '0'; } } printf("%d", count); return 0; }

Go~实现自定义Error返回体

error接口 假设你就已经创建和使用过神秘的预定义error类型,但是没有解释它究竟是什么。实际上它就是interface类型,这个类型有一个返回错误信息的单一方法: // The error built-in interface type is the conventional interface for // representing an error condition, with the nil value representing no error. type error interface { Error() string } 创建一个error最简单的方法就是调用errors.New函数,它会根据传入的错误信息返回一个新的error。 调用errors.New函数是非常稀少的,因为有一个方便的封装函数fmt.Errorf,它还会处理字符串格式化。 func Errorf(format string, args ...interface{}) error { return errors.New(Sprintf(format, args...)) } 那如果我们想自定义一个error自然实现这个error接口即可 自定义error package main import ( "fmt" "os" "time" ) type PathError struct { path string op string createTime string message string } // 自定义返回体 func (p *PathError) Error() string { return fmt.

用python裁剪PDF文档

在阅读PDF文档时,个人习惯在笔记本上双页阅读,但有的PDF边距太宽,看起来字很小,阅读吃力 本代码用来裁剪整个PDF文档间距 import PyPDF2 import os left_margin = right_margin = 30 top_margin = 5 bottom_margin = 5 input_file_path = [] output_file_path = [] os.makedirs('.\\修改') # 新建文件夹 file_path = '.\\' file_list = os.listdir(file_path) for i in file_list: if os.path.splitext(i)[1] == '.pdf': input_file_path.append('.\\' + i) output_file_path.append('.\\修改\\' + '修改' + i) def split(page): page.mediaBox.lowerLeft = (left_margin, bottom_margin) page.mediaBox.lowerRight = (width - right_margin, bottom_margin) page.mediaBox.upperLeft = (left_margin, height - top_margin) page.mediaBox.upperRight = (width - right_margin, height - top_margin) for m in range(len(input_file_path)): input_file = PyPDF2.

【算法】【华为】2019华为笔试 找终点:给定一个正整数数组,最大为100个成员,从第一个成员开始,走到数组最后一个成员最少的步骤数,

■题目描述 给定一个正整数数组,最大为100个成员,从第一个成员开始,走到数组最后一个成员最少的步骤数, 第一步必须从第一元素开始,1<=步长<len/2, 第二步开始以所在成员的数字走相应的步数,如果目标不可达返回-1,只输出最少的步骤数量 思路1:从前往后进行遍历,第一步走1步,求解;第一步走2步,求解,第一步走…… 走(len/2)步,分别求解,如果可以达到终点,则记录步数,如果步数足够小,则保存。这样复杂度是O( n 2 n^2 n2)。思路2:从后往前遍历,指针记录距离尾部距离,例如:nToTail=0,指针在9位置;nTotail=1,指针在3位置,由于3!=nToTail而且大于nToTail,不计算,指针继续前移;同样,指针一直移动,直到nToTail=6此时data[len-1-6]=6,保存此时的步长并继续向前移动,直到找到表头为止;此时,指针移动到nToTail=9,data[len-1-9]=9,所以更新最大步长为9;继续找到表头,无符合的数据了从刚才找到的最大步长开始继续往前找,令指针指向data[len-1-9]位置,更新距离为0。此时,len-1-9已经小于len/2所以可以一步到位;否则应该从9开始,继续往前找,直到找到一个步长,可以从后往前越过len/2的位置。 可以看到,思路2的耗时明显很少,采用思路2进行编码 PS:会不会有从前往后走能走通,但是从后往前走走不通的情况呢: 考虑到类似:1,3,1,2,120,1,0的输入,从后往前走,会遇到120,此时会走不通,但是走到2的时候,由于走两步到倒数第二个1,所以120并不影响。(这个证明并不严谨,大概是这个意思) 代码: #include <iostream> using namespace std; /**********************************************/ // 给定一个正整数数组,最大为100个成员,从第一个成员开始, // 走到数组最后一个成员最少的步骤数, // 第一步必须从第一元素开始,1 <= 步长 < len / 2, // 第二步开始以所在成员的数字走相应的步数,如果目标不可达返回 - 1, // 只输出最少的步骤数量 int FindEnd(int* numbers, int length) { if (numbers == nullptr || length <= 1) { return -1;//不存在,输出-1 } int nIndex = length - 1; // 尾部指针 int nToTailDist = 0; // 指针距离尾部距离 int nMaxStep = 0; // 最大距离 int nStep = 0; // 当前走的步数 while (true) { if (nToTailDist == numbers[nIndex] && nMaxStep < nToTailDist) { // 找到可达步长 nMaxStep = nToTailDist; } nIndex--; // 移动指针 nToTailDist++; if (nIndex < 0) { if (nMaxStep ==0) { // 如果该回合没有找到一个最大步数,说明卡住了,没有可达步数 return -1; } nStep++; nIndex = length - 1 - nMaxStep; if (nIndex <= length / 2) { if (nIndex>0) { nStep++; return nStep; } else { return nStep; } } nToTailDist = 0; nMaxStep = 0; } } return -1; } void Test(int v1,int v2,const char*name) { if (v1 == v2) { cout << name << "

2019华为笔试 找终点

【算法】【华为】2019华为笔试 找终点:给定一个正整数数组,最大为100个成员,从第一个成员开始,走到数组最后一个成员最少的步骤数, https://blog.csdn.net/qinglingLS/article/details/123765889 本题答案已经修改,请前往上面网址👆 本题答案已经修改,请前往上面网址👆 本题答案已经修改,请前往上面网址👆 本题答案已经修改,请前往上面网址👆 本题答案已经修改,请前往上面网址👆 本题答案已经修改,请前往上面网址👆 本题答案已经修改,请前往上面网址👆 本题答案已经修改,请前往上面网址👆 本题答案已经修改,请前往上面网址👆 本题答案已经修改,请前往上面网址👆 本题答案已经修改,请前往上面网址👆 本题答案已经修改,请前往上面网址👆 本题答案已经修改,请前往上面网址👆 本题答案已经修改,请前往上面网址👆 本题答案已经修改,请前往上面网址👆 本题答案已经修改,请前往上面网址👆 本题答案已经修改,请前往上面网址👆 本题答案已经修改,请前往上面网址👆 本题答案已经修改,请前往上面网址👆 本题答案已经修改,请前往上面网址👆 ■题目描述 给定一个正整数数组,最大为100个成员,从第一个成员开始,走到数组最后一个成员最少的步骤数, 第一步必须从第一元素开始,1<=步长<len/2, 第二步开始以所在成员的数字走相应的步数,如果目标不可达返回-1,只输出最少的步骤数量 这个题我理解错了,以为每一步都可以走 0<x<步长数字,写的代码通过率40%, 哎,我好菜啊。。 #include <stdio.h> #include <stdlib.h> int main() { int group[100]= {0}; int num=0; int max=0; while(scanf("%d",&group[num])!=EOF) { if(max<group[num]) { max=group[num]; } //printf("%d ",group[num]); num+=1; } //printf("max:%d\n",max); num=num-1; int time=0; int i=0; int flag=0; int maxstep=0; int maxindex=0; while(num>=0) { maxstep=0; maxindex=0; for(i=0; i<=max&&num-i>=0; i++) { //printf("

Flutter简介

一、Flutter简介🔥 Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面。 Flutter可以与现有的代码一起工作。在全世界,Flutter正在被越来越多的开发者和组织使用,并且Flutter是完全免费、开源的,可以用一套代码同时构建Android和iOS应用,性能可以达到原生应用一样的性能。 一句话总结就是:Flutter是一个跨平台、高性能的移动UI框架 🔴跨平台 Flutter使用自己的高性能渲染引擎来绘制 Widget([ˈwɪdʒɪt]),这样可以保证在 Android 和iOS 上 UI 的一致性,目前 Flutter 已经支持 iOS、Android、Web、Windows、macOS、Linux、Fuchsia(Google新的自研操作系统)等众多平台。 🟠高性能 Flutter的高性能主要靠两点来保证: 采用 Dart 语言开发使用自己的渲染引擎来绘制 UI Dart语言在JIT模式下,执行速度与 JavaScript 基本持平。但是它支持AOT,以 AOT模式运行时,JavaScript 便远远追不上了,执行效率也就大大提升。并且Flutter使用自己的渲染引擎绘制UI,布局数据都由Dart语言直接控制,性能开销比较可观 下面看看Flutter与其他跨平台的移动开发技术比较: 技术类型UI渲染方式性能开发效率动态化框架代表H5 + 原生WebView渲染一般高支持Cordova、IonicJavaScript + 原生渲染原生控件渲染好中支持RN、Weex自绘UI + 原生调用系统API渲染好Flutter高, Qt低默认不支持Qt、Flutter 二、采用Dart语言开发 采用Dart语言开发,顾名思义文件扩展名以 .dart 结尾。 Flutter为什么会选择 Dart 语言而不选择我们前端鲜为人知的 JavaScript 呢? 🔴开发效率高 Flutter 在开发阶段采用,采用 JIT 模式,这样就避免了每次改动都要进行编译,极大的节省了开发时间Flutter 在发布时可以通过 AOT 生成高效的机器码以保证应用性能。而 JavaScript 则不具有这个能力 🟠高性能 Flutter 中能够在每个动画帧中运行大量的代码。这意味着需要一种既能提供高性能的语言,而不会出现会丢帧的周期性暂停,而 Dart 支持 AOT,在这一点上可以做的比 JavaScript 更好 🟡快速分配内存 类型安全和空安全 Dart 是类型安全的语言,支持静态类型检测,可以在编译前发现一些类型的错误,并排除潜在问题JavaScript 是一个弱类型语言,需要给JavaScriptdiamagnetic添加静态类型检测的扩展语言和工具 三、Flutter框架结构 这里对Flutter的框架做一个整体介绍,可以有个整体印象

设计模式--今天就学这么多

设计模式 设计模式,其实就是一种写代码时的设计思想。 分类: 创建型 单例模式 原型模式 构造器模式 工厂模式 抽象工厂模式 结构型 桥接模式 外观模式 组合模式 装饰器模式 适配器模式 代理模式 享元模式 行为型 迭代器模式 解释器模式 观察者模式 中介者模式 访问者模式 状态模式 策略模式 命令模式 模板模式 为什么要学习理解设计模式 我们在写代码,写页面时,为了可维护、可迭代、可读性、低耦合性等等,有时需要考虑 逻辑代码该怎么封装,组件该怎么封装,设计模式 就是 前人从以往的经验中总结出来的一些 书写代码的思想(或者说套路),帮助我们更快的做决定、做判断,为了更好的应对我们的场景,我们眼下这块代码该怎么写。 设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结(来自百度百科) 注意: 我们实现某块功能,某个组件时,可以结合多个设计模式 外观模式(Facade) 概念: 为子系统中的 一组接口 提供一个一致的界面,外观模式定义了 一个高层接口 这个 接口 使得这一子系统更加容易使用。 引入外观角色之后,用户只需要直接与外观角色交互 用户与子系统之间的复杂关系由外观角色内部来处理,从而降低了系统的耦合度 应用示例: 普通登录、邮箱登录、手机登录,三个表单,那么我们就要判断该显示那个表单 先经过一层简单封装,变为: 逻辑处理还是留在了使用层 所以,使用 外观模式: 将逻辑判断和处理留在封装组件的内部,组件变得可读,可随意抽离 单例模式 概念: 保证一个类只有一个实例(提供一个访问它的全局访问点,无论”创建“多少次,都只返回第一次所创建的那个唯一的实例) 单例模式是创建型设计模式的一种。针对全局仅需一个实例的场景 实现需求: 具备判断自己是否已经创建过该实例的的能力 理解与应用 jquery 我们全局需要几个,只需要一个,所以这就是符合单例模式的 逻辑代码层面: 静态方法实现: <span style="background-color:#f8f8f8"> <span style="

解决:java -version,java,javac不是内部或外部命令,也不是可运行的程序 或批处理文件。

命令行输入java,java -version,javac都显示不是内部或外部命令。 1.首先查看了自己的环境变量: 经过学习确实都是环境变量出现问题,之前的环境变量都是%JAVA_HOME%\bin,全部换成了绝对路径如:C:\Program Files\Java\jdk1.8.0_321\bin 2.之后java,java-version好了,javac还是不对 网上一番搜索,path里面的如C:\Program Files\Java\jdk1.8.0_321\bin;我加了分号,把;去掉,再重启命令行,输入,一切OK。

数字信号处理(复试问题专业课考察)

1、什么是数字信号,什么是模拟信号?两者的根本区别是什么? 2、数字通信的优缺点? 答:优点:抗干扰能力强、噪声不积累、差错可控; 缺点:需要较大的传输带宽。 3、按照调制方式,通信系统可以分为? 答:基带传输系统和带通传输系统 基带传输:是指信号没有经过调制而直接送到信道中去传输的通信方式。 频带传输:是指信号经过调制后再送到信道中传输,接收端有相应解调措施的通信方式。 4、信号的复用方式? 答:时分、频分、码分 5、按照信号特征分类:模拟、数字通信系统 6、按照通信方式:单工(广播)、半双工(对讲机)、双工(电话) 7、按照数字码元排列顺序:并行、串行传输 8、通信系统的主要性能指标:有效性、可靠性 9、模拟信号:有效性:带宽 可靠性:信噪比 10、信源编码目的:提高传输有效性;信道编码目的:提高信号传输可靠性; 11、数字信号:有效性:传码率、传信率、频带利用率 可靠性:误码率、误信率 12、随机过程的统计特性:分布函数或概率密度表示。 13、广义平稳随机过程:与时间起点无关(严平稳),只与时间间隔有关。(广义包含严) 14、各态历经:用一次实现的“时间平均”值来代替“统计平均”值,从而大大简化。 15、高斯过程(正态分布)经过线性变换后生成的过程仍是高斯过程。 16、窄带平稳高斯过程,均值为零,方差ð2,其包络为瑞利分布,相位均匀分布。 17、“窄带”:频带宽度远小于中心频率,中心频率远离零频。 18、“加性噪声”:噪声以相加的形式作用在信号上。 19、“白”:指他的功率谱在频率范围内分布均匀(大于工作频带)。 20、“高斯白噪声”:白噪声其概率分布服从高斯分布。 21、“低通白噪声”:白噪声通过理想低通滤波器。 22、正弦载波信号加窄带高斯噪声的包络一般为:莱斯分布。 23、 R(0)=平均功率 R(无穷)=直流功率 24、码间串扰:相邻码元波形之间发生部分重叠。 25、衰落:信号包络因传播有了起伏的现象。 26、快衰落:由多径效应引起的衰落。 27、AM的总功率:Pc(载波功率)+Ps(边带功率),Pc=1/2 A0*A0 28、AM:包络检波恢复;FM、PM:相干解调恢复 29、“门限效应”:输出信噪比急剧恶化的现象,是由包络检波器的非相干解调作用引起的。 30、线性调制:针对幅度;非线性调制:针对频率与相位。 31、加重技术:输出信号不变,降低输出噪声,达到提高输出信噪比的目的。 32、抗噪声性能:WBFM最好,AM最差;频带利用率:SSB最高,FM最低。 33、线性调制的通用模型:滤波法和相移法 34、AMI:传号交替反转码;HDB3:三阶高密度双极性码。 35、眼图:用示波器观察接收端的基带信号波形,从而估计和调整系统性能的一种方法。 36、最佳抽样时刻:眼睛张开最大时刻;判决门限电平:中央横轴位置。 37、改善系统性能的两种措施:部分响应和均衡。 38、QAM:正交振幅调制;MSK:最小频移键控; 39、MSK:包络恒定、相位连续、带宽最小且严格正交的2FSK信号。 40、GMSK:高斯最小频移键控 41、OFDM:正交频分复用:(1)多载波并行调制体制(2)各路子载波有部分重叠且为多进制调制(3)调制制度不同,采用不同体制 42、数字化过程:抽样、量化、编码。 43、PCM:脉冲编码调制。 44、∆M(DM):增量调制 45、最佳基带传输系统:消除了码间串扰且误码率最小的基带传输系统 46、在PCM30/32系统中,信息传输速率为:2.048Mb/s 47、理想低通频带利用率最大:2B/Hz; 48、仅用低通滤波器,不可以将平顶抽样信号恢复。 49、在PCM中,对语音信号进行非均匀量化的理由是:小信号概论大,大…小; 50、二进制确知信号中,PSK信号是最佳信号形式。 51、信号在恒参信道不失真条件:幅频特性为常数,相频特性为过原点的直线。 52、折叠二进码对比自然码优点:误码对小电压影响小。 53、匹配滤波器:使输出信噪比最大的线性滤波器。 54、Ad hoc : 点对点 (无线移动通信模式) 55、非均匀量化的目的:提高输出信噪比; 56、调制信道的范围:调制器输出端到解调器输入端; 57、汉明码:能够纠正一位,检错2位,效率最高的线性分组码; 58、狭义信道的含义:传输媒介; 59、VSB在电视广播系统中应用的原因:电视图像信号的低频分量丰富.

Python基础知识(Python的简介、Python环境的安装、集成开发环境Pycharm的安装)

1.Python的简介 python是跨平台的计算机语言、解释型语言、交互式语言、面向对象语言、初学者最好学的语言 什么是跨平台:意思就是说可以在很多操作系统中执行。比如:可以在windows操作系统里执行、也可以在苹果操作系统里执行、 什么是解释型:就是写完之后由我们的解释器直接执行,没有编译这个环节,但是Java里会有编译 什么是交互式:就是可以在提示符>>>后直接写代码,回车 什么是面向对象:对于python来说一切皆为对象 为什么说最好的方法:因为python语法简单、写起来不复杂、支持广泛的应用程序 2.Python环境的安装 搭建Python开发环境 安装Python解释器 Welcome to Python.org 官网 https://www.python.org/7dowmlods/release/python-381/ 找到适合自己的版本 下载完成 IDLE(Python 3.10 64-bit ) : python自带简单开发环境,写短的代码可以直接在>>>后写,写多的可以新建文件 再写 Python 3.10(64-bit): python命令行交互式模式 Python 3.10 Mauals(64-bit):官方技术文档 Python3.10 Module Docs (64-bit):已安装的模块文档 3.集成开发环境Pycharm的安装 PyCharm安装教程(Windows) PyCharm下载地址:PyCharm 安装教程(Windows) | 菜鸟教程http://www.runoob.com/w3cnote/pycharm-windows-install.html 1)下载好之后打开---新建项目(点击左上角Projiect右击选择New Project--选择Pure-Python可以选择自己喜欢的盘符新建个文件存放数据) 2)完成后点击Project interpreter:New Virtualenv environment---d点击Base interpreter:选择哪个开发环境 3)再往下选择Existing interpreter扩展 然后创建 4)创建完成之后可以右击项目--选择New--选择Python File创建新的文件 5)可以自己取名

Java编写简易控制台计算器

Java编写简易控制台计算器 主要需求与功能: 包含四个基本运算:加,减,乘,除利用while循环和switch选择结构包含两个基本操作数输出结果后可选择退出或继续使用 import java.util.Scanner; public class Calculator { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); //scanner进行交互。 int i = 0; //定义一个用于判定循环是否继续的值,后可通过if改变i值以达到可选择继续计算或退出计算的目的。 while(i<1) { System.out.println("请输入第一个数字:"); float a = scanner.nextFloat(); //获取第一个需进行运算的数值 System.out.println("请输入第二个数字:"); float b = scanner.nextFloat(); //获取第二个需进行运算的数值 System.out.println("请选择运算符号:"); System.out.println("1:加法"); System.out.println("2:减法"); System.out.println("3:乘法"); System.out.println("4:除法"); int options = scanner.nextInt(); float c; switch (options) { //利用switch选择结构进行运算方式的选择 case 1: c = a + b; System.out.println(a + "+" + b + "=" + c); break; case 2: c = a - b; System.

less基础

一,概览 Less (Leaner Style Sheets 的缩写) 是一门向后兼容的 CSS 扩展语言。这里呈现的是 Less 的官方文档(中文版),包含了 Less 语言以及利用 JavaScript 开发的用于将 Less 样式转换成 CSS 样式的 Less.js 工具。 变量(Variables) 无需多说,看代码一目了然: @width: 10px; @height: @width + 10px; #header { width: @width; height: @height; } 编译为: #header { width: 10px; height: 20px; } 混合(Mixins) 混合(Mixin)是一种将一组属性从一个规则集包含(或混入)到另一个规则集的方法。假设我们定义了一个类(class)如下: .bordered { border-top: dotted 1px black; border-bottom: solid 2px black; } 如果我们希望在其它规则集中使用这些属性呢?没问题,我们只需像下面这样输入所需属性的类(class)名称即可,如下所示: #menu a { color: #111; .bordered(); } .post a { color: red; .

C语言-排序

十大排序算法 冒泡排序快速排序选择排序直接插入排序希尔排序归并排序堆排序计数排序基数排序桶排序 一、冒泡排序 原理: 两两比较相邻元素,如果顺序不对,则进行交换。达到使小数如气泡一样往上浮动(例如在数组中将元素左移),或者使大数如石头一样下沉(在数组中将元素右移) 步骤: 设待排序的n个元素存放在数组r[0…n-1] (注:此处数组下标从0开始)中,首先将第一个元素和第二个元素对比,如果(r[0] > r[1])则交换两个元素顺序。接着比较第二个和第三个元素。依次类推,直至r[n-2]和第r[n-1]进行比较。这个过程就是第一趟起泡排序,结果是最大的元素被放在了r[n-1]的位置(即最后一个位置)进行第二趟起泡排序,对前n-1个元素进行同样的操作,使第二大的数放在了r[n-2]的位置重复上述步骤,第i趟是从r[0]到r[n-i-1] (注:这里i也是从0开始)依次比较两个元素,并在逆序(前一个元素比后一个元素大)时交换顺序,结果是n-i个元素中值最大的数被放到了r[n-i-1]的位置。直到在某一趟排序过程中没有进行交换操作,说明序列已经全是顺序排列(从左到右元素从小到大排列) 代码实现: int oriData[8] = {49,38,65,97,76,13,27,49}; void bubbleSprt(int* data, int len) { int flag = 1; //用于记录某本趟排序是否发生顺序交换 for(int i = 0; (i < len) && (flag == 1); i < len) { flag = 0; //flag置为0,如果本趟Paiute没有发生交换,则说明全部数据已经是顺序排列,不需要再比较 for(int j = 0; j < len - i - 1; j++) { if(data[j] > data[j + 1]) { int tmp = data[j + 1]; data[j + 1] = data[j]; data[j] = tmp; //交换顺序 flag = 1; //表明本趟排序发生了交换 } } } return; } 算法分析:

面试考点:session和cookie

文章目录 一、关于 cookie 的前言概括二、session 工作原理三、常用的方法3.1 getSession()3.2 getAttribute()和setAttribute() 四、关系总结图五、实操:实现登录功能并计算访问页面的次数5.1 登录页面实现(login.html)5.2 判断是否登录成功 Servlet 程序(LoginServlet)5.3 显示访问次数 Servlet 程序(IndexServlet)5.4 结果验证与展示 一、关于 cookie 的前言概括 在之前的 HTTP 格式的介绍当中,有详细的介绍过 cookie 的相关用法。 简单回顾总结就是: cookie 是让程序员能够在客户端持久存储数据的一种机制存储的是程序员自己定义的键值对通过服务器响应 set-cookie 这个 header 获取到 cookie 的值,并保存到本地下一次请求就会带上 cookie ,发送给服务器 用户输入账号密码登录后,再次登录不需要再次输入账号密码就可以直接的登录成功就是依靠 cookie 来实现的 但是有关于用户的信息实际上是非常多的,比如访问网站的浏览记录,上次访问网站的时间等等,这么多的信息在服务器客户端之间传输来又去的非常浪费带宽。更何况 cookie 的存储容量又是有限的,一个站点最多保留20个 cookie,这么多的用户信息没有办法单纯的依靠 cookie 来保存在客户端,因此将数据保存到服务器端才是比较科学的做法。 二、session 工作原理 因为要将信息存储在服务器端,就引入了会话机制 session。 session是服务端存储的一个对象,主要用来存储所有访问过客户端网页的用户信息(也可以存储其他信息),从而实现保持用户会话状态。但是服务器重启时,内存会被销毁,存储的用户信息也就消失了。 面试题:详述 session 工作原理 当客户端登录完成后,就会在服务器端产生一个 session,,实际上是一个键值对,key 是 sessionId(随机唯一的字符串),value 保存的就是身份信息(HttpSession 对象)。服务器端将这些键值对形式的会话通过hash 表的形式管理起来此时服务器端就会将 sessionId返回到客户端浏览器。客户端将 sessionId 存储在浏览器的 cookie 中当用户再次登录的时候,就会拥有对应的 sessionId ,就将该 sessionId 发送到服务器端请求登录服务器端在内存中找到对应的 sessionId 就完成登录,如果找不到,说明还没有登录(每个用户登录都会生成一个会话),就返回登录页面让用户进行登录 session 工作原理和校园卡差不多,校园卡中实际上并没有保存太多的内容,但是有着它在学校中拥有的唯一的信息——学号。因此你(客户端)拎着这张卡,通过学号(相当于sessionId)就可以在系统中(服务器)搜索到有关于你的相关具体学生信息,就可以凭借卡进出宿舍大门,在图书馆借书,在食堂吃饭等等。

Android 开发bug杂记

1.调用camera 时闪退, 原因,FileUriExposedException,/stxx/0/xx 解决:OnCreate中调用 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder(); StrictMode.setVmPolicy(builder.build()); } 原文链接:https://blog.csdn.net/xiaoyu940601/article/details/54406725 2.导入其他项目或者library时,V4,V7包冲突, Error:Execution failed for task ‘:app:transformClassesWithDexForDebug’. com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException 解决: 解决方式一: 由于EaseUI中的v4 jar一般比较旧,所以果断将v4包从libs目录下删除,重新添加在线的依赖库v4包,在build.gradle中添加依赖: 这位博主的 https://x-sir.blog.csdn.net/article/details/53199272?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2defaultCTRLISTRate-1.pc_relevant_antiscanv2&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2defaultCTRLISTRate-1.pc_relevant_antiscanv2&utm_relevant_index=1 JNI开发中,如果有例子可供参考,那么对应的类名、包名都要与例子中的一致,不可更改 4.SwitchCompat控件运行时奔溃 解决: SwitchCompat时v7的style,需要theme.appcompat的主题才能用 控件属性加上 android:theme="@style/Theme.AppCompat.Light"

基于华为云平台上iMaster-NCE Campus的中继认证(RADIUS方式)方案简介及配置参考

基于华为云平台上iMaster-NCE Campus的中继认证(RADIUS方式)方案简介及配置参考 功能概述 第三方认证主要应用于商业Wi-Fi终端用户在商场酒店、机场地铁、企业来访等情景通过Wi-Fi访问互联网的场景,需要对接入网络的访客进行用户认证,同时提供宣传,推荐及营销等功能,通过认证的访客被允许接入Wi-Fi使用网络。 第三方合作伙伴或开发者为接入访客提供认证Portal页面(如下图),并调用华为iMaster NCE-Campus API授权接口,或通过标准RADIUS协议与iMaster NCE-Campus交互,从而实现认证、计费、用户分析、市场营销等服务。 环境拓扑 此方案涉及功能点如下: 1.华为网络设备(Cloud AP)提供接入网络等功能。 2.华为云平台(iMaster NCE-Campus)提供设备管理功能。 3.第三方Portal服务器提供Portal推送功能。 4.第三方RADIUS服务器提供用户信息校验,授权下发等功能。 认证流程 终端用户在需要访问互联网时,连接Wi-Fi的SSID,登录由第三方系统推送的Portal页面进行认证。随后第三方RADIUS系统与华为iMaster NCE-Campus云平台通过标准RADIUS协议对接,实现认证与计费功能。 配置流程 一.配置模板 1.进入模板配置。在主菜单中选择“设计 > 基础网络设计 > 模板管理”。 2.配置ACL模板,用于放通Portal和云平台的IP或域名,以及根据项目放通需要的其他地址(DNS,社交媒体等)。 3.配置URL模板,定义访问Portal Page URL时,传递的参数和取值。 4.配置RADIUS中继服务器模板,认证业务选择”Portal认证“,配置认证和计费服务器地址、密钥等信息。 二.配置Portal页面推送策略 云平台中继RADIUS认证模式下,用户需配置Portal 推送策略,并且url模版里要选用云平台中继认证的方式,终端关联WI-FI后,根据Portal推送策略给终端用户推送指定的Portal页面。 1.在主菜单中选择“准入 > 准入资源 > 页面管理”。选择“Portal页面推送策略”,单击“创建”。 a. 设置Portal页面推送名称,接入方式选择“无线”。 b. 配置认证方式为“云平台中继认证”,对接方式为“RADIUS中继”,URL模板选择配置模板章节中配置的模板,第三方认证URL填写相应的URL。并点击应用。 三.配置SSID SSID是终端用户无线接入网络时看到的网络名称。每个SSID可以指定一种认证方式,从而实现对无线接入的终端用户准入控制。 本章描述作为中继服务器时,通过配置SSID使终端接入网络,进行RADIUS中继方式认证。 1.选择站点。 a. 在主菜单中选择“配置 > 物理网络 > 站点配置”。 b. 在左上角“站点”下拉框中选择站点,将该站点设为操作对象。 2.在左侧导航中选择“AP > SSID”,单击“创建”,配置SSID基本信息。并点击下一步。 4.配置终端用户使用SSID接入网络时的认证方式。 设置“认证方式”为“开放网络”,“是否推送页面(Portal认证)”为“ON”,“页面推送方式”为“云平台中继认证”,“对接方式”为“RADIUS中继”。 设置第三方Portal页面认证所需的用户名、密码等参数信息。下图中第三方Portal服务器用户名参数为username,密码参数为password,成功页面参数为successUrl。 5.配置RADIUS中继服务器和默认放行推送的Portal页面地址,配置默认放行规则,添加默认放行的地址或域名后,用户在认证前可访问该地址或域名。 RADIUS中继服务器和默认放行规则可以使用配置模板章节中创建的模板,也可以在当前页面直接创建。 6.配置Portal免认证和实时计费。 7.如果需要,可以开启Portal免认证功能和实时计费功能。 8.最后单击“确定”。 完成以上配置后,终端客户能连上SSID,并会跳转到portal页面进行认证,认证成功后可正常访问网络。 参考文档 1.华为云园区网络文档

C语言高级用法---typeof()关键字

注:本文转载自https://blog.csdn.net/rosetta/article/details/90741468 前言 typeof() 是GUN C提供的一种特性,它可以取得变量的类型,或者表达式的类型。 本文总结了typeof()关键字的常见用法,并给出了相应的例子,以加深理解 。 typeof()关键字常见用法 typeof()关键字常见用法一共有以下几种。 不用知道函数返回什么类型,可以使用typeof()定义一个用于接收该函数返回值的变量 #include <stdio.h> #include <stdlib.h> #include <string.h> struct apple{ int weight; int color; }; struct apple *get_apple_info() { struct apple *a1; a1 = malloc(sizeof(struct apple)); if(a1 == NULL) { printf("malloc error.\n"); return; } a1->weight = 2; a1->color = 1; return a1; } int main(int argc, char *argv[]) { typeof(get_apple_info()) r1;//定义一个变量r1,用于接收函数get_apple_info()返回的值,由于该函数返回的类型是:struct apple *,所以变量r1也是该类型。注意,函数不会执行。 r1 = get_apple_info(); printf("apple weight:%d\n", r1->weight); printf("apple color:%d\n", r1->color); return 0; } 在宏定义中动态获取相关结构体成员的类型

C语言高级用法---container_of()

注:本文转载自https://blog.csdn.net/rosetta/article/details/90751028 在Linux内核源码中,实现和链表相关的接口list_entry()时,会调用container_of()宏定义,它的作用是:给定结构体中某个成员的地址、该结构体类型和该成员的名字获取这个成员所在的结构体变量的首地址。有点绕,没关系,接着往下看就能明白了。 container_of()宏定义实现如下所示 /** * container_of - cast a member of a structure out to the containing structure * * @ptr: the pointer to the member. * @type: the type of the container struct this is embedded in. * @member: the name of the member within the struct. * */ #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );}) 要看懂上述代码,需要知道三个关键点:

springboot多模块在创建一个可以独立部署的模块时遇到的坑

springboot多模块在创建一个可以独立部署的模块时遇到的坑 要在现有的项目新增一个新的模块该模块可以独立部署 思路:首先肯定是复制已有的模块来进行修改,创建启动类pom文件要集成maven统一管理插件 这个是我的模块,user-sign复制user-system模块,各自的启动类 接下来重点来了关于pom.xml文件 如果要让他自己能够运行则需要添加 特别是要引入配置模块和打包插件spring-boot-maven-plugin <?xml version="1.0" encoding="UTF-8"?> <!-- ~ Copyright 2019-2029 geekidea(https://github.com/geekidea) ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); ~ you may not use this file except in compliance with the License. ~ You may obtain a copy of the License at ~ ~ http://www.apache.org/licenses/LICENSE-2.0 ~ ~ Unless required by applicable law or agreed to in writing, software ~ distributed under the License is distributed on an "

力扣每日一题(难的我也不会)172. 阶乘后的零(2022.3.25)

172. 阶乘后的零 给定一个整数 n ,返回 n! 结果中尾随零的数量。 提示 n! = n * (n - 1) * (n - 2) * ... * 3 * 2 * 1 根据数学方法可以看出来,只有n是5的倍数时才会出现0,特殊的25,125,他们会产生两个0和三个0,对于五的倍数考虑一下就可以得出以下代码 class Solution { public int trailingZeroes(int n) { int res=0; for(int i=5;i<=n;i=i+5){ int t=i; while(t%5==0){ res++; t=t/5; } } return res; } } 结束!!! 开始学springcloud!!!

解决flask中app引用不到的问题

大型项目建议将app单独提出来定义 参考 https://github.com/xdqt/python-postgresql-flask-graphql https://stackoverflow.com/questions/14415500/common-folder-file-structure-in-flask-app https://flask.palletsprojects.com/en/2.0.x/patterns/packages/

机器学习(吴恩达)简要总结

机器学习知识简要总结 这里写目录标题 机器学习知识简要总结梯度下降法矩阵和向量多元线性回归:正规方程Normal equationlogistic回归过拟合问题正则化卷积神经网络模型选择和训练、验证、测试集评价指标无监督学习主成分分析 监督学习:给算法一个数据集,其中包含正确答案(有标记),数据集中的每个样本都给出正确答案,算法的目的是给出更多的正确答案。 无监督学习:对于给定的数据集,在未给出正确答案(无标记)的情况下将其分为不同的类,比如聚类算法。 回归:设法预测连续值的输出。 分类:预测离散值的输出。 线性回归: 拟合曲线Hypothesis: y = θ 0 + θ 1 x y=\theta_0+\theta_1x y=θ0​+θ1​x 平方误差代价函数Cost function: J ( θ 0 , θ 1 ) = 1 2 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 J(\theta_0,\theta_1)=\frac{1}{2m} \sum_{i=1}^{m}(h_\theta(x^{(i)})-y^{(i)})^2 J(θ0​,θ1​)=2m1​∑i=1m​(hθ​(x(i))−y(i))2, m m m为点的个数, y i y^i yi为真实值, y ( x i ) y\left(x^i\right) y(xi)表示函数值。

a标签实现文件或者图片的下载

1、当src是从后端返回来的,我们可以把遍历出的每一项的url放在href里面,记得href前面加上:,实现动态的获取超文本链接 <a :href="item.url" style="color: #6461ff">{{ item.name }}</a> 2、当你是点击当前项下载当前文件或者图片的时候传递当前项,具体看代码注释。 添加的字符串的作用是访问页面的时候浏览器就会开启下载框对其内容进行下载 preview(file) { //判断当前项是否存在url let url = file.url || ""; //如果没有,组织程序向下执行 if (!url) { return; } else { //如果url存在,创建一个新的a标签 let a=document.createElement('a') //在a标签的超文本链接上拼上当前项的url,后面加上这一字符串才能实现下载功能 //注意:如果不加此字符串,文件可以实现下载,图片只能实现预览功能 a.href=url+'?response-content-type=application/octet-stream'; //手动调用一下a标签的点击事件,实现下载 a.click() } }, },

查找书籍-给定n本书的名称和定价,本题要求编写程序,查找并输出其中定价最高和最低的书的名称和定价。

给定n本书的名称和定价,本题要求编写程序,查找并输出其中定价最高和最低的书的名称和定价。 输入格式: 输入第一行给出正整数n(<10),随后给出n本书的信息。每本书在一行中给出书名,即长度不超过30的字符串,随后一行中给出正实数价格。题目保证没有同样价格的书。 输出格式: 在一行中按照“价格, 书名”的格式先后输出价格最高和最低的书。价格保留2位小数。 输入样例: 3 Programming in C 21.5 Programming in VB 18.5 Programming in Delphi 25.0 输出样例: 25.00, Programming in Delphi 18.50, Programming in VB 解析:结构体的题目,不要自己创建数组,太麻烦。有一点要注意,这里是输入一个带空格的字符串,所以不能用scanf,只能用gets。用gets又出现一个问题,前面要用scanf输入一个数字,那么你输入的回车就会被gets吃掉,所以再gets前要给一个scanf(“\n”);防止吞吃回车。 //查找书籍 struct DATA { char name[30]; double price; }p[10], temp; int main() { int n = 0; scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("\n"); /*可能有些人不知道为啥呢要加这一步 , 这是因为gets函数的问题,上一个输入n是回车键结束,如果不加 这部,那么gets函数接收到的就是回车(\n),它就结束了,并 没有把实际要输的字符串输入。 以后出现需要输入字符串但是前面又出现了scanf不妨加这一步, 就可以不用for循环输入,直接使用gets*/ gets(p[i].name); scanf("%lf", &p[i].

AQS源码解析---以ReentrantLock为例

概述 学习并发编程,就必须要了解到AQS(AbstractQueuedSynchronizer)。比如经常使用的ReentrantLock就是继承的AQS,而且大部分的线程操作都是由AQS完成,ReentrantLock自身仅仅负责实现当前线程对共享资源的获取和释放功能。而AQS负责实现了对没有获取到资源的线程放入同步队列、阻塞、唤醒、溢出阻塞队列的操作。 其实对多线程获取资源分为三个步骤: (1)线程尝试获取资源; (2)将没有获取到资源的线程放入同步队列当中,线程进入等待状态(在此过程中,没有获取到资源的线程也会多次尝试重新获取资源); (3)在同步队列中陷入等待状态的线程被上一个节点中断等待,重新尝试获取资源。 架构 AQS的功能十分强大,既支持线程的共享资源抢占,也支持线程独占。这里先了解线程的资源独占方式。先明确两个概念: (1)共享资源是否被抢占有一个信号标识,标识为0则资源未被抢占,可以在源码中看到大量的cas操作; (2)线程在AQS中被封装成为一个node节点,node节点有前驱及后继,构成了等待队列。node节点有5中状态值: CANCELLED(1):表示当前结点已取消调度。当timeout或被中断(响应中断的情况下),会触发变更为此状态,进入该状态后的结点将不会再变化。 SIGNAL(-1):表示后继结点在等待当前结点唤醒。后继结点入队时,会将前继结点的状态更新为SIGNAL。 CONDITION(-2):表示结点等待在Condition上,当其他线程调用了Condition的signal()方法后,CONDITION状态的结点将从等待队列转移到同步队列中,等待获取同步锁。 PROPAGATE(-3):共享模式下,前继结点不仅会唤醒其后继结点,同时也可能会唤醒后继的后继结点。 0:新结点入队时的默认状态,此状态下的线程代表是就绪或执行状态。 我们这里先关注默认值0和SIGNAL(-1)两种状态即可。 1、ReentrantLock资源抢占 ReentrantLock默认是非公平锁,因此当前线程会什么都不管,先进行一次cas操作尝试获取锁,如下: final void lock() { //当前线程直接尝试获取资源 if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); else //开始进行后续的资源抢占方法 acquire(1); } 而如果是公平锁,则直接执行acquire(1)方法,这里是公平锁和非公平锁的区别之一,接下来还有一个地方可以展现两种锁的区别。 2、acquire() acquire()方法是在AQS中定义的,是对线程操作的入口方法,这里先进行大致说明。tryAcquire(arg)是让当前线程尝试获取资源,addWaiter(Node.EXCLUSIVE)是将当前线程封装为Node加入到等待队列,acquireQueued()是将线程执行park()方法进入到等待状态。 public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); } 2.1、tryAcquire() 可以看下AQS当中的方法源码,没有任何的功能逻辑,只是抛出了个异常。没错,这个方法需要我们自己去实现。 protected boolean tryAcquire(int arg) { throw new UnsupportedOperationException(); } 那我们看下ReentrantLock的tryAcquire()方法,ReentrantLock实现了公平锁和非公平锁两种方式,我们先看非公平锁 protected final boolean tryAcquire(int acquires) { return nonfairTryAcquire(acquires); } 好吧,那我们继续 nonfairTryAcquire(acquires)方法

c++虚函数纯虚函数

虚函数:用virtual关键字声明的; 纯虚函数:前面有virtual关键字,后面有=0; 纯虚函数的作用: 在c++中作为接口使用,因为c++没有专门的interface接口,就用纯虚函数来作为接口类。 抽象类 至少有一个纯虚函数的类,叫抽象类,注意是纯虚函数;抽象类只有一个用途:为派生类提供基类。抽象类不能实例化,但是抽象类可以有指针,指针就是用来操作衍生类。 知道纯虚函数是作为接口就行了,给被人写接口的时候用纯虚函数; 一般自己写经常用的还是虚函数,如果你预判这个方法在衍生类中会重写,那就把这个函数写成虚函数,子类中可以重写,也可以不重写,(如果是纯虚函数,必须重写); 虚函数的子类继承了父类的接口和父类的实现,如果调用一个父类和子类都有的方法,那就是采用就近原则,如果子类中有自己的定义,那就调用自己的,如果子类中没有自己的定义,就去父类里面找,调用父类的,父类没有,就去祖父类中找。 父类的指针指向子类的对象;父类的指针=子类的指针;这个叫上行转换,这个是绝对安全的转换,而且是隐式的,不需要static_cast或者dynamical_cast;赋值的本质是把数据写入内存,这里主要就是 成员变量和虚函数表。成员函数不需要赋值,不需要写入内存。成员函数存储在全局数据区;下行转换并非绝对不可以,必要条件是基类中必须有虚函数,有虚函数,才说明子类中可能有实现。

CorelDRAW Graphics Suite 2022零售版

图形设计软件CorelDRAW Graphics Suite 2022零售版2022年3月版发布!CorelDRAW2022主要增强了图像编辑和导出功能,新功能加快了图片编辑速度,带来新工具、快捷方式和命令菜单,优化了学习工具。 CorelDRAW(简称CDR)是一款专业的图形设计软件。该软件是加拿大Corel公司开发的一款功能强大的专业平面设计软件、矢量设计软件、矢量绘图软件。这款矢量图形制作工具软件广泛应用于商标设计、标志制作、封面设计、CIS设计、产品包装造型设计、模型绘制、插图描画、时装/服饰设计、印刷制版、排版及分色输出等诸多领域。经历二十多年的发展与蜕变,CorelDRAW系列已经发布了21个版本,其被广泛应用足以说明,其用户涵盖图形设计、平面设计、图文设计、广告设计、商业设计和美术设计等多个领域行业。 版本特点 采用2022年3月发布的零售版,免激活处理改装而成 修改了安装配置文件:写入序列号和免账户登陆处理 ﹂安装跳过用户许可协议,无需输入序列号直接跳过 ﹂安装过程自动提权屏蔽通知警告弹窗 ﹂取消安装完自动启动及打开帮助支持网页 删除额外的VC++运行库、VST组件安装包 删除几百多MB的用户指南帮助文档组件包 删除中文以外的其它多语言组件包 系统要求 Windows 11, Windows 10 (21H1 或更高版)64位 下载地址 mac直装安装包下载后在更新即可 : https://wm.makeding.com/iclk/?zoneid=42701 win直装安装包下载后在更新即可 : https://wm.makeding.com/iclk/?zoneid=41581 版权声明:本文为原创文章,遵循版权协议,转载请附上原文出处。

csdn中使用KaTeX给公式编号

说明:csdn用的公式编辑器是Katex,并不是LaTeX,两者语法有些区别,比如LaTeX中的公式编号\begin{equation}在KateX中就会解析错误,katex中,给公式编号用\tag{1}的形式,例如: E=mc^2\tag{1}实际的效果是: E = m c 2 (1) E=mc^2\tag{1} E=mc2(1) 注意:\tag{}只能用在公式单独占一行的情况,即公式用$$$$包围的情况。 \tag{}在行首或者行尾都可以。 KATEX公式编辑器符号大全-CSDN的Mardown公式支持 LaTeX介绍: LaTeX简介 快速查询某个数学符号对应的LaTeX表达式

CSS居中方式总结

行内元素 1.和其他元素都在同一行 2.高,行高及外边距和内边距部分可以改变 3.宽度只与内容有关 4.行内元素只能容纳文本或者其他行内元素 5.a,img,input,lable,select,sapn,textarea,font 块级元素 1.总是在新行上开始,占据一整行 2.高度,行高以及外边距和内边距都课控制 3.宽度始终与浏览器的宽度一样,与内容无关 4.可以容纳行内元素和其他块级元素 5.div,p,table,form,h1,h2,h3,dl,ol,ul,li 居中方式分为三种: 水平居中垂直居中水平垂直居中 水平居中 1.行内元素水平居中 利用text-align:center可以实现行内元素水平居中 对行内元素(inline),行内块(inline-block),行内表(inline-table),inline-flex也有效果。 <div class="center-text"> 简单是稳定的前提。 </div> div { height:60px; border: 2px dashed #f69c55; } .center-text { text-align: center; } 2.块级元素水平居中 通过把固定宽度的块级元素的margin-left和margin-right设成auto,就可以使块级元素水平居中 <div> <p class="center-block"> </p> </div> div { height:100px; border: 2px dashed #f69c55; } .center-block { margin: 0 auto; width: 8rem; padding:1rem; color:#fff; background:#000; } 3.多块级元素水平居中 方法一:利用inline-block 通过改变块级元素为inline-block和父容器的text-align属性来实现多块级元素水平居中 <div id="app"> <div class="center-block"> 第一个块级元素 </div> <div class="

集合框架最详细知识点含例题

# 集合框架 **集合**:把具有相同数据类型的一组变量,汇聚成一个整体,就被称之为集合。 **集合框架**:为了表示和操作集合而规定的一种统一标准的体系结构。最简单的集合如数组、队列和列表等。任何集合框架一般包含:对外的接口、接口的实现和对集合运算的算法。 - 接口:即表示集合的抽象数据类型(规范)。接口提供了让我们对集合中所表示的内容进行单独操作的方式(标准)。 - 实现:也就是集合框架中接口的具体实现。实际上它们就是那些可复用的数据结构。 - 算法:在一个实现了某个集合框架中的接口对象身上完成了某种有用的计算的方法,例如查找、排序等。 ## 接口的体系结构 ## Collection接口 对单个元素进行存放的最大接口规范。针对不同的方式它有不同的实现。 ### List接口 是Collection接口的子接口,主要针对于线性操作来提出的规范。 **特点**:可重复,有序的集合 #### Vector实现类 线性队列式结构的一种实现,它是线程安全的,多个线程同时对集合操作时保证了安全。 **特点**:数组结构、查询方便(只需要下标就行)、线程安全的,插入和删除的效率低下(涉及其后元素的位移) ```java // 1.如何产生Vector类的对象 // 产生了一个Vector集合,集合中只能存放Integer类型的元素 Vector<Integer> vector = new Vector<>(); // 2.Vector类的常用方法 // 存放到集合中 vector.add(88); // 添加到集合的末尾 vector.add(64); vector.add(1, 39); // 插入到指定位置之前 System.out.println(vector); // 获取集合的长度 int len = vector.size(); System.out.println("集合元素个数是:" + len); // 获取集合中的元素 int v1 = vector.get(1); // 获取指定位置的元素 System.out.println(v1); // 修改集合指定位置的元素内容 vector.set(2, 93); System.out.println(vector);

字节(Byte)、位(bit)

1、位: 数据存储的最小单位。每个二进制数字0或者1就是1个位; 2、字节: 8个位构成一个字节;即:1 byte (字节)= 8 bit(位); 1 KB = 1024 B(字节); 1 MB = 1024 KB; (2^10 B) 1 GB = 1024 MB; (2^20 B) 1 TB = 1024 GB; (2^30 B) 2个十六进制位占用一个字节(8个二进制) 1个十六进制=4个二进制 16=2^4 指针类型决定了:指针进行解引用操作的时候 能够访问空间的大小 int*p 能够访问4个字节 char*p 能够访问1个字节 double*p 能够访问8个字节 指针类型决定了:指针走一步能走多远(指针的步长) int*p: p+1-->4 char*p:p+1-->1 double*p:p+1-->8 接下来我们来看看这个题目 int* test() { int a = 10; return& a; } int main() { test(); return 0; } 这行代码虽然并不会报错,但是存在逻辑错误

隐藏滚动条但保持页面滚动及页面滚动条样式

在用React+Ant design的时候遇到过组件anchor对layout布局下(header+content),content滚动(overflow:scroll)无法做出反应的BUG,可以尝试给body加滚动条,此时anchor就可以使用了,然后隐藏掉body的滚动条就可以了,也可以用来实现页面无滚动条也可滑动的效果。同时汇总一些常用的滚动条样式: 全局滚动条隐藏 ::-webkit-scrollbar{ display: none; } 隐藏body的滚动条 body::-webkit-scrollbar{ display: none; } 可以对单独元素或者className的元素生效,例 .content::-webkit-scrollbar{ display: none; } 或 main::-webkit-scrollbar{ display: none; } 滚动条的宽高 ::-webkit-scrollbar{ width: 3px; /*对垂直流动条有效*/ height: 3px; /*对水平流动条有效*/ } /*定义滚动条的轨道颜色、内阴影及圆角*/ ::-webkit-scrollbar-track{ -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3); background-color: #6d6d6d; opacity: 0.4; 滚动条透明度 } /*定义滑块颜色、内阴影及圆角*/ ::-webkit-scrollbar-thumb{ -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3); background: #6E7794; opacity: 0.7; border-radius: 2px; 滑块两端圆角 } 要注意的是CSS部分overflowY:hidden,滚动条隐藏的同时,滚动事件也是消失的。 如有错误或者更好的方式方法还望多指点,谢谢。