VMware安装虚拟机目录 一、VMware添加虚拟机二、虚拟机启动及配置三、IP地址、子网掩码、网关和域名 一、VMware添加虚拟机 在我们安装完VWware,下载好安装的操作系统的镜像文件后(这里我们是(centos7版本),可以开始安装了。
点击新建虚拟机
点击下一步
选择workstation 15.x,点击下一步
选择稍后安装操作系统,点击下一步
选择Linux和CentOS 7 64位,,点击下一步
输入虚拟机名称和选择虚拟机的位置,,点击下一步
配置处理器数量和内核数量,点击下一步
这里根据本机电脑内存配置
选择使用网络地址切换(NAF),点击下一步
选择LSI,Logic,点击下一步
选择SCSI(S),点击下一步
选择创建新虚拟磁盘,点击下一步
输入磁盘的大小,选择“将虚拟磁盘存储为单个文件”,点击下一步
这里确定下文件名,点击下一步
选择自定义硬件
这里声卡和打印机我们不需要,可以选择完之后移除
这里更换到镜像文件(CentOS 7)的地址,点击关闭
点击完成,这里创建成功
二、虚拟机启动及配置 点击开启虚拟机
加载完之后选择语言,点击Continue
选择DATE&TIME进行设着
选择ASIA和shanghai,点击左上角的done
选择NETWORK & HOST TIME
开启之后,点击done
开始安装
设置虚拟机密码
配置用户
如下图进行虚拟机登录,账号root,密码root
设置主机别名
# 设置主机别名,sole替换成你需要设置的名称 hostnamectl set-hostname sole 查看防火墙,如下图,此时防火墙是开启状态
# 查看防火墙状态 systemctl status firewalld 关闭和禁用防火墙
# 关闭防火墙状态 systemctl stop firewalld # 禁用防火墙 systemctl disable firewalld 下面进行全局设置
# 编辑此文件 vi /etc/sysconfig/network-scripts/ifcfg-ens33 把"全部删除
1、使用scanf在VS2019出现错误,请在头部添加如下语言:
#define _CRT_SECURE_NO_WARNINGS
此时错误消失。
2、使用strlen,运行报错,找不到strlen标识符,请在头部添加如下语言:
#include<string.h>
3、使用Sleep,运行报错,找不到Sleep标识符,请在头部添加如下语言:
#include<windows.h>
4、strcmp使用在比较字符串输入是否一致时,举个例子:
if(strcmp(password,"你真棒“)==0)
做字符串的判断语句。strcmp的头文件是在string.h里
5、tolower,toupper使用头文件 ,#include<ctype.h>
目的是转换大小写
6、malloc 使用头文件,#include<stdlib.h>
7、使用sqrt,头文件使用 math.h
一个直播时发起了抢红包活动,分别有:9、666、188、520、99999五个红包。 请模拟粉丝来抽奖,按照先来先得,随机抽取,抽完即止,注意:一个红包只能被抽一次,先抽或后抽哪一个红包是随机的,示例如下(不一定是下面的顺序):
public class Test { public static void main(String[] args) { int[] pakege = {9, 666, 188, 520, 99999}; //方法一:将抽中的红包换为0,判断是否为0 Scanner sc = new Scanner(System.in); Random r = new Random(); for (int i = 0; i < pakege.length; i++) { System.out.println("请随意输入:"); sc.next(); while (true) { int i1 = r.nextInt(pakege.length); if (pakege[i1] != 0){ System.out.println("红包金额为:" + pakege[i1]); pakege[i1] = 0; break; } } } System.out.println("活动结束~"); } }
1、概念 log4j是apache实现的一个开源日志组件logback同样是由log4j的作者设计完成的,拥有更好的特性,用来取代log4j的一个日志框架,是slf4j的原生实现Log4j2是log4j 1.x和logback的改进版,据说采用了一些新技术(无锁异步、等等),使得日志的吞吐量、性能比log4j 1.x提高10倍,并解决了一些死锁的bug,而且配置更加简单灵活slf4j:日志门面,服务于各种各样的日志系,是对所有日志框架制定的一种规范、标准、接口,并不是一个框架的具体的实现,因为接口并不能独立使用,需要和具体的日志框架实现配合使用(如log4j、logback),使用接口的好处是当项目需要更换日志框架的时候,只需要更换jar和配置,不需要更改相关java代码 2、使用条件 如果你开发的是类库或者嵌入式组件,那么就应该考虑采用SLF4J,因为不可能影响最终用户选择哪种日志系统。在另一方面,如果是一个简单或者独立的应用,确定只有一种日志系统,那么就没有使用SLF4J的必要。假设你打算将你使用log4j的产品卖给要求使用logback的用户时,面对成千上万的log4j调用的修改,相信这绝对不是一件轻松的事情。但是如果开始便使用SLF4J,那么这种转换将是非常轻松的事情。
说白了,slf4j和common-logging一个意思,就是简单的日志门面,方便我们在不动代码的前提下随意切换我们的日志框架。在部署的时候,选择不同的日志系统包,就可自动转换到不同的日志系统上。
比如:选择JDK自带的日志系统,则只需要将slf4j-api-1.5.10.jar和slf4j-jdk14-1.5.10.jar放置到classpath中即可,如果中途无法忍受JDK自带的日志系统了,想换成log4j的日志系统,仅需要用slf4j-log4j12-1.5.10.jar替换slf4j-jdk14-1.5.10.jar即可。(当然也需要log4j的jar及配置文件)。当然如果这个时候觉得log4j的性能不是太好,出于性能考虑想换成logback的日志系统的话,也只是需要将logback的core包和classic包替换原来的log4j包就OK(当然也需要logback的配置文件)。
结合各日志实现包使用时提供的jar包情况为:
SLF4J和logback结合使用时需要提供的jar:slf4j-api.jar,logback-classic.jar,logback-core.jarSLF4J和log4j结合使用时需要提供的jar:slf4j-api.jar,slf4j-log412.jar,log4j.jarSLF4J和JDK中java.util.logging结合使用时需要提供的jar:slf4j-api.jar,slf4j-jdk14.jarSLF4J和simple(SLF4J本身提供的一个接口的简单实现)结合使用时需要提供的jar:slf4j-api.jar,slf4j-simple.jar 注意,以上slf4j和各日志实现包结合使用时最好只使用一种结合,不然的话会提示重复绑定日志,并且会导致日志无法输出。
3、依赖pom.xml log4j2默认会在classpath目录下寻找log4j2.xml、log4j.json、log4j.jsn等名称的文件,如果都没有找到,则会按默认配置输出,也就是输出到控制台,也可以对配置文件自定义位置 国外的服务器下载速度感人,一般都是用公司内部地址或切换到国内。 修改maven安装目录下中的conf文件夹下的setting.xml文件内容,在<mirrors>节点下新增
<mirror> <id>alimaven</id> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <mirrorOf>central</mirrorOf> </mirror> 4、SLF4J+log4j Logback默认配置的步骤:
1). 尝试在 classpath下查找文件logback-test.xml;
2). 如果文件不存在,则查找文件logback.xml;
3). 如果两个文件都不存在,logback用BasicConfigurator自动对自己进行配置,这会导致记录输出到控制台。
4.1.spring项目 本项目是基于spring项目集成logback日志
pom.xml
<!-- slf4j依赖 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.12</version> </dependency> <!-- slf4j自带的简单日志 --> <!-- log4j依赖 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.12</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> 4.2.Springboot项目 springboot项目,直接引入spring-boot-starter-web依赖即可,因为spring-boot-starter-web包含了spring-boot-starter。
而spring-boot-starter包含了spring-boot-starter-logging,所以我们只需要引入 web 组件即可。
1)引入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> 2)添加配置在application.yml
1 需求描述 最近工作需要从PDF文档中按照章节解析出对应的文本和图片(后续可能还会有表格),经过调研,找到了一个功能强大的解析工具MuPDF,对应的Python包是PyMuPDF。本篇博客记录使用它来实现具体功能。
官方文档:https://pymupdf.readthedocs.io/en/latest/index.html
2 利用书签中标题划分章节 在PDF中,点击书签或者目录页中具体一个标题时,文档页面会跳转到对应的章节,“跳转”的实现说明了其背后有一套机制(交叉引用),记录了各级标题和正文页面的对应关系。
PyMuPDF解析书签中各层级标题的接口为Document.get_toc(),该接口可以返回书签的层级、名称、点击它跳转到的页码及具体到目标页的哪个位置。
接口介绍
get_toc(simple=True/False) # 参数simple=True时,返回简单版本的各级目录,包括[标题层级, 标题名称,跳转到的页码],例如: [ 2, // 第二级 '旅行规划', // 名称 9, // 对应正文的第9页(该字段index从1开始) ] # 参数simple=False时,在跳转到的页码基础上,增加了'to'指向跳转页具体的坐标点(x, y) [2, '用户手册介绍 ', 9, {'kind': 1, 'xref': 3112, 'page': 8, 'to': Point(43.937, 29.877015), 'zoom': 0.0, 'collapse': False }] 详细文档
利用对书签的解析,获取到了:
(1)文档的层级关系: 包含多少第一级大标题、每个第一级标题下又有多少二级标题,以此类推可以获取完整的文档结构;
(2)每一级标题在正文中的页面范围,例如从第3页(43,40)到第5页的(253, 400)。
因此可以实现按照章节的拆分。
3 基于章节的文本解析 划分章节后,每一章节在正文中的位置由:起始页面、起始页面的坐标、结束页面、结束页面坐标描述,例如,start_page = 5, (start_x = 43, start_y = 36),end_page = 8, (end_x = 134, end_y=238)。
一.错误说明,npm本身下载就慢,有可能是网络的问题。
二.解决方案,把npm设置成淘宝镜像后,再重新npm install
npm config set registry https://registry.npm.taobao.org 三.还是不行,还会出现同样的问题,那接下来先清理一下npm缓存
npm cache clean -f 四.接着使用这个命令安装最新稳定版本的Node helper
npm install -g n --force 五.再重新 npm install
六.再不行,把npm 代理再改成cnpm
设置cnpm
$ npm install -g cnpm --registry=https://registry.npm.taobao.org 检查是否设置成功
cnpm -v 七.然后使用cnpm install 我的就解决了 总结 1.一般使用npm install报错的情况,大多数是网络不好,导致下载超时的情况。
2.如果真出现这种情况,解决办法就要简单粗暴一点。
3.办法,npm install 下载超时,就使用cnpm install ,cnpm 下载再超时,就使用yarn install
总有一种是成功的.如果再不成功,那就该检查网络了。
4.yarn怎么弄,百度一下就有了。
在升级tensorflow到2.10.1过程中,出现keras导入时出错问题,在网上进行了几个小时的搜索,没有找到好的解决方案。大体的解决思路是tensorflow与keras的版本不兼容。实际问题解决后,确实是这个原因。在网上查找的tensorflow对应的版本都比较低,这里可以使用的版本是:tensorflow为2.10.1,keras的版本为2.10.0。先安装keras, 再安装tensorflow。
pip install keras=2.10.0 pip install tensorflow==2.10.1 安装的结果:
Installing collected packages: tensorflow-estimator, tensorboard-data-server, google-auth-oauthlib, tensorboard, tensorflow Attempting uninstall: tensorflow-estimator WARNING: Ignoring invalid distribution -rotobuf (c:\users\he\.conda\envs\tf2\lib\site-packages) Found existing installation: tensorflow-estimator 2.11.0 Uninstalling tensorflow-estimator-2.11.0: Successfully uninstalled tensorflow-estimator-2.11.0 Attempting uninstall: tensorboard-data-server Found existing installation: tensorboard-data-server 0.7.0 Uninstalling tensorboard-data-server-0.7.0: Successfully uninstalled tensorboard-data-server-0.7.0 Attempting uninstall: google-auth-oauthlib Found existing installation: google-auth-oauthlib 1.0.0 Uninstalling google-auth-oauthlib-1.0.0: Successfully uninstalled google-auth-oauthlib-1.0.0 Attempting uninstall: tensorboard Found existing installation: tensorboard 2.
1、初始化时,数据库连接池工具类,创建连接池时,连接池由连接代理类执行SQL
com.zaxxer.hikari.pool.HikariProxyConnection#delegate
实属delegate是真实连接实体类,当真实执行sql时,再从连接池中获取连接实体类
com.zaxxer.hikari.util.DriverDataSource#getConnection
创建连接的Driver为配置的:
spring.datasource.driver-class-name=org.apache.shardingsphere.driver.ShardingSphereDriver
2、连接池创建
com.zaxxer.hikari.HikariDataSource.#getConnection()
com.zaxxer.hikari.pool.HikariPool#HikariPool
com.zaxxer.hikari.pool.PoolEntry
创建连接实体 final PoolEntry poolEntry = createPoolEntry();
return new PoolEntry(newConnection(), this, isReadOnly, isAutoCommit);
连接实体创建连接
3、数据库连接实体创建
org.apache.shardingsphere.driver.jdbc.core.driver.DriverDataSourceCache#createDataSource
从这里开始一直往下跟
org.apache.shardingsphere.driver.jdbc.core.datasource.ShardingSphereDataSource#getConnection
在这个类创建链接 DriverStateContext.getConnection(databaseName, contextManager, jdbcContext);
创建方式通过SPI 加载DriverState.class实现类
org.apache.shardingsphere.driver.state#DriverStateContext
4、执行sql拦截
connection.prepareStatement(sql);
connection是连接池,每个连接封装了代理类
com.zaxxer.hikari.pool.HikariProxyConnection#prepareStatement
由代理连接真实执行
com.zaxxer.hikari.pool.ProxyConnection#prepareStatement
真实连接类
org.apache.shardingsphere.driver.jdbc.core.connection.ShardingSphereConnection#prepareStatement
3、ShardingSpherePreparedStatement构造方法初始化
org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSpherePreparedStatement
ShardingSpherePreparedStatement#execute
断点的基本使用 断点------------------------------------------ 注意:下面的红色往下的箭头,虽然说明了什么方法都可以进入,但也只是针对于java代码,非java代码通常不能进入,其他的调试自然也不能,比如没有重写的hashCode方法,他是有native修饰的,代表默认非java代码的使用接口(一般主要是用来在Java程序中调用c/c++的代码的,也有可能是其他语言的代码,即默认只有不是java代码的方法,但调用是可以的,所以我们可以获得地址信息),即不重写,自然就会到非java代码里去,而重写,自然就是使用我们自己的了(这是重写的作用),即可以调试,所以如果不重写,自然不能调试,也就直接会到下一段代码了(下一行) 跳出方法,会跳出调用者的方法,直到跳出主线程,如main方法,上述的线程结束,是主线程结束 跳出后面的,是跳出窗口,跳出时,到当前方法位置,而跳出方法是,跳出方法的下一个位置 但有些是当前位置,如有些系统方法,但是不可以再次进入了,而跳出窗口可以继续进入 再后面的就是跳到下一个断点,按照行数来决定先后,若没有,则结束Debug模式 当然可以在Debug的时候,自己添加一个断点,那么也会到该断点,但是要添加到后面 再后面的就是计算器,当你复制一行代码时,其中可以有变量(前提一般只能是执行过的,否则会有错误提示,没有变量可以不用操作执行过的),如int a = 1+ 2; a是一个变量,那么就将这行代码复制进去,会帮你计算出结果,主要用来计算方法返回值的运算 对于左边的,最上面是重新Debug,而下面一个就类似于跳到下一个断点 若是服务器的操作(可能不同,具体自己测试,即不是完全相同操作的Debug),在没有下一个断点时,则等待下一个调试,否则跳转到下一个断点,即不会退出Debug模式(因为他并没有真的结束运行整体程序的,因为多线程关系) 单纯的执行,则会退出,即对于跳到下一个断点的退出,在服务器里基本没有明显关联 但是其他的下一个的操作等等退出,基本也都不会退出,与跳转到下一个断点基本一样,基本是这样 但这里是按照普通的执行来进行说明的,而不是服务器,所以这里看看即可 再下面红色正方形,就是直接结束Debug模式 再下面就是断点的操作,可以看到断点的位置也可以删除,再下面就是让你的断点都失效 让你不可进行跳转了,只可以一步一步执行了,再添加断点也是失效的 注意:在点击下一步时,若你的方法里面有断点,那么他不会直接到下一行,而是进入该方法的断点位置 然后在该方法里进行操作了,而且跳断点时,必须程序里面的断点 如main方法里,没有fa方法,但fa方法里有断点,那么跳不过去,若main方法有fa方法,那么就可以跳过去 之所以是这样,是因为断点是程序之间的断点,是需要联系的,无联系,不可操作断点 最好对与代码来说:在写代码,之所以用方法,除了可以看起来不那么乱外,更重要的是分工,好维护 但要好维护的缺点是,由于方法是在没创建对象时,不可以用其他类的方法(静态除外,但是静态的都会占名) 那么通常都要传递需要的参数,在方法里,但这样的参数,最好给方法对象的构造方法传递,因为有可能有很多需要该参数的 在使用对象流时,于其他流不同,读取的文件,必须写入对象的信息,因为需要版本号,若没有,则报错 该版本号,不写的话,会自动根据你的类的信息来添加,这是底层的实现
目录 1.传统计算器写法2.函数指针数组实现计算器2.1函数指针数组2.2计算器 1.传统计算器写法 传统计算器的写法需要在主函数里对逐个函数实现和调用,可以看到代码过于冗长,有没有一种更加简短的代码来实现呢,答案是肯定的
#include<stdio.h> int add(int x, int y) { return x + y; } int sub(int x, int y) { return x - y; } int mul(int x, int y) { return x * y; } int div(int x, int y) { return x / y; } int main() { int x, y = 0; int ret = 0; int input = 1; do { printf("************************\n"); printf(" 请输入你将要进行的运算:\n"
<el-button type="danger" @click="handleDownLoad('https://picsum.photos/500/500', '图片名称')">下载</el-button> // 下载图片03 const download = (href, name) => { let eleLink = document.createElement("a"); eleLink.download = name; eleLink.href = href; eleLink.click(); eleLink.remove(); }; // 下载图片02 const downloadByBlob = (url, name) => { let image = new Image(); image.setAttribute("crossOrigin", "anonymous"); image.src = url; image.onload = () => { let canvas = document.createElement("canvas"); canvas.width = image.width; canvas.height = image.height; let ctx = canvas.getContext("2d"); ctx.drawImage(image, 0, 0, image.width, image.height); canvas.
以下也是借鉴大佬的代码, 这里只是整理出来, 方便以后自己使用
大佬的帖子 : vue3中使用qrcodejs2-fix插件生成二维码_G_ing的博客-CSDN博客
其他人的帖子不是报错就是繁琐胡扯, 有人连canvas都结合起来用, 还封装成组件, 写的乱七八糟, 明明这么简单几句代码就实现的
所以看到这个帖子, 就别去搜索其他人的了, 保证管用
使用的依赖 qrcodejs2-fix
npm install qrcodejs2-fix DOM处
<div id="qrCodeBox"></div> 页面中引入
import { onMounted, ref, reactive, nextTick } from 'vue'; // 页面中引入 import QRCode from 'qrcodejs2-fix'; onMounted(() => { // 生成二维码 getQrCode(); }); // 生成方法 const getQrCode = () => { // DOM 都加载完毕再执行 nextTick(() => { document.getElementById('qrCodeBox').innerHTML = ''; new QRCode(document.getElementById('qrCodeBox'), { text: '呱呱', // 扫码后显示的内容, 如果页面链接, 扫码后会直接跳转到链接 width: 100, //二维码宽 height: 100, //二维码高 }); }); }; 如果扫码内容是需要接口返回的, 建议这样写
所要展开项的name标识符与v-model绑定值匹配即可默认展开。
1. 案例
<el-collapse v-model="activeNames"> <el-collapse-item name="0" title='段落1'>那一年,花开得不是最好,可是还好,我遇到你; </el-collapse-item> <el-collapse-item name="1" title='段落2'>那一年,花开得好极了,好像专是为了你; </el-collapse-item> <el-collapse-item name="2" title='段落3'>那一年,花开得很迟,还好,有你。 </el-collapse-item> </el-collapse> data(){ return{ activeNames:[0, 1, 2] // 展开指定项 activeNames:[] // 全部关闭 } } 实现效果:
Go的简单性、可读性、生产力 标识符: 很简洁、具有描述性、可预测的【从名字推断出使用方式】
命名的时候需要考虑上下文的!例如我们方法参数中名字就能很好的代表!
变量或常量的名称应描述其目的,而不是内容的类型!而注解应该描述内容的,如
var userMap map[string]*User 这个声明有什么好处? 我们可以看到它是一个 map,它与 *User 类型有关。 但是 usersMap 是一个 map,而 Go 语言是一种静态类型的语言,如果没有定义变量,不会让我们意外地使用到它,因此 Map 后缀是多余的。
建议是避免使用任何类似变量类型的后缀。
贴士:
不要让包名窃取好的变量名。
导入标识符的名称包括其包名称。 例如,context 包中的 Context 类型将被称为 context.Context。 这使得无法将 context 用作包中的变量或类型。
func WriteLog(context context.Context, message string) 上面的栗子将会编译出错。 这就是为什么 context.Context 类型的通常的本地声明是 ctx,例如:
func WriteLog(ctx context.Context, message string) 一致的声明样式:声明变量但没有初始化时,请使用 var。 当声明变量稍后将在函数中初始化时,请使用 var 关键字。
在没有初始化的情况下声明变量时,请使用 var 语法。
声明并初始化变量时,请使用 :=。
贴士:
使复杂的声明显而易见。
当事情变得复杂时,它看起来就会很复杂。例如
var length uint32 = 0x80 这里 length 可能要与特定数字类型的库一起使用,并且 length 明确选择为 uint32 类型而不是短声明形式:
需求:后端返回给前端的市下载地址URL,前端进行下载对应文件
downLoad(){ const link = document.createElement('a') //_blank表示在新窗口打开链接 link.target = '_blank' link.href =process.env.VUE_APP_BASE_API+this.form.POD link.setAttribute('download', '文件名字' + Date.now() + '.PDF') // 下载文件的名称及文件类型后缀 document.body.appendChild(link) link.click() document.body.removeChild(link) // 下载完成移除元素 this.$modal.msgSuccess("下载成功"); this.open=false }, 其中this.form.POD是后端返回的下载地址URL
1.声明
存放的是OC对象,int等非对象不能存放
NSArray *arr=@[@"jack",@"rose",@"mary"];
NSArray *arr=[NSArray arrayWithObjects:@"jack",@"rose",@"mary",nil];
2.取值
NSString *str=arr[0];
NSString *str1=[arr objectAtIndex:1];
NSUInteger size=arr.count; 或[arr count]
3.是否包含元素
BOOL res=[arr containsObject:@"lilei"];
4.查找元素索引
NSUInteger index=[arr indexOfObject:@"rose"];
if(index==NSNotFound)
{
NSLog(@"未找到rose");
}else
{
NSLog(@"找到rose了");
} 5.数组遍历
for循环
NSUInteger size=arr.count;
for(int i=0;i<size;i++)
{
NSLog(@"%@",arr[i]);
NSLog(@"%@",[arr objectAtIndex:i]);
}
for in循环,相当于java foreach
比如遍历存放NSString的NSArray
for(NSString *str in arr)
{
NSLog(@"%@",str);
}
当数组中类似不一致,使用id来遍历
for(id *id in arr)
{
NSLog(@"%@",id);
}
通过代码块来遍历
[arr enumerateObjectsUsingBlock:^(id _Nonnull obj,NSUInteger idx,BOOL * _Nonnull stop){
动态挂载组件 // obj={ // class:'弹窗最外面的名称', // title:'弹窗标题', // components:'传入的组件,需要先使用 import test from './components/test.vue' 引入,然后传递 test(components和content只能有一个,并且components里面的关闭和取消按钮需要自己写)' // propsData:组件的传递的参数(components传入的组件哈) // content:'弹窗内容(可以文字、html,也可以展示代码需要`<div></div>`包裹)', // width:'弹窗宽度', // cancelText:'取消按钮的文案,没有传不显示按钮', // confirmText:'确定按钮的文案,没有传不显示按钮', // style:'content内容的基础样式', // showClose:'是否显示弹窗右上角的关闭按钮', // twiceTitle:'确定时的二次确认文字,不传不会二次确定' // } Vue.prototype.$confirmDialog = async function(obj = null) { if (!obj) return const idName = 'confirmDialog_new_custom_' + new Date().getTime() + '_' + parseInt(Math.random() * 1000) const confirmDialog = (await import('@/components/dialog/confirmDialog.vue')).default const ConfirmDialogCom = Vue.component('confirmDialog', confirmDialog)// 创建组件 // 给当前组件挂载父级页面的参数(即 main.
实现代码:
import { Workbook } from "exceljs" const { nodejs } = window const buffer = await nodejs.readPublicFile('excel/xxxxxx表.xlsx') const workbook = new Workbook() await workbook.xlsx.load(buffer) const dataSheet = workbook.getWorksheet('sheetName') // 'sheetName'为左下角的sheet名称 // 获取特定id的数据 const getSiteOriginalData = (id: string) => { const data: Array<(string | number)[]> = [] dataSheet.eachRow(row => { if (row.getCell(1).text !== id) return const values = (Array.isArray(row.values) ? row.values : []).filter(value => value !== undefined) as (string | number)[] data.
理解占用多少字节的关键:明确字符(CHAR)和字节(BYTE)的关系
一个汉字在不同字符编码下所占字节不同:
UTF-8:一个汉字 = 3个字节-1个字符,一个英文 = 1个字节-1个字符
GBK: 一个汉字 = 2个字节-1个字符,一个英文 = 1个字节-1个字符
Oracle
VARCHAR2(100 CHAR)表示100个字符:
UTF8一个中文占1个字符,所以能存100个汉字GBK一个中文占用1个字节,所以能存100个汉字 VARCHAR2(100) 、VARCHAR2(100 BYTE)表示100个字节:
UTF8一个中文占3个字节,所以能存33个汉字;GBK一个中文占用2个字节,所以能存50个汉字 // oracle查询数据库编码格式。 SELECT * FROM v$nls_parameters WHERE PARAMETER='NLS_CHARACTERSET'; select userenv('language') from dual; // 查看指定字符占用多少长度 select lengthb('默辨xxx') from dual; MySQL
4.1 及之前早期版本:
VARCHAR(100)表示100个字节。
UTF8一个中文占3个字节,所以能存33个汉字;GBK一个中文占用2个字节,所以能存50个汉字 5.0版本:
VARCHAR(100)表示100个字符。
UTF8一个中文占1个字符,所以能存100个汉字GBK一个中文占用1个字符,所以能存100个汉字
编译与翻译 翻译程序 翻译时不产生新的独立目标程序解释程序和源程序参与程序的运行 编译程序 编译时产生新的独立目标程序编译程序和源程序不参与程序的运行 程序设计语言的成分 顺序、选择、循环结构 传值与传地址 略 编译、解释与翻译阶段 共同点: 编译和解释都不可省略 词法分析、语法分析、语义分析且顺序不可交换
编译器特点 词法分析、语法分析、语义分析、中间代码生成、代码优化、目标代码生成中间代码生成 和 代码优化不是必要,可省略 解释器特点 词法分析、语法分析、语义分析
编译过程 1.词法分析 输入:源程序
输出:记号流
分析字符、符号是否符合规定
2.语法分析 输入:记号流
输出:语法树
分析程序中的句子,结构是否符合结构。能分析出所有的语法错误
3.语义分析 不能分析出所有的语义错误
分析类型是否匹配
不能发现动态语义错误,只能发现静态语义错误
4.目标代码生成 目标代码生成阶段的工作与具体的机器密切相关
寄存器的分配处于目标代码生成阶段
5.中间代码生成 后缀式、三地址码、三元式、四元式和树(图)中间代码与机器无关 正规式 学会即可
有限自动机 最终都要回到终态
Σ表示可以跳过此阶段
目录
基础构造函数 重写
钻石继承
super函数
基础构造函数 命名为_init_,在实例化对象之前会自动执行该函数
构造函数方便我们在实例化对象的时候实现个性化定制 class A(): def __init__(self,x,y): self.x = x self.y = y def add(self): return self.x+self.y class B(A): #B继承A pass b = B(1,2) #自动调用A的初始化方法 result= b.add() #调用父类A的add方法 print(result) #结果为3 重写 子类可以不重写__init__,实例化子类时,会自动调用超类中已定义的__init__
如果重写了__init__,实例化子类时,则不会隐式的再去调用超类中已定义的__init__
class A(): def __init__(self,x,y): self.x = x self.y = y def add(self): return self.x+self.y class B(A): def add(self): #重写父类A中的add方法 return self.x+self.y+1 b = B(1,2) result= b.add() #将会调用B中的add方法 print(result) #结果是4 钻石继承 钻石继承是指两个类同时继承了一个父类,并且这两个类又同时被一个子类继承
1. 创建项目
Project slug是访问地址的后缀,跟前边的ProjectUrl拼在一起,就是此项目的首页地址;
Visibility Level选择默认私有即可,选择内部或者公开,就会暴露代码。
勾选Readme选项,这样项目内默认会带一个Readme文件。
2. 邀请成员
Maintainer权限可以邀请成员,直接在“GitLab成员或电子邮件地址”栏搜索即可,刚注册的账号可能搜不到,需要等几个小时。然后不要忘了指定角色权限。
3. 邀请群组
邀请成员旁边就是邀请群组。同样,刚刚创建的群组可能搜不到,需要等待。
4. 创建分支
点击左侧菜单,仓库-->分支,点击右侧新建分支,即可。
5. 解除主分支保护
默认情况下,master分支是被保护状态的,只有Maintainer权限才能修改。如果只是想简单使用一下,单分支就够用的话,可以解除主分支保护。
项目首页-->用户设置-->仓库-->展开Protected Branches-->找到master分支点击Unprotect
1 当返回体中的data同样为json格式, 此时需要拿到data中的某个数据, 如:
{ 'data': '{"seq": "s2943020914552138", "price": "0.02", "discount": "0.00", "result": true}', 'message': '', 'success': True, 'requesttoken': '', 'sign': '' } 2 需要在Test中写入代码
// 获取response的数据 var jsonData = JSON.parse(responseBody) // 获取data var jdata = jsonData.data // 获取data中的seq数据, 并将其设置为全局变量 pm.globals.set("seq",JSON.parse(jdata).seq)
CHI 2023 的一个加长摘要 相关网址简单记录一下对里面感兴趣的内容一些简单的想法 相关网址 URL:A Generative Framework for Designing Interactions to Overcome the Gaps between Humans and Imperfect AIs Instead of Improving the Accuracy of the AIs
简单记录一下对里面感兴趣的内容 AAAI '20:在STOP标志上贴上蛾状的贴纸会使自动驾驶汽车误将其识别为限速80的标牌。
2000年的一篇IEEE Transactions on Systems, Man, and Cybernetics - Part A: Systems and Humans 提出了一个自动化交互框架:Parasuraman’s framework of automation
可以看出,从等级1到等级10,计算机提供的决策权限越来越高。作者使用的用于教学的系统中,采用信息获取和信息分析方面保持了10级,而在决策和行动选择以及行动实施方面表现出1级。
一些简单的想法 对标牌加贴纸就可以让自动驾驶的视觉产生误判,这种视觉欺骗对以深度学习为基础的纯视觉导航+追踪任务的无人机是否会产生影响呢?在无人机相关的人机交互中,Parasuraman’s 的自动化模型是否能套用进来,或者是否能够进行改进?对于不同的情况,人产生的影响的比重会变化,无人机可以根据条件自主选择是否接受操作人的指令?但是这样又会有新的问题,如果环境中存在信息欺骗,是否无人机会脱离控制?这种情况需要设置某些强制手动的指令?
1. 打开设置
2.选择首选项Preferences
3. 下滑选择本地化选项Localization,设置简体中文,然后保存更改save changes。刷新网页即可。
可以直接去github github.com/1023byte/3Dmap
前言 threejs小练习,从头实现如何加载地理数据,并将其映射到三维场景中的对象上。
获取数据 在开始绘制图形前,需要一份包含地理信息数据,我们可以从阿里云提供的小工具获取datav.aliyun.com/portal/school/atlas/area_selector
在范围选择器中,可以选择整个或者各个省份的地理信息数据。
生成图形 获取数据后,先分析一下JSON的结构
image.png properties 中包含了名字、中心、质心等信息, geometry.coordinates 则是地理的坐标点,我们需要做的是将这些点连成线。
THREE.Shpae const createMap = (data) => { const map = new THREE.Object3D(); data.features.forEach((feature) => { const unit = new THREE.Object3D(); const { coordinates, type } = feature.geometry; coordinates.forEach((coordinate) => { if (type === "MultiPolygon") coordinate.forEach((item) => fn(item)); if (type === "Polygon") fn(coordinate); function fn(coordinate) { const mesh = createMesh(coordinate); unit.add(mesh); } }); map.add(unit); }); return map; }; 这里需要注意在geometry中的type分为MultiPolygon和Polygon,需要分别处理,不然会造成个别区域缺失,二者区别是MultiPolygon的坐标多一层嵌套数据,所以这里多做一次遍历。
字符串 字符类型(char)是Java中的基本数据类型之一,字符是用单引号引住的单个符号。字符串(String)是用双引号引住的任意个字符,字符串其实就是字符组成的序列。字符串在开发中可以用来表示标题,名称,地址等。
1.字符串对象与字面量 String 变量名 = "初始值"; String 变量名 = new String("初始值"); 第一种形式使用双引号引住的字符串叫做字面量
第二种使用new运算符声明的字符串叫做字符串对象。【第二种形式并不常用,推荐使用第一种形式。】
2.API 字符串内部使用byte数组(JDK8之前是char数组)来保存字符串的内容,数组中的每一位存一个字符,byte数组的长度也就是字符串的长度。
返回类型方法名称作用booleanequals(String)比较两个字符串是否相等booleanequalsIgnoreCase(String)忽略大小写比较两个字符串是否相等intlength()获取字符串的长度charcharAt(int)获取字符串中的一个字符intindexOf(String)判断传入字符串在原字符串中第一次出现的位置intlastIndexOf(String)判断传入字符串在原字符串中最后一次出现的位置booleanstartsWith(String)判断原字符串是否以传入字符串开头booleanendsWith(String)判断原字符串是否以传入字符串结尾intcompareTo(String)判断两个字符串的大小StringtoLowerCase()获取小写字符串StringtoUpperCase()获取大写字符串Stringsubstring(int)截取字符串,从传入参数位置开始截取到末尾Stringsubstring(int, int)截取字符串,从参数1位置开始截取到参数2位置Stringtrim()去掉字符串首尾的空格String[]split(String)将原字符串按照传入参数分割为字符串数组Stringreplace(String, String)将字符串中指定的内容替换成另外的内容 2.1字符串连接 字符串可以进行加法运算,作用是将两个字符串连接在一起,也可以将字符串与基本类型变量做加法运算,系统会先将基本类型转换为字符串型后进行连接操作。在Java中将两个字符串连接在一起可以使用加号连接,也可以使用 concat() 方法连接。
stringString str1="绿蚁新醅酒,"; String str2="红泥小火炉。"; System.out.println(str1.concat(str2));//绿蚁新醅酒,红泥小火炉。 2.2字符串比较 字符串也可以进行是否相等的比较,但不能直接使用 == 运算符,而是要使用equals() 方法进行比较。忽略大小写的比较 equalsIgnoreCase() 方法
在Java中,equals()和==都是用于比较两个对象的操作,但它们有着不同的含义和使用场景。
(1)==操作符用于比较两个对象的引用是否指向同一内存地址。如果两个对象的引用指向相同的内存地址,则它们是相等的。
(2)另一方面,equals()方法用于比较两个对象的值是否相等。默认情况下,equals()方法比较两个对象的引用是否相等,但可以通过重写该方法来实现自定义的相等比较逻辑。
(3)需要注意的是,对于基本类型的比较(如int、double等),==操作符比较的是它们的值,而不是引用
String str = "name"; String str2 = "name"; String str3 = "string"; System.out.println(str.equals(str2));//true System.out.println(str.equals(str3));//false 2.3字符串的长度 String类的 length() 方法可以获取字符串是由多少个字符构成的。
在数组中length属于数组的属性,而在字符串中length()是字符串的方法,注意进行区分
String str = "name"; System.out.println(str.length()); 2.4字符串查找 indexOf() 判断传入字符串在原字符串中第一次出现的位置lasetIndexOf() 判断传入字符串在原字符串中最后一次出现的位置startsWith() 判断原字符串中是否以传入字符串开头endsWith() 判断原字符串中是否以传入字符串结尾 public static void main(String[] args) { Scanner sc = new Scanner(System.
一、Anolis8.8与docker-ce 1、Anolis OS 8.8官方首页:龙蜥社区https://openanolis.cn/ 龙蜥操作系统(Anolis OS)是 OpenAnolis 龙蜥社区发行的开源 Linux 发行版,兼容主流 Linux 发行版操作习惯,支持多计算架构,提供稳定、高性能、安全、可靠的操作系统服务。当前 Anolis OS 提供 Anolis OS 7、Anolis OS 8 和 Anolis OS 23 三个主要版本。三个主要版本均集成 ANCK 内核版本(Anolis Cloud Kernel,Anolis 云内核),ANCK 是由社区 Cloud Kernel SIG 组基于上游 Kernel 研发,一款定制优化版的内核产品,在 Cloud Kernel 中实现了若干针对云基础设施和产品而优化的特性和改进功能,旨在提高云端和云下客户的使用体验。与其他 Linux 内核产品类似,Cloud Kernel 理论上可以运行于几乎所有常见的 Linux 发行版中。
龙蜥操作系统(Anolis OS)搭载了 RHCK 和 ANCK 两种不同版本的内核,性能和稳定性经过历年“双 11”历练,能为云上典型用户场景带来 40% 的综合性能提升,故障率降低 50%,兼容 CentOS 生态,提供平滑的 CentOS 迁移方案,并提供全栈国密能力。最新的长期支持版本 Anolis OS 8.6 已发布,更多龙蜥自研,支持 X86_64 、RISC-V、Arm64、LoongArch 架构,完善适配 Intel、飞腾、海光、兆芯、鲲鹏、龙芯等主流芯片。
2、docker官方首页:https://www.docker.com/ Docker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器。开发者在笔记本上编译测试通过的容器可以批量地在生产环境中部署,包括VMs(虚拟机)、 bare metal、OpenStack 集群和其他的基础应用平台。
SpringBoot 多数据源切换(超级简单)_springboot数据源切换_Tz.的博客-CSDN博客
springboot dynamic多数据源demo以及常见切换、事务问题_一片星空~的博客-CSDN博客
简介 Selenium是一款强而有力的前端应用测试工具,也非常适合搭配Python作为网络爬虫的工具;Selenium可以模拟使用者所有浏览器操作的动作,包括输入文本、点击按钮及拖拽进度条等。有鑑于新版的Selenium 4与旧版的语法有若干明显的差异,特别撰写本文来与朋友们釐清并分享。
安装 安装Selenium套件 pip install selenium
安裝WebDriver 可以去这裡下载WebDriver,注意要与你的Chrome浏览器版本相同。下载并解压缩后会得到一个chromedriver.exe的可执行档,建议将这个档案複製到你的Python项目资料夹下,可以避免路径的问题。
浏览网页 from selenium import webdriver from selenium.webdriver.chrome.service import Service service = Service('./chromedriver') # 设定chromedriver路径 driver = webdriver.Chrome(service = service) driver.get('https://www.baidu.com') # 浏览百度网站首页 print(driver.title) # 百度一下,你就知道 查找单一元素 """ <html> <body> <form id="loginForm"> <input name="username" type="text" /> <input name="password" type="password" /> <input name="continue" type="submit" value="Login" /> </form> </body> </html> """ login_form = driver.find_element(By.ID, 'loginForm') # 用ID查找 username = driver.find_element(By.NAME, 'username') # 用NAME查找 username = driver.
如何查询学生表中第一个出现的六年级学生的id呢?如果之前没这个需求,我们一般都会按照自己最熟悉的方式先去查找六年级所有的学生数据,然后获取第一条数据。虽然这种方式也可以获取到我们需要的数据,但是执行的SQL语句需要进行全表扫描后获取所有满足的记录数返回。因为我们只需要第一条数据,所以可以通过拼接limit=1来获取该条数据,减少数据库扫描。
可以在查询条件最后拼接limit,限制查询的记录数。
LambdaQueryWrapper<Student> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(Student::getLevel,6).last("limit 1"); Student student = getOne(queryWrapper);
一、硬件说明 1、引脚分配图 文章来源地址https://www.yii666.com/blog/326636.html文章来源地址:https://www.yii666.com/blog/326636.html
2、常用引脚说明 模块输入电源
引脚名描述VBAT_BB模块基带电源(Vnom = 3.8 V)VBAT_RF模块射频电源(Vnom = 3.8 V)GND接地引脚 模块输出电源
引脚名描述VDD_EXT外部电路 1.8 V 供电(Vnom = 1.8 V) 开/关机
引脚名描述RESET_N模块复位(低电平有效,1.8 V 电压域,不用则悬空。)PWRKEY模块开/关机 (VBAT 电压域) SIM 接口
引脚名描述USIM_VDD(U)SIM 供电电源(模块自动识别 1.8 V或 3.0 V (U)SIM 卡。)USIM_DATA(U)SIM 数据USIM_CLK(U)SIM 时钟USIM_RST(U)SIM 复位 主串口
引脚名描述MAIN_TXD主串口发送(1.8 V 电压域)MAIN_RXD主串口接收(1.8 V 电压域) 天线接口
引脚名描述ANT_MAIN主天线接口(50 Ω 特性阻抗) 二、常用AT指令说明 1、AT 说明: 检测AT指令收发是否正常模组收到指令回复: AT OK 2、AT+CPIN? 说明: 查询SIM卡状态(是否插入SIM卡、锁定SIM卡、解锁SIM卡),返回 READY则表示模组正常模组收到指令回复: AT+CPIN? +CPIN: READY OK 3、AT+CREG? 说明: 查询当前网络注册状态,正常则回复 +CREG: 0,1模组收到指令回复: AT+CREG? +CREG: 0,1 OK 4、AT+CEREG?
目录
一、获取多线程的4种方式(Runnable/Callable/Thread/线程池)
二、相关细节
1、自定义线程池的相关参数
1.1 生产环境中如何配置corePoolSize和maximumPoolSize?
1.2 四种拒绝策略
2、为何使用线程池?使用线程池的好处?为何不用默认线程池?
2.1 为何用?(线程复用 / 控制最大并发数 / 管理线程)
2.2 用的好处?(降低资源消耗/提高响应速度/提高线程的可管理性)
2.3 线程池的底层原理?
三、线程不安全
1、线程不安全的ArrayList(Vector, Collections.synchronized(), JUC方法)
1.1 线程不安全的原因
1.2 解决办法
2、线程不安全的HashSet
2.1 线程不安全的原因
2.2 解决办法
3、线程不安全的HashMap
3.1 线程不安全的原因
3.2 解决办法
四、核心线程数、最大线程数、阻塞队列长度的计算
1、核心线程数
【常规-核心线程数的计算】
【max-核心线程数的计算】
【实际-核心线程数的计算】
2、最大线程数(我自己总结的)
3、阻塞队列
本文通过学习:周阳老师-尚硅谷Java大厂面试题第二季 总结的多线程相关的笔记
一、获取多线程的4种方式(Runnable/Callable/Thread/线程池) 实现Runnable接口实现Callable接口实例化Thread类使用线程池获取 Runnableclass MyThread implements Runnable {
@Override
public void run() {
System.out.println("Runnable");
}
}Callableclass MyThread2 implements Callable<Integer> {
@Override
public Integer call() throws Exception {
文章目录 多路复用器简介多路复用器的两个阶段Java中的多路复用器封装测试代码压测结果总结 本篇文章是BIO到NIO、多路复用器, 从理论到实践, 结合实际案例对比各自效率与特点(上)的下一篇, 如果没有看的小伙伴, 可以先看下, 不然可能会不连贯.
多路复用器简介 多路复用器是对于传统NIO的优化, 解决了传统NIO无法直接获取所有所有连接的状态, 需要挨个遍历所有连接查看是否准备就绪的问题, 这种方式会涉及到很多次系统调用, 用户态和内核态的切换,效率不高.
那多路复用器是怎样优化的呢?
首先要明白 多路的路是谁-------->其实就是每个IO连接
每个路有没有数据谁知道呢-------->内核知道, 那既然内核自己知道某一时刻有哪些连接是有连接的, 是不是我们直接调用对应功能方法即可, 所以这里就有个多路复用器, 你调用这个多路复用器, 它就会给你返回所有的路的IO状态.
这个就可以通过一次系统调用,获取所有连接的IO状态的结果集
然后程序自己对有状态的(准备好的)连接进行读写,这样才是高性能
这里注意,多说一句, 只要程序自己读写数据, 你的IO模型就是同步的
多路复用器的两个阶段 多路复用器有两个阶段, 或者说是内核的两类实现, 这两类实现的最终目的都是一样的, 就是帮你返回所有IO连接的IO状态(是否可读), 但是实现细节有些许差别, 可以理解为epoll是select poll的升级版.
这里还是再提示下, 以下的两种实现讲的操作系统中的实现, 并不是Java中的方法.
select poll
需要把所有IO连接存到一个集合中, 把这个集合传递拷贝给内核, 也就是调用select或者poll, 内核会把集合中准备就绪的连接给个特殊标识, 然后返回.
这样程序就可以直接知道哪些连接是有状态的, 从而直接进行读取数据
弊端:
假如有1w个连接, 每次都需要把这个1w个连接拷贝给内核, 这个拷贝就是损耗点, 每次需要重复拷贝数据给内核.
epoll
正是因为select, poll 有自身的弊端, 这才催生了epoll.
优化
以空间换时间, 开辟了内核空间, 缓存了应用程序的连接信息. 这样就不需要重复的拷贝数据.无损耗才是高性能.
实现步骤
1. 在一个linux机器上, 有很多的应用程序, 所以一个应用程序想要使用epoll的话, 首先需要在内核中 开辟空间------对应epoll_create系统调用
虚拟机是指行为方式类似于实际计算机的计算机文件。换言之,即在计算机内创建一台计算机。它像任何其他程序一样在窗口中运行,让最终用户在虚拟机上享受如在主机操作系统上的相同体验。虚拟机脱离系统其余部分进行了沙盒化,这意味着虚拟机中的软件不可转义或篡改计算机本身。这制造了一种理想的环境,可用于测试其他操作系统(包括 beta 版本)、访问感染病毒的数据、创建操作系统备份,以及在操作系统上运行原本不打算运行的软件或应用程序。
多个虚拟机可以在同一实体计算机上同时运行。对服务器而言,多个操作系统并排运行,并具有一个称为虚拟机监控程序的软件进行管理;而台式计算机通常使用一个操作系统在其程序窗口内运行其他操作系统。每个虚拟机都提供自己的虚拟硬件,包括 CPU、内存、硬盘、网络接口和其他设备。然后,虚拟硬件将映射到物理计算机的真实硬件上,这可减少物理硬件系统需求和伴随的相关维护成本以节省开销,还可降低功率和冷却需求。
虚拟机还是运行在你的主机系统里面的,所以安装出来的虚拟机系统是需要与你的主机硬件所共享的
虚拟机的软件有很多,目前功能强大且比较主流的虚拟机软件首选VMware
VMware是一个虚拟PC的软件,可以在现有的操作系统上虚拟出一个新的硬件环境,相当于模拟出一台新的PC,以此来实现在一台机器上真正同时运行两个独立的操作系统。
VMare的主要特点
①不需要分区或重新开机就能在同一台PC上使用两种以上的操作系统
②本机系统可以与虚拟机系统网络通信
③可以设定并且随时修改虚拟机操作系统的硬件环境,如内存配置、硬盘大小(注意:不能超过真实主机硬件上限)
④虚拟机快照可以保存操作系统当前状态,若后续Linux系统崩溃,可以使用快照恢复
VMware下载
1、从VM11开始就不再支持32位系统了,32位系统用户和XP系统用户请使用10.0.7版本;
2、从VM14开始,对硬件要求进一步提高,所以低配电脑用户请使用12.5.9版本;
3、关于VM14黑屏问题,这是 VMware tools 版本过低引起的
提供部分版本下载和序列号:
各版本序列号
10.x:1Z0G9-67285-FZG78-ZL3Q2-234JG
11.x:YG74R-86G1M-M8DLP-XEQNT-XAHW2
12.x:ZC3TK-63GE6-481JY-WWW5T-Z7ATA
14.x:AU108-FLF9P-H8EJZ-7XMQ9-XG0U8
15.x:FC7D0-D1YDL-M8DXZ-CYPZE-P2AY6
WRITE-BUG研发团队衷心希望【WRITE-BUG数字空间】可以给每位同学一个属于自己的秘密空间,同时祝愿大家在“公开圈子”世界里,遇见志同道合的伙伴们,因为我们与大家一样,都曾孤独前行着。
继承 Java类中只支持单继承,即一个类只能有一个直接父类。
类与类之间有三种关系,分别是“is a”,“use a”,“has a”,继承表达的是“is a”的关系,如Dog is a Pet,学生 is a 人,苹果 is a 水果等。
[访问修饰符] class 类名 extends 父类名{ } // 访问修饰符:public【项目任何地方都可以访问类】 缺省【当前包中】 // 访问修饰符: // public : 项目任何地方都可以访问 // protected : 同包下任意类可以访问【其他包子类也可以访问 static 】 // private : 只能自身访问 // package-access : 同包下任意类可以访问 java基本概念
子类可以继承父类的非私有属性和方法。子类可以使用父类的属性和方法,无需重新编写相同的代码。子类可以添加自己的属性和方法。子类可以增加父类中没有的属性和方法,从而增加代码的灵活性和可扩展性。子类的构造方法可以调用父类的构造方法。在子类的构造方法中使用super关键字可以调用父类的构造方法,从而初始化父类的属性。Object类是所有类的根类。每个类都是Object类的子类,因此可以使用Object类中定义的一些通用方法,如equals()、hashCode()、toString()等。Java中的类只支持单一继承,每个类只能有一个父类(直接父类)。子类可以成为其他类的父类,从而建立多级继承关系。但是,过多的继承可能会导致代码难以理解和维护 继承是java的三大特征之一
继承就是子类继承父类的特征和行为,来实现充实自身内容
格式:使用extends 关键字申明一个类是从另一个类继承而来
现有类称为父类、超类、基类,新类称为子类、扩展类
继承的作用:代码复用,增加软件的可扩展性
继承分为单继承、多继承,java中类只支持单继承,也就是一个类只能有一个直接父类
继承的应用
Java中继承是一种面向对象编程的核心概念,它可以让子类继承父类的属性和方法,并且还可以在此基础上进行扩展和重写,提高了代码的复用性和可维护性。
public class Pet { private String name; private int age; public String color; protected double weight; public Pet(){} public Pet(String name, int age, String color, double weight, String voice) { this.
面向对象基础 文章目录 面向对象基础1.面向对象的三大特征2.类3.创建对象4.对象在计算机中的执行原理5.对象的构造和初始化成员变量 6.类和对象的一些注意事项7.构造器8.this关键字9.static关键字使用区别 代码块static代码块对象初始化顺序静态成员与实例成员的区别对象数组 10.包封装类和类成员的访问控制封装在代码中的体现getter和setter方法的规则:成员变量和局部变量的区别getter和setter方法的规则:成员变量和局部变量的区别 1.面向对象的三大特征 封装继承多态 2.类 类的定义:具有相同的状态和相同的行为的一组对象的集合。
类是对象的模板,对象是类的具体实例。
组成 类有字段和方法两部分构成的,假如描述猫类,猫的属性包括“颜色”,“品种”。类的方法包括打印动物吃啥,打印动物在干啥。
面向对象设计的过程就是抽象的过程,也是设计类的过程,一般分为三步完成。
发现类,类定义了对象将会拥有的特性(字段)和行为(方法)。发现类的字段,对象所拥有的特性在类中的表示称为类的字段。发现类的方法,对象执行的操作称为类的方法。 类的定义
定义类就是定义了一个新的数据类型,这个数据类型就是类名。
Java的数据类型有基本数据类型和引用数据类型(类,接口,枚举,数组)
public class Cat{ public String color;//类的字段声明(属性) public String breed;//类的字段声明(属性) public void eat(){ System.out.println("猫猫正在吃鱼"); }//类的方法声明(行为) } 访问修饰符如public,private等是可选的,具体可以看后面的文章。class是声明类的关键字类名的命名规则使用帕斯卡命名法,类名首字母大写 类的字段 字段使用变量表示
访问修饰符 数据类型 字段名;//见上面的表示 访问修饰符是可选的。除了访问修饰符外,其他部分与定义变量相同。 3.创建对象 类是一类事物的集合和抽象,代表着这类事物共有的字段和行为。一个对象称为类的一个实例,是类一次实例化的结果。
Cat cat = new Cat();//创建了一个猫类的具体对象 new是关键字,称为实例化。左边的类名为对象的数据类型。右边的类名( )称为类的构造方法。 使用对象 在java中,要引用对象的字段和方法,需要使用成员运算符“ . ”。
对象名.属性 // 引用对象的字段 对象名.方法名() // 引用对象的方法 4.对象在计算机中的执行原理 面向对象的代码执行原理和数组的执行原理非常类似
Cat cat = new Cat();这句话的原理如下
Cat cat表示的是在栈内存中,创建了一个Cat类型的变量,变量名为catnew Cat()在堆内存中创建一个对象,而对象中包含猫的属性名和属性值,同时系统会为这个Cat对象分配一个地址值0x4f5656接着把对象的地址赋值给栈内存中的变量cat,通过cat记录的地址就可以找到这个对象当执行cat.color=“花色”时,其实就是通过cat找到对象的地址,再通过对象找到对象的color属性,再给对象的color属性赋值为花色。 举个例子
InvocationException: GraphViz's executables not found
报错翻译:
调用错误:找不到GraphViz的可执行文件
问题产生说明:
我在生成树可视化中,为了将生成树以图片显示。应用了如下代码,运行之后报错。
graph=pydotplus.graph_from_dot_data(dot_data) Image(graph.create_png()) 解决办法如下:
1、在anaconda环境下安装,按照如下命令安装:
conda install pydotplus
conda install graphviz
2、虽然安装了这两个安装包,但是运行的时候还是报同样的错误。原来只安装graphviz这个python包还不够,还得需要安装GraphViz’s executables。Graphviz不是一个python tool,它是一个独立的软件。可以按照如下方法安装。
先下载:由于我在官网上没找到那个安装包,这个是在别人的博客上看到的。可供参考
链接:https://pan.baidu.com/s/1lnBmQspuBqzYevtPr1xuTQ 提取码:ioxf 双击 graphviz-2.38.msi 安装 3、将 graphviz-2.38\bin 下的所有文件都放到所在 anaconda 的虚拟环境的 Library\bin 中(我的是放在“C:\ProgramData\Anaconda3\Library\bin”)
最后成功,亲测可用!
软考-计算机系统 CPU运算器 算术逻辑单元(ALU)负责算术运算和逻辑运算
累加寄存器(AC) 运算操作数和结果的寄存器
数据缓存寄存器(DR)CPU和其他设备之间的中转站
状态条件寄存器(PSW)略
CPU控制器 指令寄存器(IR)存放的是从内存中取得指令,就像个中间站一样,不过是存放指令的中间站
程序计数器(PC)存放的是指令的地址,还有计数的功能
地址寄存器(AR)存放的是cpu访问内存单元的地址
指令译码器(ID)是把操作码解析成对应的指令操作
原码 正数:符号位取 0 [+1]原 = 0 000 0001 负数:符号位取 1 [-1]原 = 1 000 0001 反码 负数:符号位不变,数值位置取反 [-1]反 = 1 111 1110 补码 负数:符号位不变,数值位置取反,最后加1 即反码加一
[-1]补 = 1 111 1111 移码 移码最简单了,不管正负数,只要将其补码的符号位取反即可。
正数:正反补一致 [+1]补 = 0 000 0001 机器码范围 0的机器码 [+0]原码=0 000 0000, [-0]原码=1 000 0000[+0]反码=0 000 0000, [-0]反码=1 111 1111[+0]补码=0 000 0000, [-0]补码=0 000 0000 浮点数运算 浮点数表示取值范围由阶码决定(e)精度由尾数决定小数点不需要占位 最大范围 最小范围 1.
背景 qt信号和槽之间的参数传递默认只能传递qt内部已有的类型,例如QString等,若我们自定义类型作为参数时,虽然编译不会报错,但运行时会提示connect无效,无法识别自定义的类。
此时需要我们将自定义类进行注册,之后connect才可以使用
自定义类型并注册 //自定义类型 Struct MyTestSt{ int x{0}; int y{0}; } /* 为信号和槽声明自定义类,该声明一般在类声明之后 被声明的类需要提供公共默认构造函数、公共复制构造函数和公共析构函数 */ //1、声明一个新的元类型,该宏会使QMetaType知道该类型,声明之后就可以使用QVariant调用该类 Q_DECLARE_METATYPE(MyTestSt); //2、若想要声明的类可以在信号和槽中使用还需要注册该类,后面括号保持为空,否则就是相当于定义别名 static int id_my_struct = qRegisterMetaType<MyTestStMyTestSt>>(); //3、之后就可以定义带有自定义参数的信号和槽函数 signals: void test_signal_show(const MyTestSt)
目录
1、字典的格式
2、创建字典
3、遍历访问字典中的值
4、检查字典中是否有某个键
5、更新字典数据
6、删除字典元素
7、字典的比较算法
8、合并字典
1、字典的格式 字典的每个键值key=>value对用冒号 : 分割,每个对之间用逗号,分割,整个字典包括在花括号{}中
d = {key1 : value1, key2 : value2 }
2、创建字典 dict()工厂函数被用来创建字典。如果不提供参数,会生成空字典。
d = dict(x=1,y=2) 输出:{'x': 1, 'y': 2}
d = dict([['x', 1], ['y', 2]]) 输出:{'x': 1, 'y': 2}
d = dict(zip(('x', 'y'), (1, 2))) 输出:{'x': 1, 'y': 2} 3、遍历访问字典中的值 d = dict(x=1,y=2,z=3) for k in d: print("key=%s,value=%s" %(k,d[k])) 输出:
key=x,value=1
key=y,value=2
key=z,value=3 4、检查字典中是否有某个键 d = dict(x=1,y=2,z=3) result = "
C语言基础知识(2) 1. 常用的基础函数 1.1 字符输入输出函数 输入:getchar(); 输入一个字符
输出:putchar(); 输出一个字符
#include <stdio.h> int main() { char a; a = getchar();//函数给变量赋值,将输入的一个字符放到变量a中 //等价于scanf("%c", &a); putchar(a); //输出a中的字符,一次只能输出一个字符 //等价于printf("%c", a); putchar('\n'); return 0; } 遍历字符串,以 ‘\0’ 作为字符串的结尾
#include <stdio.h> int main() { char a[100] = "hello";// 使用字符串常量初始化数组a int i = 0; // 遍历字符串 while(a[i] != '\0') { putchar(a[i]); i++ ; } putchar('\n'); //或者 for(i = 0; a[i] != '\0'; i++) { putchar(a[i]); } putchar('\n'); retrun 0; } 1.
修改Redis配置文件redis.conf,将notify-keyspace-events Ex配置项解开注释,第1075行左右。
Redis监听配置类
@Configuration public class RedisListenConfig { @Bean RedisMessageListenerContainer container(RedisConnectionFactory factory){ RedisMessageListenerContainer container=new RedisMessageListenerContainer(); container.setConnectionFactory(factory); return container; } } 监听带key失效的回调方法
@Component public class KeyExpiredListener extends KeyExpirationEventMessageListener { public KeyExpiredListener(RedisMessageListenerContainer listenerContainer) { super(listenerContainer); } /** * 使用该方法监听,当Redis的key失效的时候执行该方法 */ @Override public void onMessage(Message message, byte[] pattern) { //过期的key String expireKey=message.toString(); System.out.println("该key已经失效 = " + expireKey); } } 编写测试类,添加一个key到Redsi中
@Test public void redisKeyExpireListen(){ String key="userId"; redisTemplate.opsForValue().set(key,"001",1, TimeUnit.MINUTES); } 结果
在项目中,一般在进行缓存预热时,会在项目启动时将部分热点数据存入Redis。
实现步骤、导入Redis依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>2.3.9.RELEASE</version> </dependency> 实现InitializingBean接口,重写afterPropertiesSet()方法,在项目启动时会执行afterPropertiesSet()方法。
/** * 项目启动时执行该方法 * @throws Exception */ @Override public void afterPropertiesSet() throws Exception { List<Item> list = itemService.list(); list.stream().map(item->{ try { String itemJSON = MAPPER.writeValueAsString(item); //保存到Redis stringRedisTemplate.opsForValue().set("item:id:"+item.getId(),itemJSON); return item; } catch (JsonProcessingException e) { e.printStackTrace(); return null; } }).collect(Collectors.toList()); List<ItemStock> itemStockList = itemStockService.list(); itemStockList.stream().map(itemStock->{ try { String itemJSON = MAPPER.writeValueAsString(itemStock); //保存到Redis stringRedisTemplate.opsForValue().set("item:stock:id:"+itemStock.getId(),itemJSON); return itemStock; } catch (JsonProcessingException e) { e.printStackTrace(); return null; } }).
官网:https://create.baidu.com/
一、关于Hadoop,基本操作命令如下:
注:hadoop fs == hdfs dfs
创建文件夹
hdfs dfs -mkdir path
删除文件
hadoop fs -rm -r -skipTrash /path_to_file/file_name
删除文件夹
hadoop fs -rm -r -skipTrash /folder_name
修改文件夹权限
hdfs dfs -chmod [-R] 777 hdfs_file_path
二、关于Hadoop 主从节点切换
方案一:命令切换
查看节点状态
hdfs haadmin -getServiceState nn1
命令切换节点状态
到 hadoop 目录下执行:
1、将 NN2 切换为 Standby 备用节点
bin/hdfs haadmin -transitionToStandby --forcemanual nn2
2、将 NN1 切换为 Active 备用节点
bin/hdfs haadmin -transitionToActive --forcemanual nn1
效果图
详细可以参考以下链接: Hadoop集群 手动主备切换 (Active - Standby)_hadoop standby_温岚万叶的博客-CSDN博客
1、Yarn 资源调度器 Yarn 是一个资源调度平台,负责为运算程序提供服务器运算资源,相当于一个分布式的操作系统平台,而 MapReduce 等运算程序则相当于运行于操作系统之上的应用程序。
2、Yarn的基础框架 YARN 主要由 ResourceManager、NodeManager、ApplicationMaster 和 Container 等组件构成。
ResourceManager(RM)主要作用如下
处理客户端请求监控NodeManager启动或监控ApplicationMaster资源的分配与调度 NodeManager(NM)主要作用如下
管理单个节点上的资源处理来自ResourceManager的命令处理来自ApplicationMaster的命令 ApplicationMaster(AM)作用如下
为应用程序申请资源并分配给内部的任务任务的监控与容错 Container
Container是YARN中的资源抽象,它封装了某个节点上的多维度资源,如内存、CPU、磁盘、网络等。
3、Yarn的工作机制 MR 程序提交到客户端所在的节点。YarnRunner 向 ResourceManager 申请一个 Application。RM 将该应用程序的资源路径返回给 YarnRunner。该程序将运行所需资源提交到 HDFS 上。程序资源提交完毕后,申请运行 mrAppMaster。RM 将用户的请求初始化成一个 Task。其中一个 NodeManager 领取到 Task 任务。该 NodeManager 创建容器 Container,并产生MRAppmaster。Container 从 HDFS 上拷贝资源到本地。MRAppmaster 向 RM 申请运行 MapTask 资源。RM 将运行 MapTask 任务分配给另外两个NodeManager,另两个 NodeManager 分别领取任务并创建容器。MR 向两个接收到任务的 NodeManager 发送程序启动脚本,这两个 NodeManager分别启动MapTask,MapTask 对数据分区排序。MrAppMaster等待所有MapTask运行完毕后,向RM申请容器,运行ReduceTask。ReduceTask 向 MapTask 获取相应分区的数据。程序运行完毕后,MR 会向 RM 申请注销自己。 4、作业全提交过程 4.1、HDFS、YARN、MapReduce三者关系 4.2、作业提交过程之YARN 4.
SequenceInputStream 介绍
SequenceInputStream 类表示其他输入流的逻辑串联,即文件的合并。
它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。
最近公司需要解码一种分包文件,多个文件组合成一个整体,进行解码操作
然后就用到了SequenceInputStream 流
具体代码示例应用如下:
List<InputStream> inputStreams = new ArrayList<>(); String s = null; Long fileSize = 0L; for (int i = 0; i < sList.size(); i++) { Path filePath = new Path(sList.get(i).toString()); InputStream is = fileSystem.open(filePath); inputStreams.add(is); if(ObjectUtils.isEmpty(s)){ s = sList.get(i).toString(); } // 算出多包文件的总字节数 fileSize = fileSize + fileSystem.getLength(filePath); } if(fileSize <= 0){ return ; } Enumeration<InputStream> inputStreamEnum = Collections.enumeration(inputStreams); SequenceInputStream sequenceInputStream = new SequenceInputStream(inputStreamEnum); BufferedInputStream buff = new BufferedInputStream(sequenceInputStream); MyDataBufferedInputStream dis = new MyDataBufferedInputStream(buff); 原文链接:https://blog.
一、前言 数据响应式
所谓数据响应式就是建立响应式数据与依赖(调用了响应式数据的操作)之间的关系,当响应式数据发生变化时,可以通知那些使用了这些响应式数据的依赖操作进行相关更新操作,可以是DOM更新,也可以是执行一些回调函数。
从Vue2到Vue3都使用了响应式,那么它们之间有什么区别?
Vue2响应式:基于Object.defineProperty()实现的。Vue3响应式:基于Proxy实现的。 那么它们之间有什么区别?为什么Vue3会选择Proxy替代defineProperty?
请听我娓娓道来~~
重要插一句!!!!
defineProperty实际上是对象里面基本方法之一,而proxy是针对整个对象所有基本方法的拦截器。这是最本质的区别!!!!
二、Object.defineProperty() 1、Object.defineProperty Object.defineProperty(obj, prop, descriptor) 方法会直接在一个对象上定义一个新属性,或修改一个对象的现有属性,并返回此对象,其参数具体为:
obj:要定义属性的对象
prop:要定义或修改的 属性名称 或 Symbol
descriptor:要定义或修改的 属性描述符
从以上的描述就可以看出一些限制,比如: 目标是 对象属性,不是 整个对象 一次只能 定义或修改一个属性
当然有对应的一次处理多个属性的方法Object.defineProperties(),但在 vue 中并不适用,因为 vue不能提前知道用户传入的对象都有什么属性,因此还是得经过类似 Object.keys() + for 循环的方式获取所有的 key ->value,而这其实是没有必要使用 Object.defineProperties()
2、为什么使用Object.defineProperty const obj = { a: 1, b: 2, c: { a: 1, b: 2 } } // obj.a // obj.a = 3 首先思考:vue的响应式到底要干什么?无非就是做一件事,就是当我们读这个对象属性的时候,我们要知道它读了,我要做些别的事我要插一脚。当给它重新赋值的时候,我要知道它在重新赋值,我要插一脚。
上面代码现在这脚就插不进去,所以要想一个办法,把这个属性的读取和赋值变成一个函数,希望将来读这个属性的时候,运行这么个函数,给这个属性赋值的时候,把新的值传给我。一变函数就简单了,不要说插一脚,100脚都不是问题。
那怎么变成函数呢,在ES6之前,没有别的办法。只有Object.defineProperty()
const obj = { a: 1, b: 2, c: { a: 1, b: 2 } } let v = obj.
链接:
https://blog.csdn.net/luoyang_java/article/details/112602640?ops_request_misc=&request_id=bef121fa940e488299bbbf924c9937fb&biz_id=&utm_medium=distribute.pc_search_result.none-task-blog-2blogkoosearch~default-1-112602640-null-null.268v1control&utm_term=%E5%A6%82%E4%BD%95%E8%AF%BB%E6%BA%90%E7%A0%81&spm=1018.2226.3001.4450