UNIX环境高级编程——进程间通信

15.1 引言 本章将说明进程之间相互通信技术——进程间通信(InterProcess Communication,IPC)。 IPC类型包括: 前10种IPC形式通常限于同一台主机的两个进程之间的IPC;最后2种是仅有的支持不同主机上两个进程之间的IPC。 15.2 管道 管道是通过调用pipe函数创建的: #include <unistd.h> int pipe(int fd[2]); // 返回值:若成功,返回0;若出错,返回-1 经由参数fd返回两个文件描述符:fd[0]为读而打开,fd[1]为写而打开;fd[1]的输出是fd[0]的输入;fstat函数对管道的每一端都返回一个FIFO类型(命名管道)的文件描述符,可以用S_ISFIFO宏来测试管道。 单个进程中的管道几乎没有任何用处。通常,进程会先调用pipe,接着调用fork,从而创建从父进程到子进程的IPC通道,反之亦然: 对于从父进程到子进程的管道,父进程关闭管道的读端(fd[0]),子进程关闭写端(fd[1]): 对于一个从子进程到父进程的管道,父进程关闭fd[1], 子进程关闭fd[0]。 当管道的一端被关闭后,下列两条规则起作用: (1)当读(read)一个写端已被关闭的管道时,在所有数据都被读取后,read返回0,表示文件结束; (2)如果写(write)一个读端已被关闭的管道,则产生信号SIGPIPE,write返回-1,errno设置为EPIPE。 15.3 函数popen和pclose 常见的操作是创建一个连接到另一个进程的管道,然后读其输出或向其输入端发送数据,为此,标准I/O库提供了两个函数popen和pclose: #include <stdio.h> FILE *popen(const char *cmdstring, const char *type); // 返回值:若成功,返回文件指针;若出错,返回NULL int pclose(FILE *fp);; // 返回值:若成功,返回cmdstring的终止状态;若出错,返回-1 这两个函数实现的操作是:创建一个管道,fork一个子进程,关闭未使用的管道端,执行一个shell运行命令,然后等待命令终止;函数popen先执行fork,然后调用exec执行cmdstring,并且返回一个标准I/O文件指针;如果type是“r”,则文件指针连接到cmdstring的标准输出;如果type是“w”,则文件指针连接到cmdstring的标准输入: pclose函数关闭标准I/O流,等待命令终止,然后返回shell的终止状态。 15.4 协同进程 协同进程通常在shell的后台运行,其标准输入和标准输出通过管道连接到另一个程序。协同进程有连接到另一个进程的两个单向管道:一个接到其标准输入,另一个则来自其标准输出。我们想将数据写到其标准输入,经其处理后,再从标准输出读取数据。 15.5 FIFO FIFO有时被称为命名管道。未命名的管道只能在两个相关的进程之间使用,而且这两个相关的进程还要有一个共同的创建了它们的祖先进程。但是,通过FIFO,不相关的进程也能交换数据。 FIFO是一种文件类型,通过stat结构的st_mode成员的编码可以知道文件是否是FIFO类型,可以通过S_ISFIFO宏对此进行测试。 FIFO的路径名存在于文件系统中,创建FIFO类似于创建文件: #include <sys/stat.h> int mkfifo(const char *path, mode_t mode); int mkfifoat(int fd, const char *path, mode_t mode); // 两个函数的返回值:若成功,返回0;若出错,返回-1 mode参数的规格说明与open函数中的mode相同;mkfifoat函数可以被用来在fd文件描述符表示的目录相关的位置创建一个FIFO,像其他*at函数一样,有3种情形:

学生成绩管理系统(逻辑清楚-简单实用)

1、需求分析 1.1、需求分析概述 需求分析是我们在软件开发中的重要环节,是软件开发的第一步也是最基础的环节,这将决定我们所实现的目标以及系统的各个组成部分、各部分的任务职能、以及使用到的数据结构、各个部门之间的组成关系和数据流程,为我们的系统设计打下基础。 1.2、学生管理系统需求分析 1、实现数据的录入(INSERT)、删除(DELETE)、修改(UPDATE)、查找(SELECT)。 2、根据学生姓名查询信息 3、更新学生的班级 4、根据班级编号查询学生信息 5、根据学生id删除学生信息 6、插入学生分数记录 7、修改学生成绩 8、删除学生成绩 9、删除成绩 10、根据班级id查询所有学生的成绩 11、根据班级名称查询班级信息 2、设计思路 1、将数据库中的Student、Classes、Course、Score四张表封装为实体类 2、设计三种Classes、Score、Student对象的工具类,工具类的主要工作就是与数据库进行交互,实现录入(INSERT)、删除(DELETE)、修改(UPDATE)、查找(SELECT)四种操作。 3、主函数实现界面的修饰,根据我们的需求实现对某个对象的具体操作,界面的功能主要是通过调用我们所实现的工具类进行完成操作,所以说,界面能实现哪些功能取决于我们能够在工具类中所能实现哪些功能 2.1、流程图 根据上述系统功能的分析,按照结构化程序设计的要求,得到系统的结构图,如下图所示 3、详细设计 3.1、设计四张表的实体类 Classes表 public class Classes { private int id; private String name; private String desc; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDesc() { return desc; } public void setDesc(String desc) { this.

【VMware】VMware安装CentOS8-Stream虚拟机

本文首发于 慕雪的寒舍 VMware安装CentOS8-Stream虚拟机 1.安装VMware 由于最新版的vm要钱,这里提供一个VMware16pro的安装包;我知道度盘下载速度慢,但确实没啥其他选择,见谅。 后文将用vm来简称VMware 提取嘛: gdt9 亚索包解押: 8888 下载安装包后,右键以管理员身份运行,在弹出的提示框中选择是 在第一个选择框,点击下一步 勾选接受协议中条款,继续下一步; 此页添加到系统PATH需要勾选,安装位置自行选择 备注:我保留的是默认的C盘安装路径没有改动,所以修改到其他盘是否会印发其他问题,暂且不知。如果你的C盘空间足够,就安在C盘吧! 将检查产品更新和加入体验计划的钩都去掉,下一步 快捷方式默认就行,后续你可以自己改。这个想必都会吧! 此页点击下一步后,点击安装,等待安装完成。 安装完成后,会出现如下页面,点击许可证,填入许可证密钥。 许可证密钥你可以百度,我分享的压缩包里面就有一个许可证码,填那个就行了 这一步操作完毕后,点击完成,虚拟机软件安装成功 2.下载centos8系统iso 可以去两个地方下载,推荐跟随本文的操作用阿里云的镜像 centos官网:https://www.centos.org/download/阿里云镜像:http://mirrors.aliyun.com/centos/8-stream/isos/x86_64/ 本文安装的是centos8-stream的iso,本站所写的绝大部分linux博客,都兼容这个系统上的操作!这里我选择的是箭头所指的iso镜像。 为了避免后续的其他操作和本文不符,这里顺便也把iso镜像给上传了一个 https://pan.baidu.com/s/1jleRo4mxILq2RwSU-rxaaA 提取嘛: t7ay 3.安装Centos 3.1 创建虚拟机 先在你电脑硬盘的其他位置,创建一个空目录 打开vm软件主界面,点击创建新虚拟机 自定义 这里保持默认的,不需要修改 iso选择 iso选择刚刚下载的centos8-stream虚拟机 操作系统 操作系统选择linux和centos8 安装盘 选择刚刚创建的空文件夹(这里是虚拟机文件的安装路径,所以建议选择你电脑上比较空的那个盘,来创建文件夹) 核数选择 核数请根据你的CPU来选择,比如我的笔记本CPU是8核16线程的(ctrl+alt+delete打开你电脑的任务管理器来查看) 这里我选择了4核,内核数量选择2 注意,这里需要和你电脑的CPU匹配,8核16线程就代表每个处理器内核有2个,所以就应该选择2。如果是intel新的大小核设计的CPU,也可以选择2。部分老款的CPU是1核只有1线程的那种 (比如n5105是4核4线程的) 内存 根据你电脑的内存选择,建议选择低于总内存一半的 比如电脑是16G,建议只选到8G,否则虚拟机运行占用太多内存,容易弄得笔记本也卡卡的,干不了啥其他事情。 这里还需要纠正小白的一部分错误认识,内存是指运行内存,不是你电脑的硬盘容量!!!右键你电脑桌面上的此电脑,点击属性,就能看到你电脑有多少内存。 CentOS8本身占用内存并不多,但如果你想深入学习linux的编程操作,后续可能会用到vscode远程连接虚拟机,这时候内存太低就容易卡卡卡。所以建议至少选择2GB 现在的电脑都是8G内存打底了,主流价位的笔记本也普及了16GB,所以大家笔记本运行虚拟机都是没问题的。 网络 选择桥接 IO和磁盘 选择推荐的,不用修改 磁盘类型选择vm推荐的就行(不同电脑推荐的可能不一样) 磁盘最少选择20GB,根据自己电脑硬盘容量自行选择。选择的硬盘容量并不会立马占满,而是随着使用时长慢慢增加的; 虚拟磁盘勾选单个文件 磁盘文件名字不用修改 完成 看看有没有设置错误的,点击完成即可 点击开启虚拟机,即启动了centos 3.2 初始化 点击虚拟机的屏幕,使用键盘方向键选第一个install 会弹出一大堆文字,等待其跑完安装进程,会到下面的界面 语言 可以选择语言为中文,但为了方便后续和其他工具的学习接轨(大部分工具都没有中文),依旧推荐选择英语!而且这在系统里面是可以改的,问题不大

Sonatype Nexus Repository配置搭建

下载 官网有mac、windows、unix的下载版本,unix在CentOS7.9中可以运行 解压 tar -zxvf nexus-3.55.0-01-unix.tar.gz 安装java yum install java 只下载安装包不安装 yum install --downloadonly --downloaddir=/opt/a java 强制安装所有包 rpm -Uvh *.rpm --nodeps --force 进入nexus的bin目录下 ./nexus start start 是后台启动,日志以文件形式保存; run 是当前进程启动,直接打印在控制台; stop 是停止服务; restart 是重启服务; status 是查看服务状态 Maven 配置Nexus 镜像 <mirrors> <mirror> <id>mirror_name</id> <mirrorOf>*</mirrorOf> <url>http://nexus_ip:8081/repository/maven-public/</url> </mirror> </mirrors>

C++设计模式介绍、分类与设计模式原则

目录 一、设计模式定义 二、设计模式的优点 三、设计模式缺点 四、设计模式中的抽象思维 五、抽象的方法 六、设计模式应用场景 七、设计模式分类 八、设计模式八大原则 1、依赖倒置原则(DIP) 2、开放封闭原则(OCP) 3、单一职责原则(SRP) 4、Liskov替换原则(LSP) 5、接口隔离原则(ISP) 6、优先使用对象组合,而不是类继承 7、封装变化点 8、针对接口编程,而不是针对实现编程 九、设计模式使用场景 附加知识 (1)C++面向对象三种访问修饰符 (2)父类析构函数必须为虚函数 (3)override关键字使用 (4)final关键字使用 (5)父类对象可以与子类对象相互转化吗? (6)虚函数、虚函数表介绍 一、设计模式定义 是一套被反复使用的代码设计经验的总结,是经过提炼的出色设计方法。设计模式主要是指面向对象这种编程模型下的设计模式;把变化与稳定的分割,管理变化,提高复用(稳定的部分可以封装为基类或者方法接口,使用子类应对变化)。设计模式可以更好地适应需求地变化,将变化来的代码修改影响减为最小。 二、设计模式的优点 设计模式一般应用于大型项目中,设计模式可以使各模块之间的代码灵活性和可复用性增强。 灵活性是指:可扩展性和低耦合型;增加新的功能,不需要大范围修改代码。 可复用性是指:可以到处重复使用,面向对象的三大特性:封装、继承、多态。泛型编程。面向对象程序设计原则之一:单一原则(一个类只干好一件事,不涉及其他事物) 三、设计模式缺点 代码的复杂度增加,增加了学习和阅读的负担,设计模式在一定程序会降低代码运行效率(对于带来的优点其下降运行效率一般可忽略)。 应用设计模式不当导致的代码灵活性、可复用性、可读性下降。 四、设计模式中的抽象思维 抽象思维强调对象的本质属性,主要用于一些软件设计中的解耦合的过程。 抽象思维的概念:能从事物中抽取出或者提炼出一些本质的,共性的内容,把这些共性的内容组合到一起封装成一个类或者方法。继承抽象类的子类都有不同的特点进行扩展。 五、抽象的方法 1、分解法:把一个复杂的事物分解成若干个单一功能的事物。 2、抽象法:从每个简单的事物中,抽象出本质的内容,封装起来。抽象法是设计模式的本质。 六、设计模式应用场景 通常应用于大型项目(几万到几十万行代码及以上项目),不建议应用于小型项目(小型项目要是适合也可使用设计模式)。对于大量重复性代码,需要使用设计模式进行设计,提高代码扩展性。 七、设计模式分类 常用的设计模式可以分为三大类:行为型模式、创建型模式、结构型模式 (1)创建型模式有6种:简单工厂模式(Simple Factory)、工厂方法模式(Factory Method)、抽象工厂模式(Abstract Factory)、单例模式(Singleton)、原型模式(Prototype)、建造者模式(Builder)。 (2)结构性模式有7种:装饰模式(Decorator)、外观模式(Facade)、组合模式(Composite)、享元模式(Flyweight)、代理模式(Proxy)、适配器模式(Adapter)、桥接模式(Bridge) (3)行为型模式包括的设计模式有11种:模板方法模式(Template Method)、策略模式(Strategy)、观察者模式(Observer)、命令模式(Command)、迭代器模式(Iterator)、状态模式(State)、 中介模式(Mediator)、备忘录模式(Memento)、职责链模式(Chain Of Responsibility)、解释器模式(Interpreter)、访问者模式(Visitor)。 创建型模式定义:关注如何创建对象,将对象的创建和使用相互分离(解耦),取代传统对象创建方式带来的扩展性差的问题。 结构型模式:关注对象之间的关系。涉及如何组合各种对象以便获得更加灵活的结构,通过继承以及更多的关系组合获得更加灵活的程序结构。达到简化设计模式。 行为模式定义:关注对象的行为或者交互方面的内容,主要涉及算法和对象之间的职责分配。通过使用对象组合,行为模式可以描述一组对象如何协作来完成一个整体任务。 注意:设计模式代码一般不是一次设计设计好的,是多次修改而成。软件开发需求变化是频繁的,尝试寻找变化点,把变化部分和稳定部分分离开发,在变化的地方使用设计模式。 八、设计模式八大原则 任何设计模式的代码需要符合设计模式的原则,设计模式的原则如下: 1、依赖倒置原则(DIP) (1)高层模块(稳定)不应该依赖于低层模块(变化),二者都应该依赖于抽象(稳定)。 (2)抽象(稳定)不应该依赖于实现细节(变化),实现细节应该依赖于抽象(稳定)。 (1)中的高层模块指的是调用低层变化的Caller类对象或者方法,变化的低层模块指的是待调用Concre1、Concret2、、、对象或方法。抽象指的是对具有共同特征一类事物的抽象类。 (2)中的抽象跟(1)一致。实现细节指的是继承于抽象的具体类的子类,并对基类中的虚函数进行重写override。抽象类中不能依赖子类中的变化。 倒置原则较为重要,写个demo,如下: #include <iostream> #include <vector> class AbsProduct { public: virtual void color(){}; virtual ~AbsProduct(){}; }; class Caller { public: std::vector<AbsProduct*>vecProducts; //高层模块依赖于抽象,使用指针,才可以使用多态应对变化。 void PrintProductColor(){ for(unsigned int i = 0;i < vecProducts.

原生小程序 微信小程序 使用ucharts

一般是uni-app项目使用ucharts在原生微信小程序也是可以使用。 方法: ## 使用说明 请将项目根目录 微信小程序/uCharts-组件/qiun-wx-ucharts/src 下全部文件复制到指定位置,例如该项目的components/qiun-wx-uchart目录下,然后在页面的json配置文件中配置如下: { "usingComponents": { "qiun-wx-ucharts": "/components/qiun-wx-ucharts/index" } } 配置好后即可在wxml文件中使用 <view class="charts"> <qiun-wx-ucharts type="column" canvas2d="{{true}}" opts="{{opts}}" chartData="{{chartData}}" bindcomplete="complete"/> </view> 注:示例中uCharts组件仅做演示,实际使用请用码云或者npmjs中最新版本 ## 组件参数详见官网组件文档或在线演示中的代码 [https://www.ucharts.cn] 源码下载: uCharts: 高性能跨平台图表库,支持H5、APP、小程序(微信小程序、支付宝小程序、钉钉小程序、百度小程序、头条小程序、QQ小程序、快手小程序、360小程序)、Vue、Taro等更多支持canvas的框架平台,支持饼图、圆环图、线图、柱状图、山峰图、区域图、雷达图、圆弧进度图、仪表盘、K线图、条状图、混合图、玫瑰图、漏斗图、词云图、时序图、散点图、气泡图、地图等常见图表。 下载解决之后,找到对应的组件源码拷贝到微信小程序项目 源码组件复制 把组件下对应微信小程序src里的所有的文件复制到项目components/qiun-wx-charts目录下,components/qiun-wx-charts这二层目录没有的话就新建。 页面中引用该组件 wxml <view class="charts"> <qiun-wx-ucharts type="line" canvas2d="{{true}}" opts="{{opts}}" chartData="{{chartData}}" bindcomplete="complete"/> </view> js Page({ data: { chartData: {}, opts: {}, }, onReady() { this.getServerData(); }, getServerData() { //模拟从服务器获取数据时的延时 setTimeout(() => { //模拟服务器返回数据,如果数据格式和标准格式不同,需自行按下面的格式拼接 let chartData = { categories:["

arduino项目中应用到的 esp32 cam 网络图传+继电器+mqtt远程控制

Arduino ESP32-CAM是一款功能强大的开发板,它集成了ESP32和摄像头模块,非常适合用于物联网应用中。在本文中,我们将介绍如何使用ESP32-CAM实现网络图传、继电器控制和MQTT远程控制。 硬件准备 首先,我们需要准备以下硬件: Arduino ESP32-CAM开发板 USB串口线 路由器 继电器模块 LED灯 杜邦线若干 软件准备 接下来,我们需要安装以下软件: Arduino IDE ESP32-CAM插件 MQTT库 项目中应用 网络图传 ESP32-CAM默认使用WiFi连接网络,我们可以使用WiFi图传库将摄像头拍摄的图像传输到网络上。首先,在Arduino IDE中打开一个新的空白项目,然后依次点击“工具”->“开发板”->“ESP32 Wrover Module”,选择正确的端口和上传速度。接下来,下载并安装WiFi图传库。 在代码中,我们需要定义WiFi热点的名称和密码,然后调用WiFi图传库中的函数来连接网络。为了实现图传功能,我们还需要调用摄像头库拍摄照片,然后使用HTTP协议将图像传输到指定的URL上。 代码示例: #include "WiFi.h" #include "WiFiClient.h" #include "WiFiServer.h" #include "WiFiUdp.h" #include "esp_camera.h" #include "esp_http_server.h" #include "img_converters.h" #include "fb_gfx.h" #include "fd_forward.h" #include "fr_forward.h" #include "app_httpd.h" const char *ssid = "your_wifi_ssid"; const char *password = "your_wifi_password"; WiFiServer server(80); void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.

ChineseBERT使用指北

文章目录 ChineseBert 模型介绍开源代码使用方法未完待续 ChineseBert 模型介绍 论文地址:https://arxiv.org/pdf/2106.16038.pdf 代码地址:https://github.com/ShannonAI/ChineseBert bert是语义模型,因此无法解决形近字、音近字的问题。 ChineseBERT主要引入了文本的拼音编码和字形编码解决上述问题。 开源代码使用方法 下载上面地址的代码作为你的project下载ChineseBERT模型到project下的一个文件夹,命名为ChineseBERT-base在上面的文件夹下安装git-lfs并初始化(以Linux系统即我们常用的服务器为例): # git lfs是大型代码管理工具Large File Storage,在BERT等大型预训练模型中 sudo apt-get install git-lfs git lfs install git lfs pull 如果提示import代码错误,可能是transformer版本不一致导致的,可以直接去百度相应解决办法,总有前人替你踩过了许多坑。 未完待续 居中并且带尺寸的图片:

matlab实现图像小波变换

1.基本概念 小波变换是一种基于函数的数学变换,将信号分解成多个不同比例和频率的波的加权和,从而实现对信号的分析和处理。与傅里叶变换不同,小波变换具有时域和频域两个维度的分析能力,可以更好地理解信号的局部特征和结构信息。 在小波变换中,信号通过与不同尺度的小波函数(小波基)进行卷积和内积运算,得到不同尺度和频率的小波系数。这个过程可以通过分解滤波器和重构滤波器来实现,其中分解滤波器用来提取高频小波系数,重构滤波器用来提取低频小波系数,从而实现信号的逐层分解。最后合成所有的小波系数,就可以获得原始信号。 小波变换具有多尺度、多分辨率的特点,能够提取信号的时空分布特征,并且具有良好的局部分析能力。因此,在信号处理、图像处理、音频处理等领域都有广泛应用。常见的小波变换包括Haar小波、Daubechies小波、Symlet小波、Coiflet小波等,不同的小波基适合处理不同类型的信号和图像。 在实际应用中,小波变换常用于信号去噪、压缩、特征提取、图像增强等方面。为了获得理想的效果,通常需要选择合适的小波基、分解层数和阈值等参数,并根据具体情况进行预处理和后处理。 2.单层小波分解 clear all; close all; clc; I=imread('lena.bmp'); I=rgb2gray(I); [cal,chd1,cvd1,cdd1]=dwt2(I,'bior3.7'); cal=uint8(cal); figure; subplot(221),imshow(cal),title('近似分量'); subplot(222),imshow(chd1),title('细节水平分量'); subplot(223),imshow(cvd1),title('细节垂直分量'); subplot(224),imshow(cdd1),title('细节对角分量'); 3.单层小波重构 clear all; close all; clc; load woman; nbcol=size(map,1); [cA,cH,cV,cD]=dwt2(X,'db1');%利用db1小波,进行单层图像分解 sX=size(X); A0=idwt2(cA,cH,cV,cD,'db4',sX);%用小波分解的第一层系数进行重构 figure; subplot(131),imshow(uint8(X)),title('原图'); subplot(132),imshow(uint8(A0)),title('重构图'); subplot(133),imshow(uint8(X-A0)),title('差异图像'); 4.多层小波分解 clear all; close all; clc; load woman; nbcol=size(map,1); [c,s]=wavedec2(X,2,'db2');%采用db2小波进行2层图像分解 siz=s(size(s,1),:); ca2=appcoef2(c,s,'db2',2);%提取多层小波分解结构C和S的第2层小波交换的近似系数 chd2=detcoef2('h',c,s,2);%利用多层小波分解结构C和S来提取图像第2层的水平分量 cvd2=detcoef2('v',c,s,2);%利用多层小波分解结构C和S来提取图像第2层的垂直分量 cdd2=detcoef2('d',c,s,2);%利用多层小波分解结构C和S来提取图像第2层的对角分量 chd1=detcoef2('h',c,s,1);%利用多层小波分解结构C和S来提取图像第1层的水平分量 cvd1=detcoef2('v',c,s,1);%利用多层小波分解结构C和S来提取图像第1层的垂直分量 cdd1=detcoef2('d',c,s,1);%利用多层小波分解结构C和S来提取图像第1层的对角分量 cal1=ca2+chd2+cvd2+cdd2;%叠加重构近似图像 cal=appcoef2(c,s,'db4',1);%提取多层小波分解结构C和S的第1层小波交换的近似系数 figure; subplot(141),imshow(uint8(wcodemat(ca2,nbcol)));%wcodemat:对图像数据进行伪彩色编码 title('2层分解的各分量') subplot(142),imshow(uint8(wcodemat(chd2,nbcol))); subplot(143),imshow(uint8(wcodemat(cvd2,nbcol))); subplot(144),imshow(uint8(wcodemat(cdd2,nbcol))); figure; subplot(141),imshow(uint8(wcodemat(cal1,nbcol))); title('1层分解的各分量') subplot(142),imshow(uint8(wcodemat(chd1,nbcol))); subplot(143),imshow(uint8(wcodemat(cvd1,nbcol))); subplot(144),imshow(uint8(wcodemat(cdd1,nbcol))); 5.多层小波重构 clear all; close all; clc; X=imread('lena.

onvif 协议 为海康摄像头设置时间 demo

站在巨人的肩膀上:onvif-java使用方案解析(留存)_be.teletask.onvif_秀发浓密的程序猿的博客-CSDN博客 3个月前弄过一次,当时确认可以设置我就把代码都删除了🤣,今天又重弄了一遍。防止遗忘记录一下。 1、设置海康摄像头 onvif 2、修改巨人的代码 public String getXml() { // TODO Auto-generated method stub return "<SetSystemDateAndTime xmlns=\"http://www.onvif.org/ver10/device/wsdl\">" + "<tt:DateTimeType>Manual</tt:DateTimeType>\n" + " <tt:DaylightSavings>false</tt:DaylightSavings>\n" + " <tt:TimeZone>\n" + " <tt:TZ>GMT+08:00</tt:TZ>\n" + " </tt:TimeZone>\n" + " <tt:UTCDateTime>\n" + " <tt:Time>\n" + " <tt:Hour>6</tt:Hour>\n" + " <tt:Minute>38</tt:Minute>\n" + " <tt:Second>24</tt:Second>\n" + " </tt:Time>\n" + " <tt:Date>\n" + " <tt:Year>2020</tt:Year>\n" + " <tt:Month>4</tt:Month>\n" + " <tt:Day>28</tt:Day>\n" + " </tt:Date>\n" + " </tt:UTCDateTime>"+ "</SetSystemDateAndTime>"; } 原代码是获取摄像头时间,现在是修改摄像头时间。只有xml中的内容不同,其实只要知道接口的xml,所有接口请求都一样简单。

最新出炉的Java面试题(2023亲身经历)

面试题清单 个人近来面试了不少的公司的,该挂的挂,该应付通过的应付通过,目前对面试题部分做一个系统的总结。最起码要保证被问过的问题第二次被问到的时候是可以回答并且理解的。算是一个被动输入学习的过程。 题目持续更新,答案自己复盘整理好之后会进行补充。 Java语言相关面试题 JVM的内存模型JVM的垃圾回收线上如何JVM排错了解反射吗反射的使用场景用过反射吗什么是阻塞IO,什么是非阻塞IOHashMap 和 Hashtable 有什么区别 集合相关问题,HashMap HashMap数据结构是怎样的HashMap是线程安全的吗如何实现线程安全的HashMapHashMap可以动态扩容吗HashMap的HashCode之类的问题HashMap的Put原理HashMap 和 Hashtable 有什么区别集合了解过吗介绍一下集合的原理。线程安全的集合都有哪些集合的原理和实现为啥要有HashCode,Hash计算是什么链表如何扩容 线程 有使用过多线程吗多线程的使用场景线程池的核心参参数线程的生命周期如何使用线程池如何确保你的线程如何知道你的线程是死锁了,如何排查线上问题如何自定义线程的线程号、名字如何自己实现一个定时批处理 数据库 数据库的四大特性,说一下 ACID 是什么数据库的事务、事务的隔离级别数据库优化数据库设计的原则谈谈你项目中的数据库SQL优化什么情况下会索引失效 Redis Redis如何实现分布式锁Redis的基本数据类型Redis的持久化是如何实现的Redis的使用场景Redis的雪崩,缓存穿透布隆过滤器如何实现Redis的高可用Redis的过期策略,重新设置值的时候是否会刷新过期时间。 设计模式 单一职责是什么你了解过的设计模式都有哪些Spring涉及的设计模式都有哪些开发中使用过的设计模式有哪些(一定要说几个) 数据结构、算法 排序算法如何实现树的遍历方式有几种 框架Spring、SpringBoot、SpringCloud 用过SpringCloud的哪些组件Mybatis的动态代理,如何实现动态代理。如何使用SpringCloud Gateway实现一个IP负载均衡Spring的AOPSpring bean的生命周期Spring是如何解决循环依赖问题的Mybatis只有接口,没有实现类,为什么可以自动注入 中间件 你用过哪些中间件了解Rabbit MQ吗了解Kafka吗Rabbitmq 怎么避免消息丢失 协议 了解过RPC框架吗讲讲CAS协议的实现原理(简历中提到了,所以都会问)HTTP和HTTPS的区别HTTPS是如何实现的介绍一下TCP和UDP的区别同步和异步的区别如何设计一个好的接口如何确保接口的幂等性对称加密和非对称加密是什么,分别用于哪些场景,为什么CAS协议中密码是如何加密传输的RSA算法的原理是什么介绍一下用户发送一个请求的全流程是怎么样的如何解决跨域问题 部署 对Docker的理解和使用程度了解过K8S吗ELK的原理是什么 其他非技术问答题 项目中让你最有成就感的事有哪些未来是怎么打算的你遇到过的难点有哪些你有个人博客或者是个人能够展示自己能力的方式吗离职原因是什么呢介绍一下你的项目吧期望薪资是多少个人介绍(重中之重zzzz) 最后 私信回复“学习”即可免费获取更多面试资料!

【vue3】vue3组件通信方式

一、props 可以实现父子组件通信,子组件通过defineProps获取父组件传递的数据,且在子组件内部不需要引入defineProps方法就可以直接使用! 1、父组件给子组件传递数据 <Child hobby="学习" :money="money"></Child> <script setup lang="ts"> import Child from "./Child.vue"; import { ref } from "vue"; let money = ref(10000); </script> 2、子组件获取父组件传递数据 ①方式1:对象类型接收 let props = defineProps({ hobby:{ type:String,//接受的数据类型 default:'赚一个亿',//接受默认数据 }, money:{ type:Number, default:0 }}) ②方式2:数组类型接收 let props = defineProps(["hobby","money"]) 3、在模板中使用 <p>{{props.hobby}}</p> <p>{{props.money}}</p> 在模板中也可以省略props,但在script中不能省略 <p>{{hobby}}</p> <p>{{money}}</p> 注意点:props只能读取不能修改 const updateProps = ()=>{ props.money+=10; } 如果通过事件去改,会报警告并且值并不会进行修改 二、自定义事件 在vue中的事件分为原生的DOM事件和自定义事件,原生DOM事件可以让用户与网页进行交互,自定义事件可以实现子组件给父组件传递数据 1、原生DOM事件 vue3中的click、dbclick、change(这类原生DOM事件),不管是在普通标签还是组件标签上都是原生DOM事件,而在vue2中组件标签需要通过native修饰符才能变为原生DOM事件。 <div @click="handler1(1,2,3,$event)">传递多个参数</div> 注意:如果要传递参数并获取event事件对象,注入的事件对象务必叫做$event 2、自定义事件 组件标签写@click应该为原生DOM事件,但是如果子组件内部通过defineEmits定义就变为自定义事件了 1、子组件给父组件传递数据 子组件通过defineEmits方法传递一个数组,元素为将来组件需要触发的自定义事件类型,方法执行会返回一个$emit方法用于触发自定义事件,第一个参数为触发事件类型,第二个、三个、N个参数即为传递给父组件的数据。 <script setup lang="

常用HTTP响应状态码介绍

在Python爬虫中通过打印响应状态码(print(response.status_code))来判断响应是否正常,本篇文章将详细介绍HTTP响应状态码含义,方便在后续的Python学习能更加得心应手。 HTTP(Hypertext Transfer Protocol,超文本传输协议)是用于在网页浏览器和Web服务器之间传输信息的协议。 HTTP响应状态码是Web服务器返回给客户端(通常是浏览器)的一种状态提示。它由三位数字组成,以告诉客户端请求的处理情况。一般来说,HTTP状态码分为五个类别: 1xx(信息性状态码):表示接收到请求并且正在被处理。 2xx(成功状态码):表示操作被成功接收、理解和接受。 3xx(重定向状态码):表示需要客户端执行一些额外的操作才能完成请求。 4xx(客户端错误状态码):表示客户端发生错误,请求无法被服务器处理。 5xx(服务器错误状态码):表示服务器在处理请求时发生错误。 下面介绍常见的HTTP响应状态码及其对应含义: 200 OK:表示服务器成功处理了请求。通常是用于GET和POST请求,响应体包含了请求的资源。 201 Created:表示服务器成功创建了新的资源。通常是用于在服务器上添加新的资源。 204 No Content:表示服务器成功处理了请求,但没有返回任何数据。通常是用于DELETE请求,或仅需要服务器处理而不需要返回数据的请求。 301 Moved Permanently:表示所请求的资源已经被永久移动到新的地址。浏览器通常会自动重定向到新地址。 302 Found:和301类似,但只是表示所请求的资源已经被临时移动到新的地址。浏览器通常也会自动重定向到新地址。 304 Not Modified:表示客户端已经正确地缓存了资源,而服务器确认它在上次请求之后没有发生修改。服务器实际上不会返回资源,而是告诉客户端直接使用它们的缓存副本。 400 Bad Request:表示客户端所发送的请求内容有误,服务器无法处理。通常是由于参数不正确或不完整导致的。 401 Unauthorized:表示请求需要有HTTP认证信息,或者认证失败。浏览器发送一个HTTP头Authorization包含认证信息。 403 Forbidden:表示请求的资源被服务器拒绝了。可能由于客户端没有权限访问,或者服务器配置不当。 404 Not Found:表示服务器无法找到所请求的资源。可能是因为URL地址有误或者资源已被删除。 500 Internal Server Error:表示服务器在处理请求时发生了未知的错误。可能是由于代码错误或者服务器配置错误导致的。 以上是常见的HTTP响应状态码及其对应含义。不同的状态码代表着不同的含义和处理方式,了解HTTP状态码可以帮助我们更好地理解Web服务器和客户端之间的交互过程,也可以帮助我们在Python爬虫开发中更好地调试和处理各种错误。

迷宫生成算法

迷宫生成 ① 十字分割 递归版本 ② BFS(即广度算法) 十字分割方法生成 要求初始时迷宫内全是通路,然后随机十字建墙,然后随机在三面墙上打洞,使四个子空间连通。 要求:十字点横纵坐标均要求为偶数(即地图行列为奇数),打洞点要求为奇数。 DFS 方法生成: 像一只地鼠打洞一般,迷宫要求初始时全是阻碍(墙),然后随机方向打洞(挖墙)。 要求,待挖墙的通路(打洞方向)只能与访问过的节点处打穿。 实战演练 十字分割 非常简单的一个方法,不过游戏效果不是很好。下面介绍下算法过程: 首先全部围起来,然后做一个十字墙 打通十字墙任意三堵墙 递归生成十字墙,然后打通任意三堵墙 然后就生成了最简单的迷宫(其实没啥卵用的迷宫,就当是温习递归) DFS 方法 其实就是一种挖墙算法,嗯,我是这样认为的。详细讲解一下这个算法。 先看一下定义地图的Node结构, #define MAP_ROW 20 #define MAP_COL 25 Node map[MAP_ROW][MAP_COL] = { 0 }; //每个墙 都没打通的 每个结点 都是没有访问过 struct Node { int flag; //表示关键结点是否访问过 0:未访问 1:已访问 2:待访问 // 3:人物 4:目的地 bool left, right, top, buttom; //表示这个节点周围的四堵墙 0:不可通过的墙 1:可通过的空地 }; 然后就是生成迷宫地图,也就是初始化函数init(),先选中左上角作为迷宫的入口,也是人物所在地 map[0][0].flag = 1; //这个节点已经访问过 定义辅助数组储存待访问节点 COORD waitForVisit[MAP_COL * MAP_ROW]; //存放待访问的结点 int len = 0; //map里面的坐标的个数 同时已访问节点周围是待访问节点,将其添加到辅助数组里面去,

大数据技术之Hadoop(MapReduce)

大数据技术之Hadoop(MapReduce) 第1章 MapReduce概述 1.1 MapReduce定义 MapReduce是一个分布式运算程序的编程框架,是用户开发“基于Hadoop的数据分析应用”的核心框架。 MapReduce核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序,并发运行在一个Hadoop集群上。 1.2 MapReduce优缺点 1.2.1 优点 1)MapReduce易于编程 它简单的实现一些接口,就可以完成一个分布式程序,这个分布式程序可以分布到大量廉价的PC机器上运行。也就是说你写一个分布式程序,跟写一个简单的串行程序是一模一样的。就是因为这个特点使得MapReduce编程变得非常流行。 2)良好的扩展性 当你的计算资源不能得到满足的时候,你可以通过简单的增加机器来扩展它的计算能力。 3)高容错性 MapReduce设计的初衷就是使程序能够部署在廉价的PC机器上,这就要求它具有很高的容错性。比如其中一台机器挂了,它可以把上面的计算任务转移到另外一个节点上运行,不至于这个任务运行失败,而且这个过程不需要人工参与,而完全是由Hadoop内部完成的。 4)适合PB级以上海量数据的离线处理 可以实现上千台服务器集群并发工作,提供数据处理能力。 1.2.2 缺点 1)不擅长实时计算 MapReduce无法像MySQL一样,在毫秒或者秒级内返回结果。 2)不擅长流式计算 流式计算的输入数据是动态的,而MapReduce的输入数据集是静态的,不能动态变化。这是因为MapReduce自身的设计特点决定了数据源必须是静态的。 3)不擅长DAG(有向无环图)计算 多个应用程序存在依赖关系,后一个应用程序的输入为前一个的输出。在这种情况下,MapReduce并不是不能做,而是使用后,每个MapReduce作业的输出结果都会写入到磁盘,会造成大量的磁盘IO,导致性能非常的低下。 1.3 MapReduce核心思想 (1) 分布式的运算程序往往需要分成至少2个阶段。 (2)第一个阶段的MapTask并发实例,完全并行运行,互不相干。 (3)第二个阶段的ReduceTask并发实例互不相干,但是他们的数据依赖于上一个阶段的所有MapTask并发实例的输出。 (4)MapReduce编程模型只能包含一个Map阶段和一个Reduce阶段,如果用户的业务逻辑非常复杂,那就只能多个MapReduce程序,串行运行。 总结:分析WordCount数据流走向深入理解MapReduce核心思想。 1.4 MapReduce进程 一个完整的MapReduce程序在分布式运行时有三类实例进程: (1)MrAppMaster:负责整个程序的过程调度及状态协调。 (2)MapTask:负责Map阶段的整个数据处理流程。 (3)ReduceTask:负责Reduce阶段的整个数据处理流程。 1.5 官方WordCount源码 采用反编译工具反编译源码,发现WordCount案例有Map类、Reduce类和驱动类。且数据的类型是Hadoop自身封装的序列化类型。 1.6 常用数据序列化类型 Java类型 Hadoop Writable类型 Boolean BooleanWritable Byte ByteWritable Int IntWritable Float FloatWritable Long LongWritable Double DoubleWritable String Text Map MapWritable Array ArrayWritable Null NullWritable

CSS面试题整理汇总

1、面试官:说说你对盒子模型的理解? CSS盒模型本质上是一个盒子,它包括:content、padding、border、margin。CSS 中的盒子模型包括IE 盒子模型和标准的 W3C 盒子模型。 在标准的盒子模型中,width 指 content 部分的宽度。 在 IE 盒子模型中,width 表示 content+padding+border 这三个部分的宽度 故在计算盒子的宽度时存在差异: 标准盒模型: 一个块的总宽度= width+margin(左右)+padding(左右)+border(左右) 怪异盒模型: 一个块的总宽度= width+margin(左右)(既 width 已经包含了 padding 和 border值) 2、box-sizing属性 CSS中的 box-sizing 属性定义了引擎应该如何计算一个元素的总宽度和总高度 box-sizing:content-box|border-box|inherit: content-box:元素的 width/height 不包含padding,border,。【标准盒子模型】 border-box:元素的 width/height 包含 padding,border。【IE 盒子模型】 inherit:继承父元素的 box-sizing 值。 3、面试官:css选择器有哪些?优先级?哪些属性可以继承? 关于css属性选择器常用的有: id选择器(#myid) 类选择器(.myclass) 属性选择器(a[rel="external"]) 伪类选择器(a:hover, li:nth-child) 标签选择器(div, h1,p) 兄弟选择器(h1 + p) 子选择器(ul > li) 后代选择器(li a) 通配符选择器(*) 优先级: !important 内联样式(1000) ID选择器(0100) 类选择器/属性选择器/伪类选择器(0010) 元素选择器/伪元素选择器(0001) 关系选择器/通配符选择器(0000)

vue-i18n插入变量,HTML等

定义i18n变量: assets\locales\zh-CN\base.json { "cups-count": "这里有{count}个杯子" } components\cup\index.vue: 一、直接插入count变量: <p>{{$t('cups-count', {count:6})}}</p> 直接使用变量,页面上: <template> <div class="page-section"> <p class="page-section-title">杯子详情</p> <!-- 插入文字 --> <div class="f12"> <p>{{$t('cups-count', {count:6})}}</p> </div> </div> </template> 二、以HTML形式插入count变量: p标签中,要单独给count变量的值设置颜色,所以要在p标签中插入span标签,给span标签设置类名: <i18n path="cups-count" :tag="false"> <template slot="count"> <span class='theme-color'>6</span> </template> </i18n> count变量以HTML形式插入,页面上: <template> <div class="page-section"> <p class="page-section-title">杯子详情</p> <!-- 插入HTML --> <div class="f12"> <i18n path="cups-count" :tag="false"> <template slot="count"> <span class='theme-color'>6</span> </template> </i18n> </div> </div> </template>

深入理解多层感知机(MLP):原理与代码解析

文章目录 1. MLP的原理1.1 结构1.2 激活函数1.3 前向传播1.4 反向传播算法 2.MLP分类任务应用3.参考文献: 多层感知机(MLP)是一种经典的神经网络模型,由多个神经元层组成。它的结构和功能使其成为深度学习中的重要组成部分。MLP在各种任务中表现出色,如图像分类、文本分类、预测和回归等。 1. MLP的原理 1.1 结构 MLP由输入层、隐藏层和输出层组成。输入层接收输入数据,隐藏层通过学习特征表示,输出层产生最终的预测结果。隐藏层和输出层的每个神经元都具有激活函数,用于引入非线性映射。 1.2 激活函数 常用的激活函数包括Sigmoid、ReLU、Tanh等。激活函数的作用是在神经网络中引入非线性性质,使其能够学习复杂的非线性关系。 1.3 前向传播 MLP的前向传播过程即从输入层到输出层的计算过程。它涉及到权重和偏置的计算、激活函数的应用等。通过一个简单的二分类任务为例来演示MLP的前向传播过程。 import numpy as np def sigmoid(x): return 1 / (1 + np.exp(-x)) # MLP的前向传播 def forward_propagation(inputs, weights, biases): hidden_layer = sigmoid(np.dot(inputs, weights[0]) + biases[0]) output_layer = sigmoid(np.dot(hidden_layer, weights[1]) + biases[1]) return output_layer # 输入数据 inputs = np.array([1, 2, 3]) # 权重和偏置 weights = [np.array([[0.2, 0.3, 0.4], [0.3, 0.4, 0.5]]), np.

(Appium_apk package)查询apk包名

查询apk包名–通过应用查看包名 aapt dump badging D:\**\Twitter.apk aapt dump badging D:\test\xxx.apk(APK的全名) 需要配置环境 回车执行结果 res 手机或模拟器上已安装app ·way 2 :use adb search· …查看当前正在运行应用的包名 ···adb shell dumpsys window w |findstr \/ |findstr name=

android11安装应用触发桌面图标刷新流程

Android系统启动篇 1,《android系统启动流程简介》 2,《android init进程启动流程》 3,《android zygote进程启动流程》 4,《Android SystemServer进程启动流程》 5,《android launcher启动流程》 6,《Android Activity启动过程详解》 Android系统开发准备篇 1,《Android 源码下载和编译》 2,《android 11源码编译和pixel3 刷机》 3,《Android Framework代码IDE加载和调试》 Android系统开发实践篇 1,《android设置默认输入法》 2,《android framework预制APK应用》 3,《Android系统层面限制应用开机自启动详解》 4,《android单独编译framework模块并push》 5,《Android Framework开发系统问题分析》 Android系统开发核心知识储备篇 1,《Android编译系统-envsetup和lunch代码篇》 2,《Android编译系统-概念篇》 3,《android日志系统详解》 4,《Android系统Handler详解》 5,《Android系统Binder详解》 6,《Android中Activity、View和Window关系详解》 7,《android view绘制流程详解》 8,《Android读取系统属性详解》 9,《android 窗口管理机制详解》 10,《初识Android系统》 11,《android中AMS进程通知Zygote进程fork新进程的通信方式》 Android核心功能详解篇 1,《android应用市场点击下载APK安装详解》 2,《Android 手势导航(从下往上滑动进入多任务页面)》 3,《android手势分析(应用界面左往右边滑动退出应用)》 4,《android应用安装流程详解》 5,《android11安装应用触发桌面图标刷新流程》 6,《Android系统多任务Recents详解》 7,《android系统导航栏视图分析》 ——————————————————————————————————————————— 应用安装调用流程: 1, 注册监听 LauncherAppState.java public LauncherAppState(Context context) { mInstallSessionTracker = InstallSessionHelper.INSTANCE.get(context) .registerInstallTracker(mModel, MODEL_EXECUTOR); } InstallSessionHelper.java public InstallSessionTracker registerInstallTracker( InstallSessionTracker.

Android编译系统-概念篇

Android系统启动篇 1,《android系统启动流程简介》 2,《android init进程启动流程》 3,《android zygote进程启动流程》 4,《Android SystemServer进程启动流程》 5,《android launcher启动流程》 6,《Android Activity启动过程详解》 Android系统开发准备篇 1,《Android 源码下载和编译》 2,《android 11源码编译和pixel3 刷机》 3,《Android Framework代码IDE加载和调试》 Android系统开发实践篇 1,《android设置默认输入法》 2,《android framework预制APK应用》 3,《Android系统层面限制应用开机自启动详解》 4,《android单独编译framework模块并push》 5,《Android Framework开发系统问题分析》 Android系统开发核心知识储备篇 1,《Android编译系统-envsetup和lunch代码篇》 2,《Android编译系统-概念篇》 3,《android日志系统详解》 4,《Android系统Handler详解》 5,《Android系统Binder详解》 6,《Android中Activity、View和Window关系详解》 7,《android view绘制流程详解》 8,《Android读取系统属性详解》 9,《android 窗口管理机制详解》 10,《初识Android系统》 11,《android中AMS进程通知Zygote进程fork新进程的通信方式》 Android核心功能详解篇 1,《android应用市场点击下载APK安装详解》 2,《Android 手势导航(从下往上滑动进入多任务页面)》 3,《android手势分析(应用界面左往右边滑动退出应用)》 4,《android应用安装流程详解》 5,《android11安装应用触发桌面图标刷新流程》 6,《Android系统多任务Recents详解》 7,《android系统导航栏视图分析》 ——————————————————————————————————————————— 一,基础介绍 在 Android 7.0 之前,Android 编译系统使用 GNU Make 描述和shell来构建编译规则,模块定义都使用Android.mk进行定义,Android.mk的本质就是Makefile,但是随着Android的工程越来越大,模块越来越多,Makefile组织的项目编译时间越来越长。 从Android7.0开始,Google采用ninja来代取代之前使用的make,由于之前的Android.mk数据实在巨大,因此Google加入了一个kati工具,用于将Android.mk转换成ninja的构建规则文件buildxxx.ninja,再使用ninja来进行构建工作。Android8.0开始,Google为了进一步淘汰Makefile,因此引入了Android.bp文件来替换之前的Android.mk。 Android.bp只是一个纯粹的配置文件,不包括分支、循环语句等控制流程,本质上就是一个json配置文件。Android.bp 通过Blueprint+soong转换成ninja的构建规则文件build.ninja,再使用ninja来进行构建工作。 Google在 Android 7.0之后,引入了Soong构建系统,旨在取代make,它利用 Kati GNU Make 克隆工具和 Ninja 构建系统组件来加速 Android 的构建。

C/C++《程序设计课程设计》[2023-06-14]

C/C++《程序设计课程设计》[2023-06-14] 《程序设计课程设计》 指导书 程序设计课程设计说明书 一、设计任务与要求 《程序设计课程设计》是在完成《程序设计基础》课程学习后进行的一门专业实践课程,是培养学生综合运用所学知识解决专业相关问题的重要环节,是对学生实际工作能力的具体训练和考察过程。本次课程设计的题目使用C语言来开发。要求每个学生可以独立完成C语言程序设计设计题目,同时可以通过同学间的讨论,共同编写比较复杂的综合课程设计题目。希望同学能避免抄袭,努力实践,提高实际动手能力。要求每个学生必须参加,并完成如下各项课程设计任务: 要求每个学生认真阅读本程序设计课程设计说明书,理解课程设计的目的和任务。要求学生通过自学理解和掌握本说明书附录2中给出的程序实例,读懂其中程序的设计功能,设计思想,设计结构,设计技巧,设计的不足等情况,提高阅读较大并且较为复杂程序源代码的能力,也可以通过实例理解本次课程设计要求的设计任务的规模和难度。要求每个学生根据自己的实际情况选择一个题目,实际动手完成这个题目,编写出程序代码,并调试通过。 4 每个同学选择一个题目,复杂问题的选题可以多人一组来实现,但是每人要有独立完成的部分,原则上不允许多组同学选择同一个题目。多组同学选择同样题目时,独立完成,程序代码不可相同。要求每个学生完成课程设计后撰写《课程设计报告》,可以按照任务书后面附带的课程设计报告模版的格式实际撰写。要求每位学生必须在上机前做好充分准备,每次上机必须目的明确,必须事先编写好程序代码,然后在规定的时间和地点上机调试。 二、学生选题原则 1.学生根据自身情况选择其中一道题目,作为课程设计选题,最终确定题目,选择的题目需要提交给指导教师并得到确认。允许学生在给出可供选择题目之外自己选择题目,但要经指导教师同意。 3.允许两至三名学生共同选择较复杂的题目,并共同完成。 三、课程设计实施过程 1.在课程设计开始时,公布此课程设计说明书。 2.教师根据需要安排合适的时间、地点进行答疑。 3.教师要认真检查学生完成的程序进展情况。 4 教师要指导学生撰写符合规范的《程序设计课程设计报告书》。 5.每个学生必须参加课程设计答辩,针对课程设计的内容回答提问。 四、检查考核办法 首先检查完成后的程序能否正常运行和得出希望的结果,程序检查通过后再检查所撰写的《课程设计报告书》, 最后参加课程设计答辩,根据报告的质量及面试的结果给出学生课程设计的成绩。 五、考核评分标准: 1.评阅教师可根据学生选择题目的难度、完成功能的多少、以及完成质量的优劣进行综合评分。完成质量较好,即可评定为优秀;完成质量尚可但有明显不足,可以评为良好;完成质量一般,成绩为中等;完成质量较差,成绩为及格;没有完成,成绩为不及格。 2. 成绩评定由指导教师根据学生面试和对设计报告的评审得出;成绩评为优秀和不及格的,要参加由系组织的统一答辩,答辩组给出最后成绩。优秀的比例为15%以内。 3. 如果发现两名或更多同学的课程设计相同部分过多,特别是程序的源代码相同部分达到或超过90%,则认定为抄袭,成绩评定为不及格。如果发现与现有技术书籍或网上资料相同部分过多,特别是程序的源代码相同部分达到或超过80%,也认定为抄袭,成绩评定为不及格。允许参考同学的工作,允许参考现有技术书籍或网上的资料,但要有自己的不同或改进之处,可以利用已有程序的代码,但要自己重新组织,调试通过并对程序理解正确。 附录1 《C语言程序设计课程设计》题目与要求 序号题目名称1组2组3组 1职工信息管理系统设计 2图书信息管理系统设计 3学生信息管理系统设计 4学生选修课程系统设计 5学生成绩管理系统设计 6酒店管理系统 7订票管理系统 8销售管理系统 9企业员工全年销售额统计及奖金发放系统 10学生综合测评系统 11学校运动会管理系统 12教师工资管理系统 13教师工作量管理系统 14会议室管理系统 15密码保险箱 16共享单车管理系统 17菜鸟驿站快递管理系统 18美容店会员管理系统 19租车门店管理系统 20点歌台 21停车场管理系统 一、选题内容及要求 1、职工信息管理系统设计 职工信息包括职工号、姓名、性别、年龄、学历、工资、住址、电话等。试设计一职工信息管理系统,使之能提供以下功能: 系统以菜单方式工作 (1)职工信息录入功能(职工信息用文件保存) (2)职工信息浏览功能 (3)查询功能:按工号和按学历查询 (4)信息删除功能:按职工姓名删除 (5)信息修改功能:把研究生学历的职工工资增加500元。 (6)可以以职工姓名拼音首字母或当月出勤率进行排序。 源码 https://pan.baidu.com/s/1J–MYtUyPilpJKTD15-SgA?pwd=1111 2、图书信息管理系统设计 图书信息包括:登录号、书名、作者名、分类号、出版单位、出版时间、价格、存在状态(已借和已还)、借书人姓名、性别、学号等。试设计一图书信息管理系统,使之能提供以下功能:系统以菜单方式工作 (1)图书信息录入功能(图书信息用文件保存)——输入 (2)图书信息浏览功能--输出 (3)查询功能:按书名查询和按作者名查询

Java发送HTTP GET/POST请求

在这篇文章中,将向你展示四种发送Http的GET/POST的例子,如下: 目录 一、Java 11 HttpClient二、Java原生HttpURLConnection三、Apache HttpClient四、OkHttp 一、Java 11 HttpClient 在Java11的java.net.http.*包中,有一个HttpClient类可以完成HTTP请求。 Java11HttpClientExample.java package com.lyl.http; import java.net.URI; import java.net.URLEncoder; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; public class Java11HttpClientExample { private final HttpClient httpClient = HttpClient.newBuilder() .version(HttpClient.Version.HTTP_2) .build(); public static void main(String[] args) throws Exception { Java11HttpClientExample obj = new Java11HttpClientExample(); System.out.println("测试1:发送Http GET 请求"); obj.sendGet(); System.out.println("测试2:发送Http POST 请求"); obj.sendPost(); } private void sendGet() throws Exception { HttpRequest request = HttpRequest.

新型镇痛药物的原型K-DPro-T|117027-34-6

KdPT是一种d - pro修饰的IL-1β类似物(193-195),以剂量依赖的方式拮抗IL-1β引起的痛觉过敏。因此,它可以被认为是一类新型镇痛药物的原型。 编号: 200173 中文名称: 三肽(D-Pro¹⁹⁴)-IL-1β (193-195) (human) CAS号: 117027-34-6 单字母: H2N-K-DPro-T-OH 三字母: H2N-Lys-DPro-Thr-COOH 氨基酸个数: 3 分子式: C15H28N4O5 平均分子量: 344.41 精确分子量: 344.21 等电点(PI): 9.71 pH=7.0时的净电荷数: 0.98 平均亲水性: 1.3 疏水性值: -2.07 来源: 人工化学合成,仅限科学研究使用,不得用于人体。 储存条件: 负80℃至负20℃

自动化运维工具—Ansible

一、Ansible概述 1.1 Ansible是什么 Ansible是一个基于Python开发的配置管理和应用部署工具,现在也在自动化管理领域大放异彩。它融合了众多老牌运维工具的优点,Pubbet和Saltstack能实现的功能,Ansible基本上都可以实现。 Ansible能批量配置、部署、管理上千台主机。比如以前需要切换到每个主机上执行的一或多 个操作,使用Ansible只需在固定的一台Ansible控制节点上去完成所有主机的操住。 Ansible是基于模块工作的,它只是提供了一-种运行框架,它本身没有完成任务的能力,真正执行操作的是Ansible的模块,比如copy模块用于拷贝文件到远程主机上,service模块用于管理服务的启动、停止、重启等。 1.2 Ansible的四个组件: Inventory 主机清单(主机组)Modules 模块Plugins 插件Playbooks 剧本(相当于脚本) 1.3 Ansible的特性 (1)特性一: Ansible其中一个比较鲜明的特性Agentless,即无Agent的存在(无代理端,即无客户端),它就像普通命令一样, 并非c/s软件,也只需在某个作为控制节点的主机上安装一次Ansible即可,通常它基于ssh连接来控制远程主机,远程主机上不需要安装Ansible或其它额外的服务。 使用者在使用时,在服务器终端输入命令或者playbooks,会通过预定好的规则将playbook拆解为play(一个play就是一个Linux操作),再组织成ansible可以识别的任务,调用模块和插件,根据主机清单通过SSH将临时文件发给远程的客户端执行并返回结果,执行结束后自动删除。 (2)特性二: Ansible的另一个比较鲜明的特性是它的绝大多数模块都具备幂等性(idempotence)。所谓幂等性,指的是多次操作或多次执行对系统资源的影响是一致的。 比如执行 systemctl stop xxx 命令来停止服务,当发现要停止的目标服务已经处于停止状态,它什么也不会做,所以多次停止的结果仍然是停止,不会改变结果,它是幂等的,而systemctl restart xxx是非幂等的。 Ansible的很多模块在执行时都会先判断目标节点是否要执行任务,所以,可以放心大胆地让Ansible去执行任务,重复执行某个任务绝大多数时候不会产生任何副作用。 二、Ansible 环境安装部署 实验环境: 角色IP安装工具管理端192.168.126.27ansible被管理端192.168.126.28无需安装被管理端192.168.126.29无需安装被管理端192.168.126.26无需安装 安装部署: hostnamectl set-hostname ansible #iptables默认放通ssh 所以不用关闭防火墙 #1、管理端安装ansible yum install -y epel-release #先安装epel源 yum install -y ansible #安装ansible ​ #ansible目录结构 [root@ansible ~]# cd /etc/ansible [root@ansible ansible]# tree . ├── ansible.cfg ├── hosts └── roles ​ 1 directory, 2 files ​ ​ #2、配置主机清单,修改/etc/ansible/hosts文件 cd /etc/ansible vim hosts [webservers] #配置组名 192.

在JS文件中加载另一个JS文件的教程

1、加载在头部 1 2 3 var js = document.createElement('script'); js.src = 'myscript.js'; document.getElementsByTagName('head')[0].appendChild(js); 另一种写法是: 1 2 3 var js = document.createElement('script'); js.src = 'myscript.js'; document.head.appendChild(js); 2、加载在BODY中 加载在页面中的写法如下: 1 2 3 var js = document.createElement('script'); js.src = 'myscript.js'; document.body.appendChild(js); 这种加载方法存在一个问题,就是有可能代码是在head区域,导致body还没达到,document.body就不存在,代码就会出错。 3、使用documentElement document.documentElement就是html文档本身,因此肯定是存在的,这种调用的写法如下: 1 2 3 4 var js = document.createElement('script'); js.src = 'myscript.js'; var html = document.documentElement; html.insertBefore(js, html.firstChild); 4、加载在第一个脚本前 这种方法是把js文件插入到第一个出现script的标识前,除非网页里没有任何一个script出现,否则应该不会出错。代码的写法如下: 1 2 3 4 var js = document.createElement('script'); js.src = 'myscript.

经典算法之——解决全排列问题以及详解

文章目录 全排列解析一、回溯法二、字典序法三、相邻对换法 全排列解析 1.这里就举例array={1,2,3,4,5}的全排列;首先根据字典的排序以小到大,将整个问题分解为子集合解决(整个感觉有点像树的结果,根分到叶子),我们现在要先固定第一位,然后变成了array1={2,3,4,5}的全排列,然后就一直进行分解直到array2={3,4,5}(固定前两位),array3={4,5}(固定前三位),array4={5}(固定前四位),到这时这里的第一次全排列,就分解到只有一个数的子集合,就算一种情况; 2.接下来就返回到上一种情况,也就是array3的子集合,因为刚刚只是排了最后一个子集合(array4),所以array3子集合就要变成{5,4},这里算一种,到这里array3的所有可能已经完了,再接下来会回到上一个集合array2的可能{3,4,5},{3,5,4}都已经排过了,所以3开头就不能要了,就会变成array2={4,3,5},再把这个array2进行分解子集合再排,然后就是一直延续下去,排完整个大的集合。 这里就只介绍这几种方法: 1.回溯法 2. 字典序法 3. 邻位对换法 一、回溯法 “回溯”指的是“状态重置”,可以理解为“恢复现场”,是在编码的过程中,是为了节约空间而使用的,而在递归或者深度优先中根据需要的场合来配合回溯法可以进一步对自己的代码进行优化。 回溯的基本模板 #include<iostream> #include<algorithm> using namespace std; const int N=10; bool st[N];//用来判断1~n这n个数是否被选。true代表已经被选了,false反之 int p[N];//用来记录1~n个位置选的是哪个数 int n; void dfs(int u){ if(u>n){//当n个位置都确定之后就打印 for(int i=1;i<=n;i++){ cout<<p[i]<<" "; } cout<<endl; return; } for(int i=1;i<=n;i++){//第u个位置开始选数 if(!st[i]){//如果这个数没有被选 st[i]=true;//选择这个数打上标记 p[u]=i;//记录 dfs(u+1);//开始枚举下一个位置 st[i]=false;//恢复现场 } } } int main() { cin>>n; dfs(1);//从第一个位置开始遍历 return 0; } 二、字典序法 首先字典序法在数学中就是字典或词典顺序(也称为词汇顺序,字典顺序,字母顺序或词典顺序)是基于字母顺序排列的单词按字母顺序排列的方法 这也就是前面所解释说明的那样,以数组 [1, 2, 3] 的全排列为例。 以 1 开头的全排列为[1, 2, 3], [1, 3, 2];

进程管道:popen函数实例

基础知识 可能最简单的在两个程序之间传递数据的方法就是使用popen和pclose函数了。它们的原型如下所示: #include <stdio.h> FILE *popen(const char *command, const char *type); int pclose(FILE *stream); 1.popen函数 popen函数允许一个程序将另一个程序作为新进程来启动,并可以传递数据给它或者通过它接收数据。command字符串是要运行的程序名和相应的参数。open_mode必须是"r"或者"w"。 如果open_mode是"r",被调用程序的输出就可以被调用程序使用,调用程序利用popen函数返回的FILE*文件流指针,就可以通过常用的stdio库函数(如fread)来读取被调用程序的输出。如果open_mode是"w",调用程序就可以用fwrite调用向被调用程序发送数据,而被调用程序可以在自己的标准输入上读取这些数据。被调用的程序通常不会意识到自己正在从另一个进程读取数据,它只是在标准输入流上读取数据,然后做出相应的操作。 每个popen调用都必须指定"r"或"w",在popen函数的标准实现中不支持任何其他选项。这意味着我们不能调用另一个程序并同时对它进行读写操作。popen函数在失败时返回一个空指针。如果想通过管道实现双向通信,最普通的解决方法是使用两个管道,每个管道负责一个方向的数据流。 2.pclose函数 用popen启动的进程结束时,我们可以用pclose函数关闭与之关联的文件流。pclose调用只在popen启动的进程结束后才返回。如果调用pclose时它仍在运行,pclose调用将等待该进程的结束。 pclose调用的返回值通常是它所关闭的文件流所在进程的退出码。如果调用进程在调用pclose之前执行了一个wait语句,被调用进程的退出状态就会丢失,因为被调用进程已结束。此时,pclose将返回-1并设置errno为ECHILD。 实验 读取外部程序的输出 现在来看一个简单的popen和pclose示例程序popen1.c。我们将在程序中用popen访问uname命令给出的信息。命令uname -a的作用是打印系统信息,包括计算机型号、操作系统名称、版本和发行号,以及计算机的网络名。 完成程序的初始化工作后,打开一个连接到uname命令的管道,把管道设置为可读方式并让read_fp指向该命令的输出。最后,关闭read_fp指向的管道。 测试代码: #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #define DEBUG_INFO(format, ...) printf("%s - %d - %s :: "format"\n",__FILE__,__LINE__,__func__ ,##__VA_ARGS__) void test_01(void){ FILE *read_fp; char buf[BUFSIZ + 1]; memset(buf, 0, sizeof(buf)); DEBUG_INFO("BUFSIZ = %d",BUFSIZ); read_fp = popen("uname -a","r"); if(read_fp == NULL){ perror("popen:"); return; } int len = fread(buf,1,BUFSIZ,read_fp); if(len <= 0){ perror("

局域网电脑共享问题, 收藏这一篇教程就够了!!

我以window10为例,其它系统大同小异。为了方便解释,后续称本机为需要设置共享内容的电脑,外机为访问共享电脑的电脑 1.网络设置 右键单击任务栏右下角网络图标,打开网络internet设置 单击属性, 进入网络配置详情,选择一种网络;这里我们选择专用网络,不需要用到GUEST账户。 公用网络:可能会影响后续文件共享,需要GUEST账户; 专用网络:权限较大,所有本机电脑账户都可以远程访问共享内容 往下拉,记住你本机的ip地址。返回上一页面,找到更改高级共享设置 启用网络发现:勾选后局域网中所有计算机可以发现这台计算机 启用文件和打印机共享:一定要勾选,否则不能共享文件和打印机 这里我们两个都勾选上,这三种网络方式设置大同小异; 来宾或公用网络即设置通过GUEST账户访问的权限,所有网络代表上面两种网络方式都生 效; 2.共享配置 右键单击你要共享的磁盘或者文件,选择属性,切换到共享选项卡 进入高级共享,勾选共享此文件夹,设置一个共享名,接着点击权限 为此共享添加一个everyone用户权限,此账户默认为管理所有共享时用户权限。 接着选中此账户,勾选需要的权限(此权限关系到外机的访问权限),设置完成后点应用和确定。 接下来切换到安全选项卡,同样添加一个everyone账户的权限。此时本机共享已经配置完毕,局域网中的所有计算机都可以通过本机计算机上的账户和密码登录访问此计算机上的共享文件和共享的打印机。 3.外机访问 两种方式访问: 1.通过 文件夹上方输入地址 2. 通过运行窗口输入共享电脑的IP地址,快捷键win+R打开运行窗口,输入地址。 不出意外就会弹出登录界面要求你输入电脑账户的用户名,当然指的是你要连接的电脑的账户和密码,如果不弹出登录窗口,有可能是默认以GUEST用户进行了登录,下面是解决办法: 打开电脑的凭据设置,可以在控制面板中找到。切换成小图标显示,找到凭据管理器 下拉找到对应的ip,我电脑没有登录过共享,所以没有保存有就不演示了,找到后删除,或者直接修改成你要登录的用户名和密码即可。然后重复步骤3即可。

Mybatis批量插入的四种方式

Mybatis批量插入的四种方式 一、循环插入 public void insert(List<User> userList) { userList.forEach(user -> userDao.insert(user)); } <insert id="insert"> INSERT INTO `demo`.`user` (`username`, `address`, `remark`, `age`, `create_time`) VALUES (#{user.username,jdbcType=VARCHAR}, #{user.address,jdbcType=VARCHAR}, #{user.remark,jdbcType=VARCHAR}, #{user.age,jdbcType=INTEGER}, now()) </insert> 二、批量插入 这里是否选择100个为一组还是200或者其他,需要进行多次测试 public void insertBatch(List<User> userList) { List<List<User>> partition = ListUtil.partition(userList, 100); for (List<User> users : partition) { userDao.insertBatch(users); } } <insert id="insertBatch"> INSERT INTO `demo`.`user` (`username`, `address`, `remark`, `age`, `create_time`) VALUES <foreach collection="users" index="" item="user" separator=","> (#{user.username,jdbcType=VARCHAR}, #{user.address,jdbcType=VARCHAR}, #{user.remark,jdbcType=VARCHAR}, #{user.age,jdbcType=INTEGER}, now()) </foreach> </insert> 三、BatchExecutor插入 mybatis提供了三种sql执行器,分别是SIMPLE(默认),REUSE,BATCH:

Rust {:?} vs {} 知多少

Rust {:?} vs {} 知多少 {} 指示符 {} 需要实现std::fmt::Display {:?} 指示符 {:?} 需要实现std::fmt::Debug 案例展示 struct Rectangle { width: u32, height: u32, } fn main() { let rect1 = Rectangle { width: 30, height: 50, }; println!("rect1 is {}", rect1); } 编译报错: error[E0277]: `Rectangle` doesn't implement `std::fmt::Display` 提示我们没有实现Display trait 改成如下代码: fn main() { let rect1 = Rectangle { width: 30, height: 50, }; println!("rect1 is {:?}", rect1); } 编译报错: error[E0277]: `Rectangle` doesn't implement `Debug` 提示没有实现Debug trait

Rust单元测试实战

Rust 单元测试实战 本文基于rust edition 2021 版本,介绍Rust Test用例编写及测试用例的运行。 Rust Test编写格式 /// 配置只有在test 模式下才生效 #[cfg(test)] mod tests { /// 添加Test 注解 #[test] /// 定义测试函数,用来测试被测试的函数 fn it_works() { let result = 2 + 2; assert_eq!(result, 4); } } 项目目录结构 创建一个test项目 cargo new example 运行成功后,目录结构如下: 编写sum 函数和自定义Rectangle结构体并提供can_hold函数 fn main() { println!("Hello, world!"); println!("{}",sum(2, 3)); let rec = Rectangle{width:1,height:2}; let rec1 = Rectangle{width:2,height:2}; println!("{}",rec.can_hold(&rec1)); } fn sum( a :i32,b :i32) -> i32{ a+b } #[derive(Debug)] struct Rectangle { width: u32, height: u32, } impl Rectangle { fn can_hold(&self, other: &Rectangle) -> bool { self.

Java多线程之synchronized(转载)

以前有些疑问或是关注不到的,这里提供了一些参考。主要看文字部分,自己做实验 最基本的synchronized Method的使用 packagecom.jadyer.thread.sync; /** * SynchronizedMethodTest * * @see=================================================================================================== * @see概述:Java中的每个对象都有一个锁(lock)或者叫做监视器(monitor) * @see说明:当synchronized关键字修饰一个方法时,则该方法为同步方法 * @see当某个线程访问某个对象的synchronized方法时,则表示将该对象上锁 * @see此时其它的任何线程,均无法访问该对象中的任何一个synchronized方法(但允许访问该对象中的非synchronized方法) * @see直到该线程所访问的synchronized方法执行完毕(或者抛出了异常)之后,该对象的锁才会被释放 * @see此时其它的任何线程,才被允许访问该synchronized方法,或者是该对象中的其它synchronized方法 * @see=================================================================================================== * @see总结:如果一个对象有多个synchronized方法,某一时刻某个线程已经执行了该对象中的某一个synchronized方法 * @see那么在该方法没有执行完毕之前,其它线程是无法访问该对象中的,包括该方法在内的,任何一个synchronized方法 * @see重点在于判断Synchronized锁的是谁。如果该方法是静态的,则锁Class对象,否则锁的就是当前对象 * @see=================================================================================================== * @see补充:1)这只是针对多个线程操作同一个类的同一个对象的情况。www.linuxidc.com若多个线程操作同一个类的不同对象,则不存在这种情况 * @see2)Java中的volatile变量也可以看作是一种"程度较轻的synchronized" * @see关于volatile的更多信息,请参考http://www.ibm.com/developerworks/cn/java/j-jtp06197.html * @see备注:实际项目中,用到的更多的还是JDK5.0开始推出的Java并发包,即java.util.concurrent包里面的工具类 * @seejava.util.concurrent可以非常细粒度的实现并发。比如线程访问到了一个已被锁的对象,它可以让这个线程等到10秒 * @see10秒后如果该对象仍未被解锁,那么就可以返回给用户超时的提示等,而如果使用synchronized则是无法这么精确控制的 * @see=================================================================================================== * @see注意:1)当synchronized方法执行完或者发生异常时,会自动释放锁 * @see2)被synchronized保护的数据应该是private的,否则也就没必要去通过方法来访问这个public的数据了 * @see=================================================================================================== * @author宏宇 * @createFeb21,20125:29:39PM */ public class SynchronizedTest { public static void main(String[] args) { Bank bank = new Bank(); Thread tt11 = new Thread(new ThreadRMB(bank)); //new一个新的Bank对象。此时存在两个Bank对象,并且它们属于同一个类的不同的对象 //如要验证多个线程操作同一个类的不同的对象的synchronized方法,只需取消注释该行代码即可 //bank=newBank(); Thread tt22 = new Thread(new ThreadDollar(bank)); tt11.

在unity中通过两个操纵点控制物体的位移,旋转和缩放

1. 场景 中创建一个不均匀的方块。 然后创建小球。 我需要通过控制小球的相对位置来让方块跟随旋转。 不过这样的话如果小球是随意移动,物体也会在三个轴进行旋转。我想让它旋转的时候只沿着角度变化比较大的轴进行旋转。 这样控制的话,会。。。稳一些吧。。。 因为假设实在手势交互中,两个小球是通过两个手控制,会很随意,,从而让旋转很乱。 这样贴近主要的旋转轴向进行旋转,我只要多旋转几次,就能保证准确度。 2.如图,通过调整2的位置,让中间的方块角度随着 1和2的相对角度变化而变化。 实现代码如下 public Transform Point01; public Transform Point02; public Transform Traget; private Quaternion _orgRotation; private Vector3 _orgPosition; private Vector3 _orgPoint01; private Vector3 _orgPoint02; void Start() { _orgRotation = Traget.rotation; _orgPosition = Traget.position; _orgPoint01 = Point01.position; _orgPoint02 = Point02.position; } void Update() { Vector3 direction = Point02.position - Point01.position; Vector3 orgDirection = _orgPoint02 - _orgPoint01; Vector3 normal = Vector3.Cross(orgDirection, direction).normalized; normal = CalculateZeroedVector(normal); Vector3 plane_direction01 = Vector3.

对象锁(Object lock)

对象锁(Object lock)是一种多线程编程中用于保护共享对象的同步机制。在并发编程中,多个线程可能同时访问共享对象,如果不采取任何措施来保护对象的一致性,可能会导致数据竞争和不确定的结果。 对象锁通过在对象上设置锁,限制同时只有一个线程可以获取该锁,从而实现对对象的互斥访问。当一个线程获取到对象的锁之后,其他线程就需要等待,直到持有锁的线程释放锁为止。 在Java中,对象锁可以通过synchronized关键字来实现。当一个方法或者一段代码块被synchronized修饰时,它就成为了一个临界区,同一时间只能有一个线程进入临界区执行,其他线程需要等待。 在上面的例子中,increment()和getCount()方法都被Synchronized修饰,这意味着同一时间只能有一个线程执行这些方法。这样可以确保对count变量的操作是线程安全的,避免了数据竞争。 除了使用synchronized关键字,还可以使用ReentrantLock类来实现对象锁。ReentrantLock提供了更灵活的锁定机制,允许更复杂的锁定和释放操作。 总结来说,对象锁是一种用于保护共享对象的同步机制,通过限制同时访问对象的线程数量来确保线程安全。在Java中,可以使用synchronized关键字或ReentrantLock类来实现对象锁。

vue3+ts 路由基本设置 router 下新建index.ts

import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router' import { getToken } from '@/utils/auth' const routes: RouteRecordRaw[] = [ { path: '/', name: 'Index', component: () => import('@/pages/index.vue') // 注意这里要带上 文件后缀.vue }, { path: '/index', name: 'Index', component: () => import('@/pages/index.vue') // 注意这里要带上 文件后缀.vue }, { path: '/login', name: 'Login', component: () => import('@/pages/login.vue') // 注意这里要带上 文件后缀.vue }, { name: 'nofound', path: "/:nofound(.*)*", redirect: '/index' } ] const router = createRouter({ history: createWebHistory(), routes, }) // 设置导航守卫 有token 直接进入首页或指定的页面(无法进入登录页面) router.

四大常用JSON解析器完成对象转换的案例

1. JSON基本格式: 博客中很多优秀的介绍JSON格式下面博客的介绍是我认为是比较完整地: 传送门: json基本数据格式 2. JSON解析器介绍: JSON解析器通常包含两个主要功能:解析和生成。解析功能将JSON字符串解析为内存中的数据结构,通常是对象、数组或键值对的集合。生成功能则将内存中的数据结构转换为JSON字符串。 许多编程语言都提供了内置的JSON解析器和生成器,可以轻松地处理JSON数据。例如,JavaScript中的JSON.parse()函数用于解析JSON字符串,将其转换为JavaScript对象;JSON.stringify()函数用于将JavaScript对象转换为JSON字符串。其他编程语言如Python、Java、C#等也提供了类似的功能。 使用JSON解析器,可以方便地在不同的应用程序之间传递和处理数据,特别适用于Web应用程序和客户端-服务器通信。无论是从网络接收JSON数据,还是将数据发送到远程服务器,JSON解析器都是必不可少的工具。 3. 常用JSON的解析器: 1. Jackson: Jackson是一个非常流行的JSON处理库,提供了高性能和灵活的JSON解析和生成功能。它可以将JSON数据映射到Java对象中,并将Java对象转换为JSON格式。Jackson还支持注解,可以用于进一步控制JSON与Java对象之间的映射关系。 首先,您需要在您的Java项目中添加Jackson库的依赖。如果使用Maven进行项目管理, 可以在pom.xml文件中添加以下依赖项: <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.12.3</version> </dependency> 接下来,假设您有一个JSON字符串如下: { "name": "John Doe", "age": 30, "email": "johndoe@example.com" } 现在,让我们看一下如何使用Jackson将该JSON字符串解析为Java对象,并将Java对象转换回JSON字符串: import com.fasterxml.jackson.databind.ObjectMapper; public class JsonExample { public static void main(String[] args) { String json = "{\"name\":\"John Doe\",\"age\":30,\"email\":\"johndoe@example.com\"}"; try { // 创建ObjectMapper对象 ObjectMapper objectMapper = new ObjectMapper(); // 解析JSON字符串为Java对象 Person person = objectMapper.readValue(json, Person.class); System.out.println("Name: " + person.

UE C++ json 使用

Json String to Json Object FString jsonstr="{'id':'xx','arr':[{'no':0}]}"; TSharedRef<TJsonReader<>> JsonReader = TJsonReaderFactory<>::Create(jsonstr); TSharedPtr<FJsonObject> rRoot; if (FJsonSerializer::Deserialize(JsonReader, rRoot)) { TArray<TSharedPtr<FJsonValue>> arr = rRoot->GetArrayField("arr"); for (auto i:arr) { TSharedPtr<FJsonObject> iObj = i->AsObject(); int32 no = iObj->GetNumberField("no"); } } JsonArr add Item TSharedPtr<FJsonObject> jsonObject = MakeShareable(new FJsonObject); TArray<TSharedPtr<FJsonValue>> jsondataArr; TSharedPtr<FJsonObject> jsonData = MakeShareable(new FJsonObject); jsonData->SetStringField(TEXT("name"), TEXT("xxx")); jsondataArr.Add(MakeShareable(new FJsonValueObject(jsonData))); jsonObject->SetArrayField(TEXT("arr"), jsondataArr); UStruct to Json String USTRUCT() struct FEntityInfoItemStruct { GENERATED_USTRUCT_BODY() FEntityInfoItemStruct() {}; FEntityInfoItemStruct(FString _id, FString _type, float _lat, float _lng) :EntityInfoItemId(_id), EntityInfoItemType(_type), EntityInfoItemLat(_lat), EntityInfoItemLng(_lng) {}; UPROPERTY() FString EntityInfoItemId; UPROPERTY() FString EntityInfoItemType; UPROPERTY() float EntityInfoItemLat; UPROPERTY() float EntityInfoItemLng; }; USTRUCT() struct FEntityInfoStruct { GENERATED_USTRUCT_BODY() UPROPERTY() FString action; UPROPERTY() TArray<FEntityInfoItemStruct> data; FString ToString() { FString OutStr; FJsonObjectConverter::UStructToJsonObjectString(*this, OutStr, 0, 0); return OutStr; } }; FString converstr_ustruct2jsonstr; FEntityInfoStruct tempEntityInfo; tempEntityInfo.

linux常用查看服务器内存的命令

1.free free 命令用来显示系统内存状态,包括系统物理内存、虚拟内存(swap 交换分区)、共享内存和系统缓存的使用情况,其输出和 top 命令的内存部分非常相似。 free 命令的基本格式如下: [root@localhost ~]# free [选项] 表 1 罗列出了此命令常用的选项及各自的含义。 表 1 free 命令常用选项及含义 选项含义-b以 Byte(字节)为单位,显示内存使用情况。-k以 KB 为单位,显示内存使用情况,此选项是 free 命令的默认选项。-m以 MB 为单位,显示内存使用情况。-g以 GB 为单位,显示内存使用情况。-t在输出的最终结果中,输出内存和 swap 分区的总量。-o不显示系统缓冲区这一列。-s 间隔秒数根据指定的间隔时间,持续显示内存使用情况。 free查看内存大小--执行free -m free -m 以 MB 为单位,显示内存使用情况。 free 命令用来显示系统内存状态,包括系统物理内存、虚拟内存(swap 交换分区)、共享内存和系统缓存的使用情况,其输出和 top 命令的内存部分非常相似。 free -m命令输出列表中,第一行显示的是各个列的列表头信息,各自的含义如下所示: total 是总内存数; used 是已经使用的内存数; free 是空闲的内存数; shared 是多个进程共享的内存总数; buffers 是缓冲内存数; cached 是缓存内存数。 Mem 一行指的是内存的使用情况;-/buffers/cache 的内存数,相当于第一行的 used-buffers-cached。+/buffers/cache 的内存数,相当于第一行的 free+buffers+cached;Swap 一行指的就是 swap 分区的使用情况。 2.df df命令功能:显示指定磁盘文件的使用情况。如果没有指定文件,则显示所有挂载的文件系统的磁盘使用情况

count(1)、count(*)、count(id)、count(name)区别

count(1)、count(*)、count(id)、count(name)区别 经过执行计划可以看到,四种执行后查询的行数是一样的(至少在mysql5.7及以后是一样的) 硬要 说区别 字段有索引的话,count(字段)>count(id):因为字段有索引的话,它会走字段索引,就是二级索引 count(*):会统计值为null的行 count(列名):不会统计列为null值的行

Redis(一)常见命令使用

常见文件名Redis-cli使用命令1、启动Redis2、连接Redis3、停止Redis4、发送命令1、redis-cli带参数运行,如:2、redis-cli不带参数运行,如: 5、测试连通性 key操作命令获取所有键查询键是否存在删除键查询键类型移动键查询key的生命周期(秒)设置过期时间设置永不过期更改键名称 字符串操作命令存放键值获取键值值递增/递减批量存放键值获取获取键值获取值长度追加内容获取部分字符 集合操作命令存储值获取元素判断集合是否存在元素获取集合元素个数删除集合元素弹出元素有序集合和列表的区别:存储值获取元素分数获取排名范围排名语法:zrange key start stop [WITHSCORES]获取指定分数范围排名语法:zrangebyscore key min max [WITHSCORES] [LIMIT offset count]增加指定元素分数获取集合元素个数获取指定范围分数个数删除指定元素获取元素排名 列表操作命令存储值左端存值语法:lpush key value [value ...]右端存值语法:rpush key value [value ...]索引存值语法:lset key index value 弹出元素左端弹出语法:lpop key右端弹出语法:rpop key获取元素个数获取列表元素 散列操作命令存放键值获取字段值获取所有键与值语法:hgetall key获取所有字段语法:hkeys key获取所有值语法:hvals key判断字段是否存在获取字段数量递增/减删除字段 常见文件名 Redis-cli使用命令 1、启动Redis > redis-server [--port 6379] 如果命令参数过多,建议通过配置文件来启动Redis。 > redis-server [xx/xx/redis.conf] 6379是Redis默认端口号。 2、连接Redis > ./redis-cli [-h 127.0.0.1 -p 6379] 3、停止Redis > redis-cli shutdown > kill redis-pid 以上两条停止Redis命令效果一样。 4、发送命令 给Redis发送命令有两种方式: 1、redis-cli带参数运行,如: > redis-cli shutdown not connected> 这样默认是发送到本地的6379端口。

如何用easyExcel的实现导出以及实现多线程分页数据导出

1.先看一下普通写法 public class ExcelExport { public static void main(String[] args) { // 输出文件路径 String filePath = "D:/demo.xlsx"; // Sheet名称 String sheetName = "Sheet1"; // 写入数据的Sheet编号 int writeSheet = 0; // 写入数据的Table编号 int writeTable = 0; // 创建ExcelWriter对象 ExcelWriter excelWriter = EasyExcel.write(filePath, DemoData.class).sheet(sheetName).build(); // 准备数据源 List<DemoData> data = new ArrayList<>(); for (int i = 0; i < 1000000; i++) { DemoData demoData = new DemoData(); demoData.setId(i); demoData.setName("name" + i); data.add(demoData); } // 将数据写入Excel文件中 excelWriter.

window Cmake开发环境搭建

背景 最近的项目需要从linux转战至Windows。因为之前的项目都是在linux环境下开发的,代码也是通过CMAKE编译。攻欲善其事,必先利其器。首先要考虑的是如何在Windows环境下使用cmake编译代码。 另外一个就是IDE的选择了,相比于动辄 好几个G的Visual Studio来说,vscode 的安装以及多种功能强大的插件,所以还是还是选择它(只是因为习惯了。。。)。 现将过程记录如下,有需要的小伙伴可以参考。 cmake下载 CMake下载地址,这里我们选择 win-x86,下载完双击打开(注意:1.安装的时候选择中间的 for all user;2. 勾选add into path 加入环境变量)。 进入cmd终端,输入 cmake --verison 出现版本号即安装成功。默认安装路径:C:\Program Files\CMake\bin MinGW-w64安装 MinGW,是Minimalist GNU for Windows的缩写。它是一个可自由使用和自由发布的Windows特定头文件和使用GNU工具集导入库的集合,允许你在GNU/Linux和Windows平台生成本地的Windows程序而不需要第三方C运行时库。——来自百度百科 因为 MinGW-w64 可以编译生成 64位 或 32位 可执行程序,而 MinGW 只能编译生成32位可执行程序,现在已经很少用了。 MinGW-w64下载地址,进去后往下拉,当前最新版本是GCC-8.1.0,下载后解压,添加环境变量:系统->高级系统设置->环境变量->系统环境变量->新建 将自己解压后的路径添加进去即可,注意路径尽可能不要有中文。 进入cmd终端,输入 cmake --verison 出现版本号即安装成功,如果没有检查环境变量与自己解压的位置。 vscode插件安装 c++ 、 CMake、CMake Tools 代码测试 目录结构: hello.h #ifndef __HELLO_H__ #define __HELLO_H__ #define HELLO "hello, world!" #endif // __HELLO_H__ main.cpp #include <iostream> #include "../include/hello.h" using namespace std; int main(void) { cout << "

iptables filter表

filter表 控制数据包是否允许进出及转发 支持的链 INPUT:处理来自外部的数据FORWARD :将数据转发到本机的其他网卡设备上OUTPUT:处理向外发送的数据 动作 ACCETP:允许DROP:阻止,不返回icmpREJECT:拒绝,返回icmp 默认策略 所有策略没有匹配上,最后走的默认策略动作 默认策略如果是ACCEPT,就是所谓的黑名单,通常都是做白名单,默认策略位DROP 实验1: iptables -P INPUT DROP iptables -P OUTPUT ACCEPT #配置默认策略 iptables -t filter -A INPUT -p tcp -s 192.168.10.19 --dport 22 -j ACCEPT #配置白名单,放行源地址为192.168.10.19,目标端口22 iptables -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT #OUTPUT主动出去的数据包,默认在INPUT被丢弃,需要通过扩展模块state跟踪nf_conntrack 实验2: docker转发规则 net.ipv4.ip_forward=1 #/etc/sysctl.conf 需要开启内核转发 iptables -R FORWARD 5 -i docker ! -o docker -j DROP #修改docker的转发规则,测试docker网络 测试结果:不通了 查看命令: iptables -t filter -nvL --line-numbers

三维点云处理(三)——Kenerl PCA

文章目录 前言1.1 关于Kernel PCA1.2 用法总结1.3 Kernel PCA实例总结 前言 上一章节说明的基础PCA主成分分析的基本原理,这种PCA主要适用于线性关系的数据点,在原理里包含的矩阵乘法实际上也是线性操作。数据中矩阵乘一个向量就是对矩阵的列的线性组合。如果我们遇到数据不是线性的情况下怎么办呢? 1.1 关于Kernel PCA 如上图所示的 一批点,如果给他做线性PCA时无法区分开红色和绿色的点,也就达不到聚类的效果,所以在解决非线性相关的数据时,我们应该用升维的方法 。比方说将上图里的数据点,我们将其放置于一个平面上,再从三维空间的角度将平面折叠起来成一个圆锥的话,就可以很好的将红点和绿点区分开来。这时候做一个普通的PCA就可以进行聚类了。 于是我们引出了kernel PCA的概念,他的步骤就是将原来n₀维度的数据给提升成n₁,得到一个函数ɸ,将中心值变为0,计算其矩阵H的相关矩阵,加上波浪线之后和原来的矩阵区分开,下一步解他们的特征值和特征向量,下面就引申出来两个问题: 如何去选择升维函数ɸ?如果避免升维过高而产生的过高算力,以节省运算资源。 由此我们得到了kernel PCA的方法。证明如下: 将Hz=λz代入,得到结论: 得到如下的式子,通过Kα = λα替换进去,代表αr应该有一个1/λr的长度,得到一个仍然含有ɸ的式子,我们最终目标是要去掉ɸ,在后续的变换中,将所有的ɸ都变换为核函数k,只需要定义一个核函数k即可。之前我们假设了高维空间的中心点为0,需要进行一个Normalization。 最后将所有的变换回到核函数上去: 这里有很多核函数形式,还包括高斯和拉普拉斯分布等,通常会通过数据实验来评估使用效果。 1.2 用法总结 将所有的数据点投影到主向量上去,由此得到投影后的系数yr。 1.3 Kernel PCA实例 图一为三个不同数据点组成的圆,我们选取一个简单的二次多项式的核函数,就可以计算出不同的主成分,将原来的数据投影到主向量上面,x轴为第一个主向量,y轴为第一个主向量。就已经可以将数据明显区分开来。 再使用高斯核函数来验证一下: 横轴为第一个主成分,竖轴为第二个主成分,此时已经可以区分开不同数据点这就是高维空间以及核PCA的用法。 总结 从PCA引入到kernel PCA,主要是通过使用核函数来对数据进行升维来达成聚类效果。而核PCA的中心思想就是将高维空间的运算转换成低维空间的核函数。

redis集群选举机制简介高可用性与主备切换原理(经典)

redis cluster的高可用的原理,跟redis replication sentinel类似,过程如下 1、判断节点宕机 ​ 如果一个节点认为另外一个节点宕机,那么就是pfail,主观宕机。如果多个节点都认为另外一个节点宕机了,那么就是fail,客观宕机,跟哨兵的原理几乎一样,pfail对应sdown,fail对应odown 。 ​ 在cluster-node-timeout内,某个节点一直没有返回pong,那么就被认为pfail,如果一个节点认为某个节点pfail了,那么会在gossip ping消息中,ping给其他节点,如果超过半数的节点都认为pfail了,那么就会变成fail。 2、从节点过滤 ​ 对宕机的master node,在其所有的slave node中,选择一个切换成master node,检查每个slave node与master node断开连接的时间,如果超过了cluster-node-timeout * cluster-slave-validity-factor,那么就没有资格切换成master,这个也是跟哨兵是一样的,从节点超时过滤的步骤。 3、从节点选举 对slave进行排序,排序方法如下: slave priority:选择优先级slave-priority最大的从节点作为主节点,如不存在则继续。 按照slave优先级进行排序,slave priority越低,优先级就越高。replica offset:选择复制偏移量(数据写入量的字节,记录写了多少数据。主服务器会把偏移量同步给从服务器,当主从的偏移量一致,则数据是完全同步)最大的从节点作为主节点,如不存在则继续。如果slave priority相同,那么看replica offset,哪个slave复制了越多的数据,offset越靠后,优先级就越高。run id:如果上面两个条件都相同,那么选择一个run id比较小的那个slave。(redis每次启动的时候生成随机的runid作为redis的标识) ​ 所有的master node开始slave选举投票,给要进行选举的slave进行投票,如果大部分master node(N/2 + 1)都投票给了某个从节点,那么选举通过,那个从节点可以切换成master。从节点执行主备切换,成为主节点 来源:redis集群选举机制简介 – 源码巴士 

基于MATLAB的人脸识别系统(包含传统/深度学习方法)

基于MATLAB GUI的人脸识别系统(包含传统/深度学习方法) 人脸检测与识别作为计算机视觉研究的核心内容之一,是一个不断发展的领域,并且还是模式识别、机器学习和数据挖掘等相关学科交叉研究的热点,已经发展成为计算智能的重要研究课题。本文是作者人脸识别系统V1.0,基于MATLAB平台,主要实现人脸识别功能,包含3种人脸识别算法,PCA-最近邻、PCA-SVM、以及深度学习的方法,都在ORL数据集上取得了较高的识别率。 00目录 1 应用背景 2 研究历程 3 ORL数据库介绍 4 人脸识别算法 5 系统实现 6 展望 01 应用背景 人脸识别技术就是以计算机为辅助手段,从静态图像或动态图像中识别人脸。问题一般可以描述为给定一个场景的静态或视频图像,利用已经存储的人脸数据库确认场景中的一个或多个人。一般来说,人脸识别研究一般分为3个部分:从具有复杂背景的场景中检测并分离出人脸所在的区域;抽取人脸识别特征;然后进行匹配和识别。 虽然人类从复杂背景中识别出人脸相当容易,但人脸的自动机器识别却是一个极具挑战性的课题。它跨越了模式识别,图像处理、计算机视觉以及神经生理学、心理学等诸多研究领域。 如同人的指纹一样,人脸也具有唯一性,可用来鉴别一个人的身份,人脸识别技术在商业、法律和其他领域有着广泛的应用。 02 研究历程 60 年代末,Chan 等人[1]发表了自动人脸识别(Automated Face Recognition,AFR)研究技术报告,以人脸特征点的间距、比率等作为特征,建成了一个人脸识别系统。以此为时间点,越来越多的学者致力于人脸识别的研究。 第一个阶段,是上世纪 60 年代到 90 年代。这一阶段的人脸识别研究主要是集中于人工设计的特征提取方法,典型的有基于几何特征和基于局部模式的方法。提取人脸几何特征,需要手动标定面部的一些特征点,如眼角、嘴角、鼻尖等部位,并对各特征点的距离进行归一化,刻画出人脸的关键轮廓,例如局部二值模式LBP。这类方法抗干扰能力不好,当采集到的人脸图像有些许偏移则识别失败。 第二个阶段,研究者们认为人工设计的特征提取方法过于单一,往往只能在约束条件下取得较好的结果,于是这一阶段出现了大量基于特征学习的方法。这类方法是从数据中学习种特征提取模型,只要训练数据和测试数据分布一致,就能取得非常高的识别精度,根据这类方法的学习模型是否为深度模型, 又可细分为深度特征学习(如深度卷积神经网络)和浅层特征学习(如PCA算法)。[2] 3 ORL数据库介绍 ORL人脸数据集 http://www.datatang.com/data/13501 共包含40个不同人的400张图像,是在1992年4月至1994年4月期间由英国剑桥的Olivetti研究实验室创建。 此数据集下包含40个目录,每个目录下有10张图像,每个目录表示一个不同的人。所有的图像是以PGM格式存储,每个图像都是是92x112x1像素、256级的灰度图。对每一个目录下的图像,这些图像是在不同的时间、不同的光照、不同的面部表情(睁眼/闭眼,微笑/不微笑)和面部细节(戴眼镜/不戴眼镜)环境下采集的。所有的图像是在较暗的均匀背景下拍摄的,拍摄的是正脸(有些带有略微的侧偏)。ORL人脸库部分图像如下: 4 人脸识别算法 4.1 基于PCA-最近邻的人脸识别算法 4.1.1 主成分分析PCA PCA法是模式识别中的一种行之有效的特征提取方法。在人脸识别研究中,可以将该方法用于人脸图像的特征提取。 一个mn 的二维脸部图片将其按列首尾相连,可以看成是mn的一个一维向量。ORL人脸数据库中每张人脸图像大小是92×112,它可以看成是一个10304维的向量,也可以看成是一个10304维空间中一点。图像映射到这个巨大的空间后,由于人脸的构造相对来说比较接近,因此可以用一个相应的低维子空间来表示。我们把这个子空间叫做“脸空间”,我们对ORL数据库进行降维得到的特征脸如下: PCA的主要思想就是找到能够最好地说明图像在图像空间中的分布情况的那些向量,这些向量能够定义“脸空间”。 每个向量的长度为mn,描述一张mn的图像,并且是原始脸部图像的一个线性组合,称为“特征脸”。对于一副mn 的人脸图像,将其每列相连构成一个大小为D= mn维的列向量。D就是人脸图像的维数,也即图像空间的维数。设N是训练样本的数目;x,表示第j幅人脸图像形成的人脸向量;u为训练样本的平均图像向量,则所需样本的协方差矩阵为 根据K-L变换原理,需要求得的新坐标系由矩阵AAT的非零特征值所对应的特征向量组成。直接计算的计算量比较大,所以采用奇异值分解(SVD)定理,来求解AAT的特征值和特征向量。依据SVD定理,令l.(i= 1 ,2,…,r)为矩阵AAT的r个非零特征值,v为AAT对应于4;的特征向量。由于特征值越大,与之对应的特征向量对图像识别的贡献越大,为此将特征值按大小排列,依照式; 选取前p个特征值对应的特征向量,构成降维后的特征脸子空间。则AA^T的正交归一特征向量u,为 特征脸空间为 将训练样本y投影到“特征脸”空间W,得到一组投影向量Y =W^T y,构成人脸识别的训练样本数据库。 4.1.2 最近邻算法 m 维 空间中两点之间的实际距离,即是求两点间向量的 自然长度,即点到原点的距离。在三维空间以及二维空间中的距离就是空间两点之间的实际距离。将最近邻看作信号的相似程度,距离越短说明信号越相似。最近邻的计算公式为: 两幅图像之间的距离反映了图像的相似性,距离越近,图像的相似度越高。最近邻在数字图像处理中有着广泛的应用。将图像最近邻应 用于传统人脸识别算法,能提高人脸识别算法的效率。

利用Python爬虫,查询12306车次信息

效果展示: 分析目标网站: 进入12306官网以商丘南到汝州为例,在点击查询后会跳转到查询结果的网站 右键点检查或审查元素,在弹出的控制台中点网络或network,如果没有显示数据的话,刷新一下网页就有了;在点击Fetch/XHR后会发现有一个名为query...的请求,点开它后再点击预览会发现,车票的信息就在这个里面 4. 在找到存放的车票信息后,按常理直接对目标链接发送请求即可,但我们通过查看URL携带的参数时,不难发现: - 第一个参数:查询的日期,固定格式(YYYY-MM-DD) - 第二个和第三个参数:不同城市对应的英文代码 - 第四个参数:固定值 获取所有城市英文代码: 这里不在过多叙述,找到URL链接直接发送请求,获取响应的数据即可,代码如下: url = "https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9053" print("正在获取数据。") # 发送请求,获取返回的数据 res = requests.get(url) data = str(res.content, encoding="utf8") print(data) 通过返回的数据可以发现,所有的数据都是以|符号隔开的,所以使用split("|")对数据进行处理,代码如下: dict_data = dict() # 根据'|'分隔数据 list_data = data.split('|') # 从下标'1'开始, 每间隔5个为字典key result_x = list_data[1:len(list_data):5] # 从下标'2'开始, 每间隔5个为字典value result_y = list_data[2:len(list_data):5] # 循环将数据写入字典 for i in range(len(result_x)): dict_data[result_x[i].replace(" ", "")] = result_y[i] print(dict_data) 将数据提取后保存到工作路径的data文件夹下,这样后期使用时,就无需再次对该网站发送请求了,代码如下: json_data = json.dumps(dict_data, indent=1, ensure_ascii=False) with open("./data/city_data.json", 'w') as w: w.

TPS波动较大问题排查

现象 接口TPS在160左右无法上升 排查 9-27排查 让测试重新压测。 通过线程繁忙查询,基本为如下 可以看到大多数线程为Druid连接池进入等待取连接状态。 Druid线程池问题 根据源码查看,定位到此方法主要根据maxWait的值来设置等待时间。 下面进行arthas链路追踪 可以看出,maxWaitMills使用了默认值 -1 (即:maxWait的默认值,即如果连接池没有空闲连接,获取连接的线程则会一直等待下去。) 后续就是漫长的配置查询之路 项目是通过spring.datasource.type=com.alibaba.druid.pool.DruidDataSource引入druid连接池,通过这种方式引入配置文件中的其他属性是无法自动注入。要使该配置生效,需要使用javaBean的方式配置。 @Configurationpublic class DruidConfig { @Bean // 将所有前缀为spring.datasource下的配置项都加载DataSource中 @ConfigurationProperties(prefix = "spring.datasource") public DataSource druidDataSource() { return new DruidDataSource(); } } 重新压测 修改代码后进行重新压测。 可以看到性能提高了10倍。 但是目前仍然存在问题,性能存在不稳定性 9-28排查 让测试重新压测。 使用arthas profile导出cpu的火焰图。 分别是4种数据库查询的场景。 火焰图显示主此方法中主要占用cpu的为这4个sql查询(其他都是正常的链路)。 排查数据库 通过了解得知,此服务是通过连接mycat代理mysql。 让测试直接压测mycat(其地址和现在排查服务地址一致)。 发现性能真好 排除mycat/mysql的问题 接口详细分析 通过对其中一个查询进行tt分析。 tt -t class名字 -n 次数 tt -i 详细的值 可以看出在某个时间下,他会出现耗时由几毫秒变成几百毫秒的场景。 得出结论:数据库查询不稳定,需要认真定位 通过arthas trace查询超过100ms的请求 trace 包名 方法名 -n 10 ‘#cost > 100’

ThreeJS 炫酷特效旋转多面体Web页 Demo 01《ThreeJS 炫酷特效制作》

本案例为一个 threejs 的特效网页,大小球体进行包裹,外球体为透明材质,但是进行了线框渲染,使其能够通过外球踢查看其内球体。 注:案例参考源于互联网,在此做代码解释,侵删 本案例除 ThreeJS 外不适用任何第三方框架,放心食用 懒的同学可以直接下载代码,打赏作者一根精神食粮:https://download.csdn.net/download/A757291228/87871503 这是 inscode 的代码,不过渲染有点问题,不过也可以看到大致效果: 一、ThreeJS 三要素 在编写 ThreeJS 前,需要明白 ThreeJS 的三个要素,若对建模、游戏有过了解的同学在学习 ThreeJS 时对知识点理解会更容易接受。 在 ThreeJS 中有三个很关键的对象,分别是 摄像头、场景以及渲染器: 其中 场景 是通过 ThreeJS “搭建”呈现特效的一个“舞台”,创建好一个场景后,即可往这个场景中添加对应的多种物体,例如多边形、粒子、球体等;创建好场景后我们需要在场景中添加摄像头用于呈现场景中的视觉效果,摄像头在 ThreeJS 中担任 “视觉采集” 角色,可以通过控制摄像头采集范围(大小)从而采集场景中视觉呈现;那么完成以上两步后,还需要对场景进行渲染,只有渲染过后才能进行视觉效果的呈现。 可以想象场景为一个场地,摄像头为一个摄像头,渲染器就是渲染器,然后拍成了一段视频或照片。 二、代码中创建三要素 2.1 创建 html 首先创建一个 html 文件,并且引入 CSS 与 JS 文件: <!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>1_bit ThreeJS 炫酷旋转多面体Web页 Demo</title> <link rel="stylesheet" href="./style.css"> </head> <body> <div id="

用idea创建vue文件

我只会一种方法就是: 1:win+q打开搜索框,输入cmd打开控制命令提示符 2:然后打开我的vue文件想要创建的地方,比如我的文件想建立在D盘/课程学习/课程设计里面。于是在cmd里面输入命令行: cd D: cd 课程学习 cd 课程设计 执行过程如图: 3:创建vue文件语句:vue create practice practice是我的文件名 此行语句之后等待一会会出现如下界面,选择Manually select features并提交 按上面的选择并提交。之后系统就会自动创建vue文件practice。 显示如图即创建成功 然后在idea中file->open->d/课程学习/课程设计 即可·

基于SpringBoot+Vue的酒店管理系统设计与实现

博主介绍: 大家好,我是一名在Java圈混迹十余年的程序员,精通Java编程语言,同时也熟练掌握微信小程序、Python和Android等技术,能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架下进行项目开发,具有丰富的项目经验和开发技能。我的代码风格规范、优美、易读性强,同时也注重性能优化、代码重构等方面的实践和经验总结。 我有丰富的成品Java毕设项目经验,能够为学生提供各类个性化的开题框架和实际运作方案。同时我也提供相关的学习资料、程序开发、技术解答、代码讲解、文档报告等专业服务。 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇🏻 不然下次找不到哟 Java项目精品实战案例(300套) 酒店管理系统源码下载地址: https://download.csdn.net/download/weixin_54828627/87775463 一、前言介绍 21世纪的今天,随着社会的不断发展与进步,人们对于信息科学化的认识,已由低层次向高层次发展,由原来的感性认识向理性认识提高,管理工作的重要性已逐渐被人们所认识,科学化的管理,使信息存储达到准确、快速、完善,并能提高工作管理效率,促进其发展。 论文主要是对酒店管理系统进行了介绍,包括研究的现状,还有涉及的开发背景,然后还对系统的设计目标进行了论述,还有系统的需求,以及整个的设计方案,对系统的设计以及实现,也都论述的比较细致,最后对酒店管理系统进行了一些具体测试。 二、主要技术 技术名作用SpringBoot后端框架Vue前端框架MySQL数据库 三、系统设计 3.1、主要功能模块设计 : 本项目是以java为开发技术,采用了B/S的结构,同时,也使用springboot框架技术在动态页面上进行了设计,后台上采用Mysql数据库,实现了一个酒店管理系统。酒店管理系统的主要使用者分为管理员、用户;用户:首页、个人中心、客房预订管理、入住登记管理、服务费用管理、退房登记管理、我的收藏管理。管理员:首页、个人中心、用户管理、客房类型管理、客房服务管理、客房信息管理、客房预订管理、入住登记管理、服务费用管理、退房登记管理、系统管理等功能。通过这些功能模块的设计,基本上实现了整个酒店信息管理的过程。 3.2、用户登录流程设计 四、功能截图 4.1、系统功能模块 酒店管理系统,在系统首页可以查看首页、客房服务、客房信息、酒店公告、个人中心、后台管理等内容进行操作,如图所示。 图4-1系统首页界面图 4.1.1、用户注册 图4-2用户注册界面图 4.1.2、个人中心 图4-3个人中心界面图 4.1.3、客房服务 图4-4客房服务界面图 4.1.4、客房信息 图4-5客房信息界面图 4.2、管理员功能模块 管理员登录,通过填写注册时输入的用户名、密码、选择角色进行登录,如图所示。 图4-6管理员登录界面图 管理员登录进入系统可以查看首页、个人中心、用户管理、客房类型管理、客房服务管理、客房信息管理、客房预订管理、入住登记管理、服务费用管理、退房登记管理、系统管理等信息进行详细操作,如图示。 图4-7管理员功能界面图 4.2.1、用户管理 图4-8用户管理界面图 4.2.2、客房类型管理 图4-9客房类型管理界面图 4.2.3、客房服务管理 图4-10客房服务管理界面图 4.2.4、客房信息管理 图4-11客房信息管理界面图 4.2.5、客房预订管理 图4-12客房预订管理界面图 4.2.6、入住登记管理 图4-13入住登记管理界面图 4.2.7、服务费用管理 图4-14服务费用管理界面图 4.2.8、退房登记管理 图5-15退房登记管理界面图 4.2.9、系统管理 图4-16系统管理界面图 4.3、用户后台功能模块 用户登录进入系统后台可以查看首页、个人中心、客房预订管理、入住登记管理、服务费用管理、退房登记管理、我的收藏管理等内容进行详细操作,如图5-17所示。 图4-17用户后台功能界面图 4.3.1、个人中心 图4-18个人中心界面图 4.3.2、客房预订管理 图4-19客房预订管理界面图 4.3.3、我的收藏管理 图4-20我的收藏管理界面图 五、数据设计 在该系统的信息中,由于数据库的支持,我们可以对数据库进行收集、整理、更新和加工等操作。由于数据库的存储功能强大,所以数据库已经成为了计算机必不可少的一部分,一个数据库的好坏直接影响该系统的质量和效率。一个系统中的数据库是必不可少的,并且起着决定性因素。通过之前的系统分析,可以规划出本系统中使用的主要等,下面设计出这几个关键实体的实体关系图: 本系统部分的E-R图如下图所示: 1、客房信息管理实体图如图所示:

零基础学Python,最受推荐的10本Python书籍

目录 适合初学者的最佳Python书籍1、《Python编程:从入门到实践》2、《Head-First Python (2nd edition)》3、《“笨方法”学Python》4、《Python程序设计(第3版)》 最适合初学者的免费Python书籍5、《像计算机科学家一样思考Python (第2版)》6、《A Byte of Python》 适合中高级程序员的Python书籍7、《Python Cookbook(第3版)中文版》8、《Python机器学习基础教程》9、《流畅的Python》10、《Programming Python》 Python是一种通用的解释型编程,主要用于Web开发、机器学习和复杂数据分析。Python对初学者来说是一种完美的语言,因为它易于学习和理解,随着这种语言的普及,Python程序员的机会也越来越大。 如果你想学习Python编程,市场上就有很多的书籍。这些是目前最受编程社区成员推荐的Python书,该列表还包括一些为初学者准备的免费Python书籍。 适合初学者的最佳Python书籍 1、《Python编程:从入门到实践》 埃里克·马瑟斯的这本《Python编程:从入门到实践》是一本快速,全面的Python语言入门教程,适合初学者,他们希望学习Python编程并能够编写出有用的程序。本书旨在让读者快速上手编写真正的程序。本书也适用于对语言有模糊理解并希望在尝试Python编程之前了解其知识的程序员。在学习本书时,你将学习使用Numpy和matplotlib等库和工具,并使用数据创建令人惊叹的可视化效果。你还将了解2D游戏和Web应用程序背后的思想以及如何创建它们。 这本560页长的书主要分为两部分。本书的第一部分讨论了Python编程的基础知识,并阐述了字典,列表,循环和类等概念,在此部分你将了解Python程序的工作原理,并学习如何编写干净且可读的代码来创建交互式程序,第一部分最后讲解的主题是关于测试代码。本书的第二部分遵循实用的方法,通过使用Python的库实现三个不同的项目,街机游戏,简单的Web应用程序和数据可视化,帮助你检验通过这本书你都学到了什么。 2、《Head-First Python (2nd edition)》 如果你想要学习Python编程的基础知识,并且不想要看一堆乏味难懂的书籍和教程。那么Paul Barry的《Head First Python》就是你的不二之选,它将帮助你快速掌握Python编程的基础知识,并使用内置函数和数据结构。然后,本书将帮助你构建自己的Web应用程序,异常处理,数据争论和其他概念。 作者是Paul Barry,是一位讲师。在进入学术界之前,他在IT行业工作了十多年。他是许多著名编程书籍的作者。 3、《“笨方法”学Python》 这本书结构很简单,是52个习题的集合。你必须认真阅读这些习题的代码并准确输入,然后你还得修复代码中的Bug,以便更好地理解并观察程序的运行情况。在这个过程中,你将了解软件是如何工作的,好的程序看起来是什么样子,怎样阅读、编写、思考代码,以及如何用专业程序员的技巧来找出并修正错误。 本书通过帮助你安装完整的Python环境开始,接着教你如何编写优化的代码。然后,本书讨论了基础数学,变量,字符串,文件,循环,程序设计和数据结构等主题。本书非常适合想通过语言的核心来学习Python编程的初学者。作者是Zed A. Shaw,他是Hard Way系列的创建者,该系列包括有关C,Python和Ruby编程语言的书籍。 4、《Python程序设计(第3版)》 John Zelle的《Python程序设计》,与其把它当做Python编程的代码介绍,不如把它当做是一本关于编程艺术的介绍,这本书将向你介绍计算机科学、编程以及其他相关的概念,只是使用Python语言作为初学者的媒介,本书以最适合初学者的方式讨论,因此书中的概念是非常有趣并易于理解 第三版中最显著的变化就是几乎删除了所有python eval()库的使用,并增加了一个讨论其缺点的部分,最新版本还使用了新的图形示例。 最适合初学者的免费Python书籍 5、《像计算机科学家一样思考Python (第2版)》 本书按照培养读者像计算机科学家一样的思维方式的思路来教授Python语言编程。作者从最基本的编程概念开始讲起,包括语言的语法和语义,而且每个编程概念都有清晰的定义,引领读者循序渐进地学习变量、表达式、语句、函数和数据结构。此外,书中还探讨了如何处理文件和数据库,如何理解对象、方法和面向对象编程,如何使用调试技巧来修正语法、运行时和语义错误。 本书是遵循GUN自由文档许可,可以被免费下载和打印,已经被翻译成西班牙语、意大利语、德语、捷克语、中文等。 6、《A Byte of Python》 这是另外一本关于Python的免费书籍,本书主要讨论Python 3版本,这本书有超过26种语言可供选择,包括土耳其语、瑞典语、法语、汉语、德语、西班牙语、俄语、乌克兰语、葡萄牙语和朝鲜语。这些翻译是由活跃的社区成员提供的。 这本书首先介绍了这本书是关于什么的,然后介绍Python以及它如何成为编程世界中最强大的语言之一。然后介绍Python概念,并在每个示例的步骤中详细讲解。在阅读完本书之后,你还需要继续深入学习Python。 适合中高级程序员的Python书籍 7、《Python Cookbook(第3版)中文版》 《Python Cookbook(第3版)中文版》旨在帮助你掌握Python 3中的编程技巧,对于那些想要采用现代工具和用法,而不仅仅是标准编码的有经验的Python程序员来说,这本书包含了大量用Python 3.3测试过的代码。本书提供了各种主题的完整代码,包括Python语言及其用途,以及大量应用程序领域的常见示例。 8、《Python机器学习基础教程》 许多商业应用和项目都将机器学习作为其不可或缺的组成部分,而这类的应用程序多年来一直在增加。Sarah Guido和Andreas C. Muller的这本书将教你如何使用Python编程语言来构建自己的机器学习解决方案。 在本书中,你将了解使用Python和scikit-learn库创建丰富的机器学习应用程序所需的步骤。向你介绍机器学习的基本概念和用法,然后再介绍流行的机器学习算法的优缺点。然后,你还将了解交叉验证和网格搜索;管道的概念;如何将前面各章的方法应用到文本数据上,以及介绍了一些文本特有的处理方法。总之,本书将提供能够帮助你提高数据科学技能的一切建议。 9、《流畅的Python》 本书将帮助你学习如何使用该语言最被忽视但最好的特性来编写有效的Python代码。作者将带你了解该语言的特性和库,并帮助你使代码更短、更快和可读。 本书涵盖了各种概念,包括python数据模型、数据结构、把函数视作对象、面向对象习惯用法、控制流程和元编程。通过这本书,高级Python程序员将了解Python 3以及如何精通该语言版本。

vue3自定义指令——元素平滑移动

vue提供一个用户可以高度自定义的指令入口directives 利用这个入口我们实现一个常见的元素平滑移动的自定义指令 ‘sl’ 首先我们结合指令创建一个多元素的界面: 这个场景我们在很多网站,商城都有见过,特别对于移动端的清单类界面 我们的终极目标是在滚动的过程中出现在视口的元素移动,而并不是所有的元素都在移动 平滑移动 有了目标之后我们就可以分解一下我们codeing的过程, 创建一个基础的指令选则一个合适的方式去建立一个高效的运行动画如何获取到进入视口的元素找到视口元素并让它移动 s1创建一个基础的指令文件 //移动的距离 const DISTANCE : number = 150; const derDve = { mounted(el:any){ el.style.transform=`translateY(${DISTANCE}px)` } } export default derDve s2指令内容根据分解的需求变更 指令使用的过程不应影响到原始元素的属性特征 el.style 方式会导致元素原有的样式出现变更指令的使用应该具有兼容性和高效的复用价值 动画方式创建一个平滑指令 const derDve = { mounted(el:any){ //动画方式创建 const animation = el.animate([ { transform:`translateY(${DISTANCE}px)`, opacity:0.5 }, { transform:'translateY(0)', opacity:1 } ], { duration:DURATION, easing:'ease' } ); //初始状态下动画应该是停止状态 animation.pause(); }, } export default derDve s3一个好用的视口元素检测WebAPI IntersectionObserver IntersectionObserver 一个浏览器自带的用于检测元素与视口是否有交集的api 接收两个参数,[callback,option] 详细配置可自行百度 有了这个api之后我们就可以对上述指令再次进行修改

HTTP协议报文格式和Fiddler4用法

路漫漫其修远兮,吾将上下而求索 文章目录 目录 一、Fiddler4的使用 二、HTTP请求 1.首行 2.header 3.空行 4.body 三、HTTP响应 1.首行 2.header 3.空行 4.body 三、HTTP请求详解 首行 HTTP方法 POST方法和GET方法的区别 URL:唯一资源定位符 报头header header的属性 body(正文) 四、HTTP响应详解 首行:​编辑 常见的状态码: 五、构造HTTP请求 1.使用form表单构造HTTP请求 2.使用ajax构造请求 3.使用Postman构造HTTP请求 一、Fiddler4的使用 使用抓包工具Fiddler抓取HTTP的请求或者响应 抓包工具相当于一个代理 可以看到网上传输的具体数据 使用前需要我们进行一些设置 我们从官网下载好之后打开Fiddler 1.打开HTTPS 点击设置 选择HTTPS 勾选选项后点击OK OK之后 会弹出对话框 让你选择是否安装根证书 一定要选择一直是 安装根证书 可能出现的问题: 1.没有勾选HTTPS 没有安装根证书 会导致一些包抓不到 2.Fiddler作为一个代理 可能会和电脑上的其他代理冲突 设置完之后就可以正式抓包了 因为电脑是在上网的 所以会抓到很多网络包 我们为了方便观察 可以全选 delete删除之前抓到包 然后我们打开浏览器 输入百度的官网 实现一次访问 此时我们看Fiddler 找到蓝色的(黑色的是响应的普通数据 蓝色是HTML) body较长的 域名和自己访问的一样的包 此时就抓到了这个包 可以点击查看一个完整的HTTP请求 二、HTTP请求 一个HTTP请求包含了四个部分 1.首行 2.

【gmsh源码阅读】源码阅读环境设置

我的gmsh源码阅读环境是VS Code + Remote SSH配置的。gmsh的编译都在Ubuntu Server上完成的,本地Windows上VSCode阅读代码及调试。 1. 在Server上编译gmsh,按代码仓中README操作即可: mkdir build cd build cmake .. make 2. 本地Windows配置Remote SSH 3. 配置.vscode/launch.json文件,内容如下: { "version": "0.2.0", "configurations": [ { "name": "C/C++: g++ build and debug active file", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/build/gmsh", "args": ["../tutorials/t1.geo"], "stopAtEntry": false, "cwd": "${workspaceFolder}/build", "environment": [], "externalConsole": false, "MIMode": "gdb", "miDebuggerPath": "/usr/bin/gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true } ] } ] } 做完以上配置本地即可debug了。

【Pytest实战】解决ModuleNotFoundError: No module named ‘pytest’问题

😄作者简介: 小曾同学.com,一个致力于测试开发的博主⛽️,主要职责:测试开发、CI/CD 如果文章知识点有错误的地方,还请大家指正,让我们一起学习,一起进步。😊 座右铭:不想当开发的测试,不是一个好测试✌️。 如果感觉博主的文章还不错的话,还请点赞、收藏哦!👍 在上一篇文章给大家分享了 Pytest的运行方式,其中提到了主函数运行方式,我是直接右击选择指定的文件运行,可是在控制台显示报错。 可能有小伙伴也遇到了类似的问题,我明明已经安装了 pytest 怎么会显示 No module named 'pytest’ /font>呢? ➜ ~ pytest --version pytest 7.3.0 出现这个问题,大概率是你Python环境变量的问题, 我用的IDE是VSCode,如果如何在VSCode中解决 ModuleNotFoundError: No module named 'pytest’ 问题 第一步:使用快捷键 command+shift+p 选择 Python:Select Interpreterer 第二步:选择对应的python路径即可解决。 此时再重新右击文件,即可成功运行。 写在后面 在本系列教程会带小伙伴们从入门Pytest到精通Pytest,如果有需要补充的内容,欢迎小伙伴留言评论哦,还请小伙伴持续关注,让我们共同进步,早日成为测试架构师 。如果你想获取更多免费资料,也可以关注下方公众号,给小编留言。

【redis-初级】redis安装

文章目录 1.非关系型数据库(NoSQL)2.在Linux上安装redis2.1 安装前准备2.2 安装2.3 启动2.4 关闭 3. redis客户端3.1 命令客户端3.2redis远程客户端3.3 redis编程客户端 1.非关系型数据库(NoSQL) 2.在Linux上安装redis 2.1 安装前准备 (1)使用Xftp将安装包上传到Linux服务器上的/root。 在Xshell中查看: 2.2 安装 (1)解压到 /usr/local tar -zxvf redis-3.2.9.tar.gz -C /usr/local (2)查看解压结果 (3)进入reids-3.2.9 (4)安装gcc yum install gcc -y (5)查看gcc安装成功 which gcc (6)编译 make (7)进入src查看编译生成的文件 2.3 启动 ./redis-server 后台启动 ./redis-server & 后台启动并输出日志 nohup ./redis-server & 2.4 关闭 ./redis-cli shutdown 查看redis进程 ps -ef | grep redis 3. redis客户端 3.1 命令客户端 ./redis-cli -h 127.0.0.1 -p 6379 3.2redis远程客户端 Redis Desktop Manager 需要做一些配置

如何使用Java进行单元测试?

Java中的单元测试通常使用JUnit框架来实现。JUnit是一个开源的Java测试框架,它能够帮助开发者快速编写和运行单元测试。下面是一个简单的单元测试示例: import org.junit.Test; import static org.junit.Assert.assertEquals; public class MyTest { @Test public void testAddition() { int result = Calculator.add(1, 2); assertEquals(3, result); } @Test public void testSubtraction() { int result = Calculator.subtract(5, 2); assertEquals(3, result); } } 在以上示例中,我们定义了一个名为MyTest的测试类,其中包含两个测试方法testAddition和testSubtraction。这两个方法分别对Calculator类中的add和subtract方法进行测试。其中,assertEquals方法用于比较两个数值是否相等,如果不相等,则抛出一个AssertionError异常。 当我们运行这个测试类时,JUnit框架会自动执行其中的测试方法,并给出测试结果报告。如果所有测试都通过,则该测试类通过,反之则测试失败。通过单元测试可以提高程序的可靠性和代码的质量,同时也可以缩小代码调试的范围,帮助程序员更好地维护代码。

Google benchmark在 linux、windows下安装使用

Google benchmark 的源码GIT地址: https://github.com/google/benchmark Google benchmark的功能应该是知道的而且官网或者其他网站都可以找到,下面只是介绍一下在我们在编译源码以及链接源码静态库的时候的一些问题的总结。 近日因为项目需要找到Google benchmark在三个平台 嵌入式linux(ARM64)、linux(x86_64) 、windows (x64)下 来测试日志库 log4cplus以及spdlog 的性能对比。 一、linux(x86_64)平台下 使用benchmark 1、linux下编译Google benchmark 就按照git源码的readme,使用cmake 编译源码即可。 摘录 readme 关键步骤 # Check out the library. $ git clone https://github.com/google/benchmark.git # Go to the library root directory $ cd benchmark # Make a build directory to place the build output. $ cmake -E make_directory "build"# Generate build system files with cmake, and download any dependencies. $ cmake -E chdir "

头歌educoder-旅游网站大数据分析 - 数据清洗

第1关:清洗HTML文档中无意义数据 package step1; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.safety.Whitelist; public class Task { //通过filePath文件路径获取Docment对象 public Document getDoc(String filePath) throws IOException{ /********** Begin **********/ File input = new File(filePath); Document doc = Jsoup.parse(input,"UTF-8","http://www.educoder.net/"); return doc; /********** End **********/ } /** * 获取清理后的信息 * @param doc * @return */ public List<String> cleanHTML(Document doc){ /********** Begin **********/ List<String> list=new ArrayList<>(); list.add(Jsoup.clean(doc.toString(), Whitelist.basic())); list.add(Jsoup.clean(doc.toString(), Whitelist.simpleText())); return list; /********** End **********/ } } 第2关:获取携程网北京市的所有酒店信息 package step2; import java.

VS Code 下载安装以及非常好用的插件

VS Code 安装文档 给他家也准备好了安装包:快捷直达 一、下载 进入VS Code官网:地址直达,点击 DownLoad for Windows下载windows版本 当然也可以点击旁边的箭头,下载Windows版本 或 Mac OS 版本 Stable:稳定版Insiders:内测版 二、安装 双击安装包,选择我同意此协议,再点击下一步 选择安装路径,点击下一步 。也可以使用默认值: C:\Users\super\AppData\Local\Programs\Microsoft VS Code 继续点击下一步 可以勾选创建桌面快捷方式,如果不想使用vscode作为代码默认打开方式,可以取消将code注册为受支持的文件类型的编辑器,点击下一步 点击安装,开始安装 安装完成,运行VS Code。 三、VS Code插件安装 VS Code提供了非常丰富的插件功能,根据你的需要,安装对应的插件可以大大提高开发效率。 完成前端开发,常见插件介绍: 1、Chinese (Simplified) Language Pack 适用于 VS Code 的中文(简体)语言包 2、Code Spell Checker 拼写检查器。比如 banana 单词写错成 banane ,会提示你是否修改成 banana ,也可以将 banane 添加至检查器的字典中。 3、HTML CSS Support 在编写样式表的时候,自动补全功能大大缩减了编写时间。 4、JavaScript (ES6) code snippets 支持ES6语法提示 5、Mithril Emmet 一个能大幅度提高前端开发效率的一个工具,用于补全代码 6、Path Intellisense 路径提示插件 7、Vue 3 Snippets 在 Vue 2 或者 Vue 3 开发中提供代码片段,语法高亮和格式化的 VS Code 插件,能极大提高你的开发效率。

CentOS7安装docker

设置yum源 curl -o /etc/yum.repos.d/CentOS-Base.repo https://repo.huaweicloud.com/repository/conf/CentOS-7-reg.repo 清除原有yum缓存 yum clean all 查看所有配置可以使用的文件,会自动刷新缓存 yum repolist all 下载repo文件 wget -O /etc/yum.repos.d/docker-ce.repo https://repo.huaweicloud.com/docker-ce/linux/centos/docker-ce.repo 替换软件仓库地址 sudo sed -i 's+download.docker.com+repo.huaweicloud.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo 更新索引文件 sudo yum makecache fast 安装 sudo yum install docker-ce 设置开机自启 systemctl enable docker 开启Docker服务 sudo service docker start

企业微信建设代开发应用的基本流程及实现

一、企业微信代开发应用的基本流程 企业微信中除了系统提供的应用以及上架应用商店的第三方应用外,也可以使用自己开发的应用,不过多数企业都不具备开发能力,只能采用代开发的形式进行定制。就给大家分享一下企业微信代开发应用的基本流程,为大家定制应用提供参考。 1.1什么是代开发应用 如我方是科技服务公司A,有一家公司B,B提出想在自己的企业微信工作台上,上线一个xxx功能,但是B公司没有自己的研发人员去实现完成,且也没有服务器去支撑。所以找到了A。A通过自己家的企业微信,创建一个模板,让B的管理员扫码授权后,A的研发人员可以在模板下开发应用,提交上线到B的企业微信中。这就是代开发应用。 微信官方的解释:当前第三方服务商为企业代开发自建应用时,需要线下获取企业的各类密钥数据,流程复杂、管理成本高且权限获取有安全合规风险。为了帮助服务商更加高效地、安全地为企业提供应用代开发服务,企业微信新增自建应用代开发模式,即:企业可通过扫码授权的方式,授权第三方服务商代开发自建应用。 官网:https://work.weixin.qq.com/ 1.2代开发流程 二、开发过程 2.1 创建代开发模板 首先需要开发公司创建代开发应用模板,填写代开发模板的名称、介绍、Logo、分类行业等信息,填写该代开发模板的回调 URL、Token、加密key等信息并提交申请。 点击下一步 配置回调接口 注意:这个回调接口,需同时支持POST请求,GET请求!!!! 如果是服务端是Java 参考如下Controller层代码: 这个模板回调接口是干什么的?主要的意义如下: 官方介绍 2.2 创建代开发模板 完成模板创建后,点击模板查看会看见一个二维码,发给客户企业微信的管理员进行扫码授权,企业客户扫码后会有如下的提示: 授权以后,我方的模板下会展示该客户企业: 点击进行代开应用的配置,配置基本信息、回调URL,主页等。 此时。当前应用中也有一个回调URL,这个url也要支持POST、GET请求,在这个URL里,对微信发送来的消息进行校验。授权后,服务商将收到授权成功的回调通知,通过解密可以得到该企业对应于该代开发模板的临时授权码 auth_code。 通过临时授权码与以上步骤得到的代开发应用凭证 suite_access_token 作为参数,调用代开发授权应用secret的获取接口,便能获得企业对于该代开发模板的代开发授权应用secret 、corpid、agentid。之后开发公司即可将这些信息配置到应用开发中,为企业客户代开发应用。 2.3 提交上线 一定要选择代开发应用模板下的代开发应用!这一步不要选错。确定以后,微信端审核,大约一两分钟时间,会显示提交上线的按钮出来,点击提交上线,完成微信代开发应用的建设。 三、注意事项 以上只是微信代建应用的流程,契合到项目中,要考虑把微信中的openid与当前项目体系中的用户进行关联映射的绑定。比如我们的页面其实是在APP登陆后 才能进入的一个工作台,在其中就要涉及到用户角色权限的问题。做法就是通过企业微信的开发接口获取当前用户信息,在关联映射表中找出对应的用户,而后再进行一个模拟登录生成Token,将token再放入请求头中去访问我的业务功能。 /** * provied by zym * 0 error(s), 0 warning(s) */

React + Antd实现动态切换主题功能之二(默认主题与暗黑色主题切换)

前言 ps. 文中方案仅适用于antd 4.x,不适用于最新的antd 5.x,如需要适用于antd 5.x版本的方案,请移步至:https://blog.csdn.net/m0_58016522/article/details/131168634 在前一篇文章中(https://blog.csdn.net/m0_58016522/article/details/121751043)初略的讲解了通过ConfigProvider全局化配置prefixCls的方式来动态切换部分主题样式配置,文章中只是通过修改部分颜色(如primary颜色)来初步展示了效果,可能效果不甚理想。 对于实际项目开发中,其中有一类需求比较多的就是动态切换默认(亮色)主题与暗黑色主题,在ant-design官网有一个官方的demo可以参考:https://github.com/gzgogo/antd-theme 。下面我通过一个小demo,来展示一下默认主题与暗黑色主题切换功能的开发步骤。 实现思路 首先我的思路还是通过ConfigProvider全局化配置prefixCls的方式来修改ant design样式的prefix,即默认主题通过类名前缀custom-default来控制样式,而暗色主题通过类名前缀custom-dark来控制样式。 1. 编译默认主题css文件 # 指定prefix为custom-default # 源文件为antd.less $ lessc --js --modify-var="ant-prefix=custom-default" node_modules/antd/dist/antd.less custom-default.css 按照上述步骤的命令会生成一个custom-default.css的文件,该文件为默认主题的样式文件,在该文件内容中有一段如下样式: body { margin: 0; color: rgba(0, 0, 0, 0.85); font-size: 14px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; font-variant: tabular-nums; line-height: 1.5715; background-color: #fff; font-feature-settings: 'tnum'; } 这段内容主要是控制body区块的样式,我们将这段样式做如下修改

【Linux】解决Linux无法联网的一个小问题

今天使用在虚拟机VMware中使用Linux系统(Centos7)的时候,发现不能联网,找了很多办法也没有解决,甚至重新安装也没有解决,后来想起之前的解决方案。 要在任务管理器中打开,VMware的网络管理。

Colyseus 常见错误

报错原因解决errno: -4058 spawn git ENOENT找不到Git命令安装Git/配置Git路径XXX has been blocked by CORS policyhttp请求试图调用https资源/本地试图访问网络资源/Arena上传代码后没有部署/在已连接服务器的情况下重复连接/服务器地址写错统一使用https/配置跨域访问政策文件/Arena上传代码后记得点击'deploy' /避免重复连接服务器/修正服务器地址SyntaxError: Unexpected token '.'NodeJS版本太旧升级NodeJSMissingMethodException: Default constructor not found引擎代码被删减尝试关闭 code strippingTypeError: Cannot assign to read only property 'map' of object '#<QueryCursor>'NodeJS版本太旧升级NodeJSError: missing serializer客户端/服务器版本不一致统一SDK到当前版本Error: seat reservation expired客户端与服务器版本不匹配/客户端未实例化或数量过大/redis驱动不匹配/matchAPI无法正常工作/服务器URL端口不对或者是URL后多打了一个"/"升级客户端/等待客户端完成实例化/升级服务端容量/升级redis驱动/更正URLClass constructor Room cannot be invoked without 'new'Typescript编译版本过低配置Typescript编译目标 "es2015" 或更高Type 'number[]' is missing the following properties from type 'ArraySchema<number>'schema类型写错ArraySchema<number>的类型是number[]ERROR in XXX.d.ts ... XXX expectedTypescript版本过低升级Typescript: npm install --save-dev typescript@latestnpm ERR! Could not resolve XXXnpm命令执行错误重新安装相关依赖模块net::ERR_SSL_PROTOCOL_ERROR使用了ip地址进行SSL连接改用https://domain进行连接TypeError: Cannot read properties of undefined (reading 'prototype')依赖库版本不匹配尝试运行 npm update 命令Right-hand side of 'instanceof' is not callableschema类型写错检测并修复schemaIPC timed out.

IP地址介绍及运算方法

目录 一、IP地址 二、IP地址分类 1.IP公有地址 2.IP私有地址 三、子网划分 1.定义 2.划分的原理 3.计算方法 4.网段划分 一、IP地址 IP 地址是互联网协议特有的一种地址,它是 IP 协议提供的一种统一的地址格式,为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。 IP地址分为IPV4和IPV6两类。 IPV4由32位二进制数组成,一般用 点分十进制数。例:192.168.1.123 IPV4地址主要由两部分组成。IPV4=网络部分(NETWORK)+主机部分(HOST)。 IPV6由128位二进制数组成,一般用冒号分隔,十六进制表示。如1030::C9B4:FF12:48AA:1A2B 二、IP地址分类 IP地址类型分为公有地址和私有地址,公有地址就是分配给公共网络可以直接访问互联网的地址。. 私有地址就是属于非注册地址,可以给每个组织机构内部使用,我们经常公司网络组网,网络摄像机,交换机路由器配置都是用的私有地址。 1.IP公有地址 公有地址(Public address,也可称为公网地址)由Internet NIC(Internet Network Information Center因特网信息中心)负责。这些IP地址分配给注册并向Internet NIC提出申请的组织机构。通过它直接访问因特网,它是广域网范畴内的。 为了方便IP地址的管理及组网,IP地址分成五类: A1.0.0.1-126.255.255.254B128.0.0.1-191.255.255.254C192.0.0.1-223.255.255.254D224.0.0.1-239.255.255.254E240.0.0.1-255.255.255.254 A类地址:1.0.0.1~126.255.255.254 A类地址IP=网络部分+主机部分+主机部分+主机部分 例:100.168.0.2 网络部分为100.168.0 主机部分为2 其中1.0.0.0 是网络地址;126.255.255.255 是广播地址 默认子网掩码:/8,即255.0.0.0 B类地址:128.0.0.1~191.255.255.254 B类地址IP=网络部分+网络部分+主机部分+主机部分 默认子网掩码:/16,即255.255.0.0 128.0.0.0是网络地址,191.255.255.255是广播地址 C类地址:192.0.0.1~223.255.255.254 C类地址IP=网络部分+网络部分+网络部分+主机部分 默认子网掩码:/24,即255.255.255.0 192.0.0.0是网络地址,223.255.255.255是广播地址 D类地址:224.0.0.1~239.255.255.254 D类地址IP主要用于组播通信的地址。 E类地址:240.0.0.1~255.255.255.254 E类地址IP主要用于科学研究的保留地址。 以127开头的IP地址都代表本机。(广播地址127.255.255.255除外),其中127.0.0.1是主机回环地址。 169.254.0.0~169.254.255.255 是DHCP服务失效时分配的地址。 2.IP私有地址 私有地址(Private address,也可称为专网地址)属于非注册地址,专门为组织机构内部使用,它是局域网范畴内的,出了所在局域网是无法访问因特网的。 私有IP地址的范围: A类私有IP地址: 10.0.0.0~10.255.255.255 默认子网掩码:/8 B类私有IP地址: 172.16.0.0~172.31.255.255 默认子网掩码:/12C类私有IP地址: 192.168.0.0~192.168.255.255 默认子网掩码:/16 三、子网划分 1.

java案例6:学生投票系统

思路: 学生投票系统 实现投票程序,班级总人数100,每人一票 投票成功提示“已成功投票,感谢您的支持” 重复投票提示“请勿重复投票” 当投票总数达到100或者主观结束投票时,同时统计投票学生人数和投票结果 1.学生类Voter 姓名 最大投票数 当前投票数 投票意见 2.票次数,静态成员变量,private static int count 保证数据只有一份 3.防止学生重复投票,必须保存参与投票的学生信息,可采用一个集合来存放已经投票的学生对象。 private static Set<Voter>voters = new HashSet<Voter>(); 4.编写测试类 代码: 代码结构: 测试类: public class Test06 { public static void main(String[] args) { Voter v1 = new Voter("周自珩"); Voter v2 = new Voter("夏习清"); Voter v3 = new Voter("shoogy"); v1.voterFor("同意"); v1.voterFor("反对"); v2.voterFor("反对"); v3.voterFor("同意"); v1.printResult(); // v2.printResult(); // v3.printResult(); } } 学生类Voter: package base.base006; /* 1.学生类Voter 姓名 name 最大投票数 MAX_COUNT 当前投票数 count 投票意见 answer 2.

DCL单例及synchrosized问题

疑问待解: 1 synchronized代码块执行完后,在没有return INSTANCE之前,其他线程是否可见这个对象(因为synchronized出块后会把工作内存写到主存)? 如果可见,那么return的作用是不是可有可无? 2 假如synchronized在执行new Singleton03时,会不会发生cpu时间片用完了?

HIVE函数讲解之单行函数、聚合函数、炸裂函数、窗口函数

Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的SQL查询功能,可以将SQL语句转换为MapReduce任务进行运行。其优点是学习成本低,可以通过类SQL语句快速实现简单的MapReduce统计,不必开发专门的MapReduce应用,十分适合数据仓库的统计分析。 Hive会将常用的逻辑封装成函数给用户进行使用,类似于Java中的函数。好处在于可以避免用户反复写逻辑,可以直接拿来使用。重点在于用户需要知道函数叫什么,能做什么。 Hive函数大致分为五类:单行函数、聚合函数、炸裂函数、窗口函数、自定义函数,今天我们主要介绍一下除自定义函数外的函数部分案例使用。 自定义函数咱们之前已经细致的讲过了,可以根据连接查看:HIVE函数讲解之自定义函数 一、单行函数 单行函数的特点是一进一出,大致可以分为数学函数,日期函数,字符串函数,流程控制函数,集合函数。 1. 数学函数 数学函数针对于数值形式的计算,返回值均为数值类型。 示例: select 1 + 1; 2 select 1 - 1; 0 select 2 * 2; 4 select 3 / 2; 1.5 select 5 % 2; 1 select 1 & 2; 0 select 1 | 2; 3 select 1 ^ 2; 3 select ~1; -2 2. 日期函数 ① unix_timestamp(string time):返回值为bigint类型。 select unix_timestamp('2023-04-06 15:31:26'); 1680795086 ② from_unixtime(bigint time [,string format]):返回值为 string类型。 select from_unixtime(1680795086);

Vue中如何进行图片裁剪与上传?

Vue中如何进行图片裁剪与上传? 在Web开发中,经常需要使用图片,有时候需要对图片进行裁剪和上传,Vue作为一种流行的前端框架,提供了很多方便的工具和插件来帮助开发者实现这些功能。 图片裁剪 Vue中提供了很多图片裁剪的插件,本文介绍一种常用的插件vue-cropper,它是一个基于Vue的图片裁剪组件,可以快速实现图片的裁剪功能。 安装vue-cropper 安装vue-cropper非常简单,只需要使用npm或yarn安装即可。 npm install vue-cropper --save 使用vue-cropper 安装完成后,在需要使用的组件中引入vue-cropper,并在template中使用。 <template> <div> <vue-cropper ref="cropper" :src="imageSrc" :auto-crop="true" :output-type="'jpeg'" :output-quality="0.8" :fixed-box="true" :fixed-number="[1, 1]" :drag-mode="cropDragMode" :view-mode="1" :guides="true" :center="true" :zoomable="false" :rotatable="true" :scalable="false" :crop-box-movable="false" :crop-box-resizable="false" @crop-success="cropSuccess" ></vue-cropper> <button @click="crop">裁剪图片</button> </div> </template> 在script中,引入vue-cropper,并在data中定义需要的变量和方法。 import VueCropper from 'vue-cropper' export default { components: { VueCropper }, data () { return { imageSrc: '', // 图片地址 cropDragMode: 'crop', // 裁剪模式 } }, methods: { crop () { this.

Beyond Compare4 提示错误“这个授权密钥已被吊销”的解决办法

启动Beyond Compare时弹框提示“这个授权密钥已被吊销”。 解决方法: 方法一: 防火墙禁止BCompare.exe程序访问网络 打开防火墙高级设置界面,在出入站规则中限制BCompare.exe访问网络(同样适用于家庭版系统): 开始→运行→control→回车→Windows Defender 防火墙→高级设置→在出站/入站规则中分别新建一条拒绝BCompare.exe访问网络的规则。 见下图,未截图部分不用按照默认值即可,出站规则设置同入站一致。 创建一个清除无效授权文件的批处理程序bat 打开Beyond Compare 4的安装目录,与BCompare.exe程序同一目录,新建一个记事本,粘贴以下代码 rem 授权失效时,将此文件放在BCompare程序安装目录下,以系统管理员身份运行此文件 cd /d %~dp0 echo y|del "%AppData%\Scooter Software\Beyond Compare 4\*.*" echo y|del BCState.* echo y|del BCSessions.* 文件保存为 act.bat,关闭BCompare正在运行的程序,以管理员身份运行此文件并启动BC即可 方法二:暂时解决问题,删除以下目录中的所有文件即可。 C:\Users\hui\AppData\Roaming\Scooter Software\Beyond Compare 4 注意:不同的电脑路径会有所差别。在C盘搜一下 Scooter Software 即可

Dockerfile创建镜像

一、Docker镜像的创建 创建镜像有三种方法,分别为【基于已有镜像创建】、【基于本地模板创建】以及【基于Dockerfile创建】。 1.1 基于现有镜像创建 (1)首先启动一个镜像,在容器里做修改 docker run -it centos:7 /bin/bash #启动容器 ​ yum install -y epel-release #安装epel源 yum install -y nginx #安装nginx yum install net-tools #安装tools工具 nginx #启动服务 netstat -natp |grep 80 #查看端口是否开启 ​ docker ps -a #查看容器ID ​ (2)然后将修改后的容器提交为新的镜像,需要使用该容器的ID号创建新镜像 docker commit -m "new nginx" -a "yuji" c7f4bc905c29 nginx:centos #常用选项: -m 指定说明信息; -a 指定作者信息; -p 生成过程中停止容器的运行。 c7f4bc905c29 原容器ID。 nginx:centos 生成新的镜像名称。 ​ docker images #查看生成的新镜像 docker run -itd nginx:centos bash #使用新的镜像创建容器 docker ps -a #查看容器状态 docker exec -it ae8e40e434fe bash #进入容器 nginx #启动nginx服务 netstat -natp |grep 80 #查看80端口是否开启 1.

Java NIO学习笔记(堆外内存之 DirectByteBuffer 详解)

堆外内存 堆外内存是相对于堆内内存的一个概念。堆内内存是由JVM所管控的Java进程内存,我们平时在Java中创建的对象都处于堆内内存中,并且它们遵循JVM的内存管理机制,JVM会采用垃圾回收机制统一管理它们的内存。那么堆外内存就是存在于JVM管控之外的一块内存区域,因此它是不受JVM的管控。 在讲解DirectByteBuffer之前,需要先简单了解两个知识点。 java引用类型,因为DirectByteBuffer是通过虚引用(Phantom Reference)来实现堆外内存的释放的。 PhantomReference 是所有“弱引用”中最弱的引用类型。不同于软引用和弱引用,虚引用无法通过 get() 方法来取得目标对象的强引用从而使用目标对象,观察源码可以发现 get() 被重写为永远返回 null。 那虚引用到底有什么作用?其实虚引用主要被用来 跟踪对象被垃圾回收的状态,通过查看引用队列中是否包含对象所对应的虚引用来判断它是否 即将被垃圾回收,从而采取行动。它并不被期待用来取得目标对象的引用,而目标对象被回收前,它的引用会被放入一个 ReferenceQueue 对象中,从而达到跟踪对象垃圾回收的作用。 关于java引用类型的实现和原理可以阅读之前的文章Reference、ReferenceQueue详解 和 Java 引用类型简述。 关于linux的内核态和用户态 内核态:控制计算机的硬件资源,并提供上层应用程序运行的环境。比如socket I/0操作或者文件的读写操作等用户态:上层应用程序的活动空间,应用程序的执行必须依托于内核提供的资源系统调用:为了使上层应用能够访问到这些资源,内核为上层应用提供访问的接口 我们可以得知当我们通过JNI调用的native方法实际上就是从用户态切换到了内核态的一种方式。并且通过该系统调用使用操作系统所提供的功能 Q:为什么需要用户进程(位于用户态中)要通过系统调用(Java中即使JNI)来调用内核态中的资源,或者说调用操作系统的服务了? A:intel cpu提供Ring0-Ring3四种级别的运行模式,Ring0级别最高,Ring3最低。Linux使用了Ring3级别运行用户态,Ring0作为内核态。Ring3状态不能访问Ring0的地址空间,包括代码和数据。因此用户态是没有权限去操作内核态的资源的,它只能通过系统调用外完成用户态到内核态的切换,然后在完成相关操作后再有内核态切换回用户态。 DirectByteBuffer ———— 直接缓冲 DirectByteBuffer是Java用于实现堆外内存的一个重要类,我们可以通过该类实现堆外内存的创建、使用和销毁。 DirectByteBuffer该类本身还是位于Java内存模型的堆中。堆内内存是JVM可以直接管控、操纵。 而DirectByteBuffer中的unsafe.allocateMemory(size);是个一个native方法,这个方法分配的是堆外内存,通过C的malloc来进行分配的。分配的内存是系统本地的内存,并不在Java的内存中,也不属于JVM管控范围,所以在DirectByteBuffer一定会存在某种方式来操纵堆外内存。 在DirectByteBuffer的父类Buffer中有个address属性: // Used only by direct buffers// NOTE: hoisted here for speed in JNI GetDirectBufferAddresslong address;address只会被直接缓存给使用到。之所以将address属性升级放在Buffer中,是为了在JNI调用GetDirectBufferAddress时提升它调用的速率。 address表示分配的堆外内存的地址。 unsafe.allocateMemory(size);分配完堆外内存后就会返回分配的堆外内存基地址,并将这个地址赋值给了address属性。这样我们后面通过JNI对这个堆外内存操作时都是通过这个address来实现的了。 在前面我们说过,在linux中内核态的权限是最高的,那么在内核态的场景下,操作系统是可以访问任何一个内存区域的,所以操作系统是可以访问到Java堆的这个内存区域的。 Q:那为什么操作系统不直接访问Java堆内的内存区域了? A:这是因为JNI方法访问的内存区域是一个已经确定了的内存区域地质,那么该内存地址指向的是Java堆内内存的话,那么如果在操作系统正在访问这个内存地址的时候,Java在这个时候进行了GC操作,而GC操作会涉及到数据的移动操作[GC经常会进行先标志在压缩的操作。即,将可回收的空间做标志,然后清空标志位置的内存,然后会进行一个压缩,压缩就会涉及到对象的移动,移动的目的是为了腾出一块更加完整、连续的内存空间,以容纳更大的新对象],数据的移动会使JNI调用的数据错乱。所以JNI调用的内存是不能进行GC操作的。 Q:如上面所说,JNI调用的内存是不能进行GC操作的,那该如何解决了? A:①堆内内存与堆外内存之间数据拷贝的方式(并且在将堆内内存拷贝到堆外内存的过程JVM会保证不会进行GC操作):比如我们要完成一个从文件中读数据到堆内内存的操作,即FileChannelImpl.read(HeapByteBuffer)。这里实际上File I/O会将数据读到堆外内存中,然后堆外内存再讲数据拷贝到堆内内存,这样我们就读到了文件中的内存。 static int read(FileDescriptor var0, ByteBuffer var1, long var2, NativeDispatcher var4) throws IOException { if (var1.

事件监听的简单代码

事件监听 当某件事发生,会做什么行为。 package com.jun.lesson01; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class TestActionEvent { public static void main(String[] args) { Frame frame = new Frame(); frame.setVisible(true); frame.setBounds(200,200,500,200); Button button = new Button(); //MyActionListener myActionListener = new MyActionListener();//实例化对象对下面的事件监听做参数 button.addActionListener(new MyActionListener()); frame.add(button); frame.pack();//窗口的优化方法 windowclose(frame); }//关闭窗体的事件 static void windowclose(Frame frame){ frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); } } class MyActionListener implements ActionListener{//继承事件监听接口 @Override public void actionPerformed(ActionEvent e) { System.

【Applied Algebra】扩域(Galois域)上的乘加法表构造

【Applied Algebra】扩域(Galois域)上的乘法表构造 在之前的文章里,我们讨论了扩域上(Galois域)的计算及其实现,但是侧重的是扩域中元素之间运算的细节实现,而如果想描述整个域的结构,就需要构造乘法表和加法表;实现仍然是基于c++和符号计算库GiNaC; 运算表及其设计 考虑 F p n \mathbb{F}_{p^n} Fpn​上的元素,根据 F p n ≅ F p / f ( x ) \mathbb{F}_{p^n} \cong \mathbb{F}_{p}/f(x) Fpn​≅Fp​/f(x),比如计算 F 2 4 \mathbb{F}_{2^4} F24​上的元素,根据 F 2 4 ≅ F 2 / f ( x ) \mathbb{F}_{2^4} \cong \mathbb{F}_{2}/f(x) F24​≅F2​/f(x),这里设 f ( x ) = x 4 + x 3 + 1 f(x) = x^4+x^3+1 f(x)=x4+x3+1为不可约多项式; F 2 4 \mathbb{F}_{2^4} F24​中洽有 16 16 16个元素, F 2 / f ( x ) \mathbb{F}_{2}/f(x) F2​/f(x)中的元素可以表示为小于 4 4 4次的多项式,根据每一项出现与否( { x 3 , x 2 , x , 1 } \{x^3,x^2,x,1\} {x3,x2,x,1})也恰有16个多项式,那么和 F 2 4 \mathbb{F}_{2^4} F24​中的元素一一对应,因此 F 2 4 \mathbb{F}_{2^4} F24​亦可表示为:

软件工程 | 期末复习习题

一、软件工程概述 1、选择 软件有无可行性和不可控性 软件工程是一门工程性学科 软件生存周期常见模型:螺旋模型、增量模型、瀑布模型、原型模型、融合模型、快速应用开发模型、敏捷模型 软件生存周期中时间最长的阶段是维护阶段 瀑布模型是一种软件生存周期模型 采用结构化生存周期方法,由于其特征面而一般称其为瀑布模型 在结构性的瀑布模型中,需求分析阶段定义的标准将成为软件测试中系统测试阶段的目标 2、简答题 什么是软件危机?软件危机表现在哪些方面? 答:具体来说,软件危机出现的原因可以概括如下 忽视软件开发前期的需求分析。开发过程缺乏统一的、规范化的方法论指导。文档资料不齐全或不准确。忽视与用户之间、开发组成员之间的交流忽视测试的重要性。不重视维护或由于上述原因造成维护工作的困难从事软件开发的专业人员对这个产业的认识不充分,缺乏经验没有完善的质量保证体系 具体地说,软件危机的表现形式可以概括如下。 软件开发费用和进度失控。软件系统实现的功能与实际需求不符软件的可靠性差软件难以维护软件通常没有适当的文档资料软件成本在计算机系统总成本中所占的比例居高不下,且逐年上升软件生产率提高的速度,远远跟不上计算机应用迅速普及深入的趋势 (4) 什么是软件生存周期?它分为几个时期?几个阶段? 答:软件生存周期是指从设计该产品的构想开始,到软件需求的确定、软件设计、软件实现、产品测试与验收、投入使用,以及产品版本的不断更新,到该产品最终被市场淘汰的全过程。软件生存周期由软件定义、软件开发和运行维护三个时期组成,划分为问题定义、可行性研究、需求分析、概要设计、详细设计、软件实现和单元测试、综合测试和运行维护八个阶段。 (5) 什么是软件生存周期模型?有哪些主要软件过程模型? 答:软件生存期模型也称为软件过程模型,是从软件项目需求定义直至软件运行维护为止,跨越整个生命周期的系统开发、运行和维护所实施的全部过程、活动和任务的结构框架。典型的包括瀑布模型、快速原型模型、增量模型、螺旋模型、统一过程、敏捷过程等。 二、软件问题定义及可行性分析 1、填空 可行性研究的目的是:用最小的代价在尽可能短时间内确定问题是否能够解决 经济可行性研究范围包括:投资效益分析、公司经营长期策略、开发所需的成本和资源、潜在的市场前景。 可行性分析的目的是研究这个软件项目是否值得去开发 可行性分析实质上是进一步简化,压缩了需求分析和设计过程 成本-效益分析首先要估算将要开发系统的开发成本,然后与可能取得的效益进行比较和权衡 成本效益分析的目的是从经济角度评价一个软件项目是否可行 可行性分析具体步骤最后一步是编写可行性报告 可行性研究主要集中在以下几个方面技术可行性、经济可行性、社会因素方面可行性和操作可行性。 可行性分析成本包括直接成本和间接成本,收益包括有形收益和无形收益。 系统经济效益等于因使用新系统而增加的收入加上使用新系统可以节省的运行费用 系统的经济效益可以用货币时间价值、投资回收期和纯收入等指标进行度量 纯收入就是指软件生命周期内,系统累计经济效益与投资之差 投资回收期就是积累的经济效益等于最初投资所需要的时间 制订软件计划过程,需确定软件的工作范围、估算开发所需要源、估算软件成本费用和进度安排 软件的作用范围包括软件系统的功能、软件系统的性能、接口、可靠性 数据流图也被称为“数据流图表”或 泡泡图 数据流图的一些辅助图,其中符号* 表示相邻的一对数据流同时出现,+表示相邻的数据流A或B或A和B 同时出现,圈圈里面+表示两个数据流只取其一 绘制数据流图时,每个加工至少有一个输入数据流和一个输出数据流 绘制数据流图时个数据流子图必须与它上一层的一个加工对应。数据流图中的每个元素必须有名字 数据字典有5类条目:数据流、数据项、数据存储、基本加工及数据源点与数据终点。 2、选择 可行性是系统方案实现的可能性 可行性研究从经济、技术、操作、法律、社会效益等方面进行 开发软件时对提高软件开发人员工作效率至关重要的是程序人员的数量 软件可行性分析中,从软件的功能角度考虑可行性是技术可行性,他要解决技术风险问题 可行性研究要进行的需求分析和设计应是简化压缩的 软件系统的可行性研究包括经济可行性、技术可行性、社会可行性 研究硬件资源的有效性是进行操作可行性研究的一个方面 数据流图,被计算机处理的成分是控制流、数据流、节点 结构化分析方法使用的描述工具数据字典定义了数据流图中每一个图形元素 分层DFD是一种描述方式,他顶层图描述系统的输入与输出 数据存储和数据流都是数据,仅仅所处的状态不同 数据字典中,一般不包括下列选项中的源点与终点条目 数据字段是对数据定义信息的集合,他所定义的对象都包含与数据流图 3、简答题 可行性研究主要研究哪些问题? 可行性研究的任务是决定软件项目是做还是不做,对技术可行性、经济可行性、社会可行性、开发方案的可行性以及运行可行性等方面进行分析 三、需求分析 1、选择 进行需求分析可以用多种工具,但PAD是不适用的 E-R图中,包含实体、属性、关系等基本成分 软件规格说明书内容不应该包括对算法的详细描述 结构化需求分析方法的基本思想是自顶向下逐步分解

MATLAB中的xlsxread函数使用详解

MATLAB中的xlsxread函数可以读取Excel文件中的数据,为数据分析和可视化提供了方便。本文将详细介绍xlsxread函数的使用方法。 xlsxread函数的基本语法为: [num,txt,raw] = xlsxread(filename, sheet, range) 其中,filename是Excel文件名(可以包括相对路径或绝对路径),sheet是要读取的工作表名称或工作表索引号,range是要读取的数据范围或单元格地址(例如’A1:G10’)。 返回值: num:Excel文件中数字数据的数值矩阵。txt:Excel文件中文本数据的字符矩阵。raw:Excel文件中原始数据的矩阵形式。 需要注意的是,在Excel文件中,数字、文本和公式的检测是自动进行的,因此,在使用xlsxread函数时,需要分别处理这三种类型的数据。 代码示例: 让我们来看一个简单的例子。假设我们有一个"test.xlsx"文件,其中包含一个名为"Sheet1"的工作表,包括如下数据: ABC12A34B 现在,我们想要读取并存储Excel表中的数据。我们可以使用以下方式: [num,txt,raw] = xlsxread('test.xlsx', 'Sheet1', 'A1:C2'); 这样,我们将会分别得到num、txt和raw的值: num = [1 2; 3 4]。txt = [‘A’ ‘B’; ‘C’ ‘D’]。raw = [1 2 ‘A’; 3 4 ‘B’]。 需要注意的是,当读取Excel文件时,使用xlsxread函数要求在数据范围中包含所有要读取的单元格,否则可能会出现数据丢失或偏移的情况。 总结 以上是xlsxread函数的使用方法,通过使用xlsxread函数,我们可以轻松地读取Excel文件中的数据,并将其保存在MATLAB中进行数据分析和可视化。需要注意的是,在读取不同类型数据时,应注意数据的格式和质量,以避免数据分析过程中出现的错误。

Windows 下vscode 无法激活conda环境问题解决

原因是: vscode终端使用的是PowerShell,该脚本环境下不支持激活conda 环境 解决办法: 在vscode中修改使用的终端。 步骤: 进入vscode中,在vscode界面内打开搜索框(CTRAL+SHFT+P)之后会弹出 输入框中输入:terminal:select default profile,之后选择第一个cmd.exe即可。 之后查看用户的setting.json 文件内,发现最后一行多了一行,即成功。 其实,还有个很简便的方法,就是, 这个右边的红色加号,可以选择 command prompt 。 ​​​​​​​

vue 3 第三十六章:vite环境变量(.env文件的配置及使用)

文章目录 1. 环境变量使用场景2. 创建`.env`文件3. 在应用程序中使用环境变量3.1. 输出结果(开发环境):3.2. 输出结果(生产环境): 4. 在 vite 中使用环境变量 1. 环境变量使用场景 区分不同的环境。在Vite中,我们可以使用环境变量来管理不同环境下的配置。Vite支持使用.env文件来配置环境变量,不同的环境可以使用不同的.env文件来管理配置。当做全局变量使用。用来判断是开发或者测试环境,展示不用的页面、按钮等等。 2. 创建.env文件 首先,我们需要在项目的根目录下创建.env文件。.env文件中可以定义各种环境变量,例如API的地址、端口号等等。以下是一个简单的.env文件示例: VITE_APP_DEV = 'dev-api' VITE_APP_URL = 'http://192.168.0.0.1/api' 注意:在vite中环境变量必须以VITE开头 3. 在应用程序中使用环境变量 要在Vite的应用程序中使用环境变量,我们可以使用import.meta.env对象来访问它们。例如,在组件中可以使用以下方式访问VITE_APP_TITLE环境变量: // 在组件中可以通过这种方式来访问 <script setup lang="ts"> console.log(import.meta.env); </script> 3.1. 输出结果(开发环境): 3.2. 输出结果(生产环境): 运行 npm run build 打包项目,生成 dist 文件运行 npm install http-server -g 安装 http-server。(由于dist文件本地直接打开会跨域(file文件协议不允许跨域),因此需要启动一个后台服务)运行 http-server -p <端口号> -o,启动后台服务打开页面后,此时查看浏览器控制台就可以看到如下的输出信息 此处启动后台服务方式很多。可以使用http-server,也可以使用nginx等其他方式 在这个示例中,我们使用import.meta.env来访问环境变量,并将其输出到控制台中。 4. 在 vite 中使用环境变量 另外,我们还可以在Vite的配置文件中使用环境变量。例如,可以在vite.config.js文件中使用以下方式访问环境变量: 在 vite.config.js文件测试 vite 获取到的环境: 运行 npm run dev 可以看到打印出的是 development 运行 npm run build 可以看到打印出的是 production vite 中不支持 import.

java内存可见性测试

测试过程中由于用到了println输出结果,导致运行结果与实际不符,也找不到原因。后来查了些资料,知道是因println引起。但也不知道如何输出才会避免这个问题。今天再测试一次,有点眉目。 package com.test; import java.util.concurrent.TimeUnit; public class VolatileTest { /* volatile */ boolean running = true; void m() { System.out.println(Thread.currentThread().getName() + " start"); while(running){ // System.out.println(""); // try { // Thread.sleep(1000); // } catch (InterruptedException e) { // e.printStackTrace(); // } } System.out.println(Thread.currentThread().getName() + " end"); } public static void main(String[] args) throws InterruptedException { VolatileTest te = new VolatileTest(); Runnable r = te::m; new Thread(r,"M").start(); //new Thread(() -> te.

Shell脚本攻略:数组

目录 一、理论 1.数组概述 2.定义数组 3.数组打印 4.数组的数据类型及处理 5.数组赋值 6.数组遍历 7.数组切片 8.数组替换 9.删除数组 10.追加数组中的元素 11.数组排序算法 二、实验 1.实验一 2.实验二 3.实验三 一、理论 1.数组概述 数组是Shell的一种特殊变量,是一组数据的集合,里面的每个数据被称为一个数组元素。 当前Bash仅支持一维索引数组和关联数组,Bash对数组的大小没有限制。 2.定义数组 (1)索引数组 ① 方式一 数组名=( value0 valuel value2 … ) ② 方式二 shell中,用小括号( )来表示数组,数组元素之间用空格来分隔 数组名=(value0 valuel value2 …) ③ 方式三 采用键值对的形式赋值 数组名=( [0]=value [1]=value [2]=value …) ④ 方式四 通过分别定义数组变量的方法来定义 数组名[0]=“value” 数组名[1]=“value” 数组名[2]=“value” ⑤ 方式五 列表名=“value0 valuel value2 …” 数组名=($列表名) (2)备注 ① 数组中的元素,必须以"空格"来隔开,这是其基本要求; ② 定义数组其索引,可以不按顺序来定义,比如说:names=([0]=Jerry [1]=Alice [2]=David [8]=Wendy); ③ 字符串是SHELL中最重要的数据类型,其也可通过($str)来转成数组,操作起来非常方便;

Shell脚本查询进程并kill进程(集群版)

记录:454 场景:使用Shell脚本查询进程并kill进程。使用Shell脚本远程执行脚本查询进程并kill进程。 版本:CentOS Linux release 7.9.2009。 1.使用Shell脚本查询进程并kill进程 1.1脚本 脚本名称:zk-kill_pid.sh 脚本内容: #!/bin/bash PID=`ps -ef | grep zookeeper | grep -v grep | awk '{print $2}'` echo "查出zookeeper相关的进程PID: $PID" for item in $PID do kill -s 9 $item echo "已经kill进程: $item" done 执行脚本:sh zk-kill_pid.sh 1.2解析 ps命令:process status的简称。一个查看进程信息工具。查看进程执行瞬间的进程信息工具。查看进程状态、进程使用内存状况、进程使用CPU状况、进程PID等。 ps -ef:-e查看全部进程信息。-f,-f完整格式,包括命令行。打印字段:UID、PID、PPID、C、STIME、TTY、TIME、CMD。 |:管道符,把上一个命令输出内容,出入到下一命令。 grep zookeeper,搜索包含zookeeper关键字的进程。 grep -v grep,-v,不匹配包含grep关键字进程。 awk '{print $2}',使用awk把上一级输入的信息以使用空格分割字符串。$2,取出第二个字符。 kill -s 9,根据进程号kill进程。 2.使用Shell脚本远程执行脚本查询进程并kill进程 2.1脚本 脚本名称:zk-kill_pid_cluster.sh 脚本内容: #!/bin/bash for host_name in app161 app162 app163 do echo "

Linux——IP协议1

目录 协议头格式 如何封装和解包 如何交付(分用) 报头每一个字段 分片是怎么做到的 应用层解决的是数据使用的问题。 在传输层,网络层,数据链路层:解决的是网络通信的细节,将数据可靠的从A主机跨网络发送到B主机。 可靠性由传输层决定,从主机A送到主机B由网络层决定。 IP协议主要是提供一种能力,将数据从A主机送到B主机的能力。有这种能力,一定能把数据送给对方吗?不能,有能力是指有很大概率能做成,而不是一定能做成。 主机: 配有IP地址, 但是不进行路由控制的设备; 路由器: 即配有IP地址, 又能进行路由控制; 节点: 主机和路由器的统称; 协议头格式 数据部分有TCP数据段 如何封装和解包 IP协议也是固定长度的报文,前20个字节就是固定的,也可携带选项。读取前20个字节,就能读取到报头的相关属性了,先读取前20字节,再读取4位首部长度,用首部长度减去20字节,得到的就是选项。如果没有选项,4位首部长度就是5(0101). IP采用的是定长报头和子描述字段。 如何交付(分用) 8位协议表示有效载荷部分表示是UDP还是TCP,根据8位协议决定交给TCP还是UDP。 报头每一个字段 4位版本:就是IPV4,指定IP协议的版本, 对于IPv4来说, 就是4 IPV6和IPV4差别:IPV4是4字节,32个比特位来表示IP地址,IPV6用128位比特位表示IP地址。但IPV6和IPV4是不兼容的。现在所有的计算机用的都是IPV4。 4位首部长度:IP地址表示报头长度用4个比特位表示,即十进制下0-15,4位首部长度有自己的单位,基本单位是4字节,即整个报文的宽度0-32比特位,假设4位首部长度是4,整个报文长度就是4*x,即最终能表示0-60的数字。 8位服务类型:3位优先权字段(已经弃用), 4位TOS字段, 和1位保留字段(必须置为0). 4位 TOS分别表示: 最小延时, 最大吞吐量, 最高可靠性, 最小成本. 这四者相互冲突, 只能选择一个. 对于ssh/telnet这样的应用程序, 最小延时比较重要; 对于ftp这样的程序, 最大吞吐量比较重要. 16位总长度:IP数据报整体占多少个字节,有效载荷=16位总长度-4位首部长度*4 生存时间:当一个报文进行转发的时候,可能会由于路由器问题,导致报文在路由器里长时间转发,经过了大量路由器,为了防止出现环路转发的情况,给每个报文设置了生存时间。 生存时间本质是一个计数器,每转发一次,计数器--,当生存时间为0时,便不在路由器中转发,直接丢弃。 16位首部校验和:如果首部校验失败,报文就被直接丢弃,我们不用担心报文被丢弃,发送方主机会重传。 32位源IP:数据包从哪来 32位目的IP:数据包到哪去。 IP报文的形式和TCP报文非常类似,因此称为TCP/IP协议。 链路层由于物理特征的原因,一般无法转发太大的数据,链路层有一次可以转发到网络的报文大小的限制。一般是1500字节,一般称为MTU(最大传输单元),若网络层要向下交付2500字节数据,网络层就需要做一件事情:“数据分片。” 分片之后,又由谁来组装? 谁分片,谁组装(对端网络层),谁污染,谁治理。 分片是将一个较大的IP报文,分割成多个较小的 ,满足条件的报文,分片的行为是网络层大的,同样组装的行为也必须由对方的网络层做。 对方为什么要组装?因为对方给自己的网络层是一个完整的TCP报文,接收方在网络层向上交付也必须是一个完整的报文。IP分片和组装的行为,TCP是不知道,不关心的。 分片是怎么做到的 16位标识是IP报文的序号,可根据这个序号区分报文,唯一的标识主机发送的报文. 如果IP报文在数据链路层被分片了, 那么每一个片里面的这个id都是相同的 3位标志:第一位保留(保留的意思是现在不用, 但是还没想好说不定以后要用到). 第二位置为1表示禁止分片, 这时候如果报文长度超过MTU, IP模块就会丢弃报文. 第三位表示"更多分片", 如果分片了的话,最后一个分片置为0, 其他是1.

安装win10虚拟机

(1)依次点击【文件】、【新建虚拟机】 (2)选择【典型】,点击【下一步】 (3)选择【稍后安装操作系统】,点击【下一步】 (4)选择客户机操作系统为【Microsoft Windows(W)】,版本为【Windows 10 x64】,点击【下一步】 (5)编辑虚拟机名称,选择虚拟机文件的存放位置,点击【下一步】 (6)选择【将虚拟磁盘存储为单个文件】,点击【下一步】 (7)点击【完成】 (8)点击【编辑虚拟机设置】 (9)点击【CD/DVD】,选择【启动时连接】、【使用ISO镜像文件】,点击【浏览】,选择本地windows镜像 (10)点击【显示器】,取消勾选【加速3D图形】,点击【确定】(不取消勾选会导致虚拟机无法正常开启) (11)点击【开启此虚拟机】 (12)当界面出现 “Press any key to boot from CD or DVD …” 时,此时一定要将光标至于虚拟机中,然后按任何一个按键。 如果没有及时按的话,就会出现如下界面,此时只能重启虚拟机,重新选择了。 (13)进入win10安装程序,点击【下一步】 (14)点击【现在安装】 (15)在激活界面,如果有密钥,就输入,没有密钥就点击【我没有产品密钥】 (16)选择安装的win10版本,点击【下一步】 (17)勾选【我接受许可条款】,点击【下一步】 (18)选择【仅安装Windows(高级)】 (19)虚拟机默认只有一个分区,如果不用调整,就直接点击【下一步】 (20)开始安装win10系统

黑马点评项目总结

文章目录 1.登录怎么实现?1.1 基于Session登录1.2 ThreadLocal1.3 session共享问题1.4 基于Redis实现共享session登录 2.商户查询缓存怎么实现?2.1 什么是缓存,有什么用?使用缓存会带来什么问题?2.2 解决缓存一致性问题要采用什么策略?2.3 缓存存在的问题2.3.1 缓存穿透2.3.2 缓存雪崩2.3.3 缓存击穿 3.秒杀业务3.1 全局唯一ID3.2 秒杀下单3.3 库存超卖问题3.4 一人一单3.4.1 单机情况下实现一人一单3.4.2 集群模式下一人一单的并发安全问题 3.5 分布式锁3.5.1 基于 Redis 的分布式锁 3.6 Redis消息队列实现异步秒杀 4.点赞怎么实现?4.1 需求:4.2 实现步骤: 5.点赞排行版怎么实现?5.1 需求:5.2 实现步骤: 6.关注怎么实现?6.1 需求:6.2 实现步骤: 7.共同关注怎么实现?7.1 需求:7.2 实现步骤: 8.关注推送怎么实现?8.1 需求:8.2 实现步骤: 9.用户签到怎么实现?9.1 签到9.2 连续签到天数统计 10.用户信息UV统计怎么实现?11.项目中遇到的困难11.1 事务失效的情况11.2 事务失效的情况——秒杀模块一人一单 1.登录怎么实现? 1.1 基于Session登录 登录包括短信验证码的发送,然后是基于短信验证码的登录,最后是对登录状态的校验。 发送短信验证码 用户提交自己的手机号,服务端接收到这个手机号以后,首先要去验证一下手机号是不是合法的。合法就发送验证码。发验证码之前要先生成验证码,生成验证码的目的是为了让用户去做登录。要把这个验证码保存在本地,将来用户在登录的时候,才能做验证。那既然是基于session登录,那肯定是把这个验证码保存在session当中,之后就可以给用户发送短信验证码了。 public Result sendCode(String phone, HttpSession session) { //1.校验手机号:利用util下RegexUtils进行正则验证 if (RegexUtils.isPhoneInvalid(phone)) { // 2.如果不符合,返回错误信息 return Result.fail("手机号格式错误!"); } // 3.

如何入门编程

随着信息技术的快速发展,编程已经成为一个越来越重要的技能。那么,我们该如何入门编程呢? 一、自学编程需要注意什么? 首先要搞清楚自学的目的是什么?是为了兴趣爱好还是为了以后要从事这个编程行业,因为编程是一门需要长时间投入精力、不断学习和练习的技能,要想取得长远的进步就需要有足够的毅力和决心,所以在你开始学习之前,一定要问问自己为什么要学习编程,是否有足够的动力和信心去保持学习的态度和习惯。 二、编程初学者学什么语言好? 目前有很多编程语言可供选择,例如Python、Java、C++等。初学者应该选择主流的、社区比较大的、易于学习的,以下是这三个主流语言的有点介绍: Python的优点 1. 易于学习:Python是一种相对简单易懂的编程语言,语法简洁,代码易于阅读,注重代码可读性,初学者容易掌握。 2. 应用场景广泛:Python在数据处理、Web开发、人工智能和机器学习等领域都有广泛的应用,可以为初学者提供更多的实践机会。 3. 社区资源丰富:Python生态系统活跃,有一个庞大的开发社区和试验平台,因此可以找到大量优质的解决方案,库,插件等等。 Java的优点 1. 跨平台性:Java语言编写的程序可以在多个平台上运行,具有强大的跨平台性。 2. 安全性高:Java语言自带的安全机制可以有效地防止代码被恶意攻击和病毒感染等问题。 3. 应用广泛:Java在企业级开发和Android开发方面广泛应用,可以为初学者提供更多的就业机会。 C++的优点 1. 效率高:C++具有高效的内存管理和直接硬件操作的能力。 2. 应用广泛:C++应用领域广泛,包括操作系统、游戏开发、图形库、嵌入式系统等等。 3. 适合学习底层编程:C++是一种底层语言,有助于初学者理解计算机的底层操作,并提高代码的优化性能。 建议 本人觉得Python适合将编程作为爱好的初学者,Java适合将编程作为职业的初学者,C++适合志于深耕计算机底层的初学者。 三、编程中,有哪些好的习惯从一开始就值得坚持? 1. 懂得团队开发 不管是上学时自学编程,还是在公司里工作,学习如何和团队协作是非常重要的。使用Git或其他版本控制工具来维护代码库,编写具有可读性和可重复性的注释,不断督促自己和他人更新代码库,都是非常重要的编程习惯。 2. 保持代码简洁 简洁的代码既方便阅读,也更易于维护。遵循KISS原则(Keep It Simple, Stupid 即保持简单和直接性),避免写循环嵌套过深的条件语句,以及遵循"分而治之"的模式,来保持代码简洁性。 3. 抽象和模板的使用 编程时保持仅定义一次的原则,以及使用通用的方式来解决其他类似的情况,可以有效地提高代码重复利用率和可读性。这些方法包括函数编写、设计模式和使用算法模板等方式。 4. 清晰的命名规范 使用遵循统一的命名规范,例如驼峰命名法或下划线命名法,可以让代码更加容易阅读。此外,定期删除无用变量,已经废弃的函数和依赖,以提高代码可读性。 5. 异常处理的习惯 在编写代码时,要考虑代码的健壮性和对异常情况的处理,根据墨菲定律,可能有问题的地方后面都可能会导致应用程序崩溃,留下漏洞,安全问题。 6. DRY Don't Repeat Yourself(不要重复你自己,既在软件开发中,减少重复的信息)。当你看到自己在不止一处重复编写类似的代码时,就意味着可以将他们合并成抽象、可复用的函数或类,维护同一份代码,从而减少了Bug产生的可能性。 四、如何学习编程? 现在有很多学习编程的资源,如在线课程、编程书籍、博客等。要根据自己的需求和当前水平程度选择适合自己的资源,并从中挑选最合适自己的学习路径。同时,要保持对新技术的关注,不断学习新的知识。 五、编程新手如何提高编程能力 1.参加社区、交流和开源项目 编程是一项集体活动,通过与其他有经验的开发人员交流,你可以学到新的知识、方法和技能。因此靠近社区,参加开源项目,寻找一个好的学习氛围和机会,与同行交流。 2.代码评审 虽然独自学习编程是可行的,但获得来自他人的反馈和指导也是非常有价值的。使用代码评审工具和代码编辑器插件,在代码编写和检查时帮你发现常见的错误和不良编码规范。 3.记录和分享 经常出错的地方、遇到棘手bug的解决过程、优秀的代码段、可复用的轮子等等都是值得记录和分享的,写写博客,组织线下员工培训等,都可以激励自己不断优化知识体系。 六、编程资料分享 网上资料很多,本人常用的有B站、CSDN、github、掘金、极客时间、知识星球等,里面都有不错的宝藏资源,请按需检索。

数据库 视图 创建视图 修改视图 删除视图 SQL

视图 1. 概念 视图是一种虚拟存在的表,对于使用视图的用户来说基本上是透明的。 视图并不在数据库中实际存在,行和列数据来自定义视图的查询总使用的表, 并且是在使用视图时动态生成的。 2. 视图相对于普通表的优势: 简单:使用视图的用户完全不需要关系后面对应的表结构、关联条件和筛选条件, 对用户来说已经是过滤好的符合条件的结果集。 安全:使用视图的用户只能访问他们被允许的结果集, 对表的权限管理并不能限制到某个行某个列,但是通过视图就可以简单的实现。 数据独立:一旦视图的结构确定了,可以屏蔽表结构变化对用户的影响, 源表增加列对视图没有影响;源表修改列名,则可以通过修改视图来解决, 不会造成对访问者的影响。 3. 语法 create or replace view 视图名称 ( 列名1 , 列名2 , 列名3 , ... ) AS select ....... select * from student select * from score create view student_score_view as select student.*,cid,mark from student inner join score on student.sid=score.sid select * from student_score_view select * from student_score_view where sid=2001001 -- 修改视图 alter view student_score_view as select student.

利用宝塔搭建个人博客:简单而高效的教程

前言 宝塔面板是一款服务器管理软件,支持windows和linux系统,可以通过Web端轻松管理服务器,提升运维效率。 例如:创建管理网站、FTP、数据库,拥有可视化文件管理器,可视化软件管理器,可视化CPU、内存、流量监控图表,计划任务等功能。 今天我们一起来看一下关于宝塔的使用,并利用宝塔安装个人博客。 宝塔的官网: https://www.bt.cn/new/index.html 🏠个人主页:我是沐风晓月 🧑个人简介:大家好,我是沐风晓月,阿里云社区博客专家 😉😉 💕 座右铭: 先努力成长自己,再帮助更多的人,一起加油进步 🍺🍺🍺 💕欢迎大家:这里是CSDN,我总结知识的地方,喜欢的话请三连,有问题请私信😘 可以关注我的云原生社区:云原生社区 也可以关注我的英语社区:从零开始学英语 文章目录 前言一. 实验环境二. 开始安装宝塔2.1 按照图示操作2.2 安装完成,网页端登录 三. 开始搭建个人博客3.1 直接在网页上点击安装LAMP3.2 开始安装wordpress3.3 访问测试3.4 登录后台 总结 一. 实验环境 [root@mufeng164 ~]# cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core) [root@mufeng164 ~]# uname -a Linux mufeng164 3.10.0-862.el7.x86_64 #1 SMP Fri Apr 20 16:44:24 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux [root@mufeng164 ~]# 在这里我使用centos7.5的系统,后面centos7不维护了之后,进行升级。 [root@mufeng164 ~]# ifconfig |grep inet |awk '{print $2}' |head -1 192.

Unity学习笔记之 FPS计算

前言 原文:Measuring Performance 在学习Catlikecoding里关于计算FPS时的一个笔记 公式 FPS=1f / Time.unscaledDeltaTime 当我第一眼看到的时候非常的疑惑,所以必须要从头分析一下 FPS是什么 FPS全文为frame per second,即单位为 frame/second = f/s Time.unscaledDeltaTime是什么 Time.unscaledDeltaTime 为“从上一帧到当前帧的独立于 timeScale 的时间间隔” 即每帧的运行时间,即单位为 second / frame = s / f 综上,Time.unscaledDeltaTime的倒数即为FPS 这样计算的是每帧所表现的帧数,如果每帧所需要的时间都不一样,这个数值就会一直变,从应用上来说,应该给帧数一个统计区间,如累计1秒钟再计算一次帧数,详情请接着看原文

第十四届蓝桥杯大赛软件组国赛 Python大学A组 个人暴力题解

Powered by:NEFU AB-IN 文章目录 国赛 Python大学A组 个人暴力题解A思路代码 B思路代码 C思路代码 D思路代码 E思路代码 F思路代码 G思路代码 H思路代码 I思路代码 !!!博主个人的暴力题解,基本很少是正解,求轻喷 !!!代码是赛后凭着印象复原的,可能会有记错的 国赛 Python大学A组 个人暴力题解 A 思路 调日期库,模拟 代码 from sys import setrecursionlimit, stdin, stdout, exit from collections import Counter, deque from heapq import heapify, heappop, heappush, nlargest, nsmallest from bisect import bisect_left, bisect_right from datetime import datetime, timedelta from string import ascii_lowercase, ascii_uppercase from math import log, ceil, gcd, sqrt, fabs class sa: def __init__(self, x , y): self.

keras 自然语言处理 lstm_seq2seq 案例分析

本例演示了如何实现一个基本的字符级使用 LSTM(长短期记忆神经网络)和 Seq2Seq(序列到序列模型)来进行自然语言处理的模型。我们将其应用于逐个字符,将短英语句子翻译为短法语句子。需要注意的是,在这个领域里,使用字符级机器翻译是相当不寻常的,因为使用单词级的模型更为常见。 算法摘要 我们从一个领域(例如英语句子)的输入序列开始,并从另一个领域(例如法语句子)中获得相应的目标序列。一个编码器 LSTM 将输入序列转换为 2 个状态向量(我们保留最后一个 LSTM 状态并丢弃输出)。一个解码器 LSTM 被训练,将目标序列转换为相同的序列,但是将时间步向前偏移一个步长,这个训练过程在这个上下文中称为“teacher forcing”。它使用来自编码器的状态向量作为初始状态。实际上,解码器在输入序列的条件下学习生成“targets[t+1…]”给定“targets[…t]”。在推理模式下,当我们想要解码未知的输入序列时,我们要做以下操作: 编码输入序列为状态向量。以大小为 1 的目标序列开始(只有开始字符)。将状态向量和 1 个字符的目标序列提供给解码器,生成下一个字符的预测值。使用这些预测值采样下一个字符 (我们简单地使用 argmax)。将采样的字符添加到目标序列中。重复操作,直到生成结束字符或达到字符限制。 导入依赖 import numpy as np import tensorflow as tf from tensorflow import keras 加载数据:fra-eng 这是一个包含超过64000个法语-英语单词和短语的Anki词汇卡组,它可以帮助学习者提高词汇量并加强其语言技能。Anki是一种基于记忆卡片的学习方法,被广泛用于学习基础词汇和语法规则。该词汇卡组可以在线或离线使用,并可以导入到Anki应用程序中,以便离线学习。该词汇卡组的单词和短语都包含音频发音,可以帮助学习者正确地发音字词。这里用于机器翻译。 !!curl -O http://www.manythings.org/anki/fra-eng.zip !!unzip fra-eng.zip 配置项 这些配置决定着模型的参数和训练的行为。在配置模型时,我们需要用经过实验验证的数值来平衡训练时间和模型性能。 latent_dim:这是解码器中LSTM层的隐藏状态的维度大小。通俗地说,这决定了模型学习到的内部表示的复杂度。num_samples:这是用于训练模型的语料库中的句子数量。更多的语料库可以带来更好的性能,但需要更多的训练时间和计算资源。batch_size:这是一次传递给模型的句子数。更大的批量可以加速训练,但也可能导致内存不足等问题。 batch_size = 64 # 训练的 batch 大小。 epochs = 100 # 训练的 epoch 数。 latent_dim = 256 # 编码器空间的潜在维度。 num_samples = 10000 # 训练样本数量。 # 存储在磁盘上的数据文本文件路径。 data_path = "

获取网卡ip地址代码实现

背景 业务需要在访问某个接口的时候需要实时获取到当前机器的各网卡的ip信息,以下代码仅供参考。 代码实现 #include <iostream> #include <map> #include <net/if.h> #include <netinet/in.h> #include <arpa/inet.h> #include <ifaddrs.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <netdb.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/socket.h> void PaddingSpecNetInfoByName(const char *szDevName, std::map<std::string, std::string> &netMap) { int s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { fprintf(stderr, "Create socket failed!errno=%d", errno); return; } struct ifreq ifr; unsigned char mac[6]; unsigned long nIP, nNetmask, nBroadIP; std::string netName = std::string(szDevName); // printf("

Linux中find命令的用法综合

Linux下find命令在目录结构中搜索文件,并执行指定的操作。Linux下find命令提供了相当多的查找条件,功能很强大。由于find具有强大的功能,所以它的选项也很多,其中大部分选项都值得我们花时间来了解一下。下面我们就来简单汇总下其用法 在绝大多数Linux发行版中,你都可以直接使用 find 命令而无需进行任何安装操作。如果你想在linux系统的命令行中变得特别高效,那么 find 是你必须掌握的命令之一。 find 命令的基本语法如下: $ find [path] [option] [expression] 一、基本用法 1. 列出当前目录和子目录下的所有文件 这个命令会列出当前目录以及子目录下的所有文件。 1 2 3 4 5 6 $ find . ./abc.txt ./subdir ./subdir/how.php ./cool.php 该命令与以下命令效果相同 1 2 $ find . $ find . -print 2. 查找特殊的目录或路径 下面的命令会查找当前目录下 test 文件夹中的文件,默认列出所有文件。 1 2 3 4 5 6 $ find ./test ./test ./test/abc.txt ./test/subdir ./test/subdir/how.php ./test/cool.php 下面的命令用于查找指定名称的文件。 1 2 $ find ./test -name "abc.txt" ./test/abc.txt 也可以使用通配符

Redis 哨兵架构、集群选举原理分析-04

sentinel哨兵是特殊的redis服务,不提供读写服务,主要用来监控redis实例节点。 哨兵架构下client端第一次从哨兵找出redis的主节点,后续就直接访问redis的主节点,不会每次都通过 sentinel代理访问redis的主节点,当redis的主节点发生变化,哨兵会第一时间感知到,并且将新的redis 主节点通知给client端(这里面redis的client端一般都实现了订阅功能,订阅sentinel发布的节点变动消息) 1、当一个master服务器被某sentinel视为下线状态后,该sentinel会与其他sentinel协商选出sentinel的leader进行故障转移工作。 2、每个发现master服务器进入下线的sentinel都可以要求其他sentinel选自己为sentinel的leader,选举是先到先得。同时每个sentinel每次选举都会自增配置纪元(选举周期),每个纪元中只会选择一个sentinel的leader。 3、如果所有超过一半的sentinel选举某sentinel作为leader。之后该sentinel进行故障转移操作,从存活的slave中选举出新的master,这个选举过程跟集群的master选举很类似。 4、哨兵集群只有一个哨兵节点,redis的主从也能正常运行以及选举master,如果master挂了,那唯一的那个哨兵节点就是哨兵leader了,可以正常选举新master。 5、不过为了高可用一般都推荐至少部署三个哨兵节点。 再选举出一个slave作为master 通知其余的slave,新的master是谁 通知客户端一个主从的变化 最后,sentinel会等待旧的master复活,然后将新master成为slave 那么,如何选择“合适”的slave节点呢? 选择slave-priority(slave节点优先级,人为配置)最高的slave节点,如果存在则返回,不存在则继续。其次会选择复制偏移量最大的slave节点(复制得最完整),如果存在则返回,不存在则继续最后会选择run_id最小的slave节点(启动最早的节点) Redis集群选举原理分析 当slave发现自己的master变为FAIL状态时,便尝试进行Failover,以期成为新的master。由于挂掉的master可能会有多个slave,从而存在多个slave竞争成为master节点的过程, 其过程如下: 1.slave发现自己的master变为FAIL 2.将自己记录的集群currentEpoch加1,并广播FAILOVER_AUTH_REQUEST 信息 3.其他节点收到该信息,只有master响应,判断请求者的合法性,并发送FAILOVER_AUTH_ACK,对每一个epoch只发送一次ack 4.尝试failover的slave收集master返回的FAILOVER_AUTH_ACK 5.slave收到超过半数master的ack后变成新Master(这里解释了集群为什么至少需要三个主节点,如果只有两个,当其中一个挂了,只剩一个主节点是不能选举成功的) 6.slave广播Pong消息通知其他集群节点。从节点并不是在主节点一进入 FAIL 状态就马上尝试发起选举,而是有一定延迟,一定的延迟确保我们等待FAIL状态在集群中传播,slave如果立即尝试选举,其它masters或许尚未意识到FAIL状态,可能会拒绝投票 •延迟计算公式: DELAY = 500ms + random(0 ~ 500ms) + SLAVE_RANK * 1000ms SLAVE_RANK表示此slave已经从master复制数据的总量的rank。Rank越小代表已复制的数据越新。这种方式下,持有最新数据的slave将会首先发起选举(理论上)。 集群脑裂数据丢失问题 redis集群没有过半机制会有脑裂问题,网络分区导致脑裂后多个主节点对外提供写服务,一旦网络分区恢复,会将其中一个主节点变为从节点,这时会有大量数据丢失。 只作用在一个Redis节点上,即使Redis通过sentinel保证高可用,如果这个master节点由于某些原因发生了主从切换,那么就会出现锁丢失的情况: 在Redis的master节点上拿到了锁;但是这个加锁的key还没有同步到slave节点; master故障,发生故障转移,slave节点升级为master节点;导致锁丢失。 由于脑裂是由网络等原因造成的,除了提高网络、硬件等方法外,主要通过增加以下配置,改善出现脑裂而引发的数据丢失问题。规避方法可以在redis配置里加上参数(这种方法不可能百分百避免数据丢失,参考集群leader选举机制): min‐replicas‐to‐write 1 写数据成功最少同步的slave数量,这个数量可以模仿大于半数机制配置,比如集群总共三个节点可以配置1,加上leader就是2,超过了半数 注意:这个配置在一定程度上会影响集群的可用性,比如slave要是少于1个,这个集群就算leader正常也不能提供服务了,需要具体场景权衡选择。 min-slaves-max-lag 10 一旦所有的slave复制和同步的延迟达到了10s,那么此时master就不会接受任何请求。 通过降低min-slaves-max-lag参数的值,可以避免在发生故障时大量的数据丢失,一旦发现延迟超过了该值就不会往master中写入数据。

解决websocket.GetHttpSessionConfig.modifyHandshake中获取httpsession时为null报NullPointerException

1.报错说明 public class GetHttpSessionConfig extends ServerEndpointConfig.Configurator { @Override public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) { // 获取session HttpSession httpSession = (HttpSession) request.getHttpSession(); // session放入serverEndpointConfig sec.getUserProperties().put(HttpSession.class.getName(),httpSession); } } 在这段WebSocket的配置器代码中,在 WebSocket 连接建立时,会调用 modifyHandshake方法,并将当前的 ServerEndpointConfig、握手请求和握手响应作为参数传入该方法。 但是从request中获取HttpSession为null报空指针异常 2.错误原因 客户端连接还未创建 HttpSession,所以获取到的是null,WebSocket 的这个Api实现仅获取已创建的某些内容,如果没有则不会帮助创建的 3.解决方案 既然WebSocket的Api不会帮助我们创建session,那么我们就需要在它获取session之前为客户端创建session,即,可以使用WebListner监听器,监听的时候为请求创建session @Component public class RequestListener implements ServletRequestListener { public void requestInitialized(ServletRequestEvent sre) { //将所有request请求都携带上httpSession ((HttpServletRequest) sre.getServletRequest()).getSession(); } } 上面这段代码来源于stackoverflow的这篇帖子session - Websocket - httpSession returns null - Stack Overflow 原文中使用的是@WebListener注解,但是使用@WebListener注解需要注意的是,

数据库系统概论 ---知识点大全(期末复习版)

(一)绪论 数据(Data):是数据库中存储的基本对象 数据的定义:描述事物的符号记录 数据的种类:文字、图形、图象、声音等 数据的特点:数据与其语义是不可分的 数据库(Database,简称DB):是长期储存在计算机内、有组织的、可共享的大量数据集合 数据库管理系统(Database Management System,简称DBMS):是位于用户与操作系统之间的一层数据管理软件。 DBMS的用途:科学地组织和存储数据、高效地获取和维护数据。 DBMS的主要功能: 数据库的运行管理 保证数据的安全性、完整性 多用户对数据的并发使用 发生故障后的系统恢复 数据库的建立和维护功能(实用程序) 数据库数据批量装载 数据库转储 介质故障恢 数据库的重组织 性能监视等 数据库系统(Database System,简称DBS)是指在计算机系统中引入数据库后的系统构成。 数据库系统的构成:由数据库、数据库管理系统(及其开发工具)、应用系统、数据库管理员(和用户)构成。(三树一人) 数据管理:对数据进行分类、组织、编码、存储、检索和维护,是数据处理的中心问题 数据模型这个工具来抽象、表示和处理现实世界中的数据和信息。 数据模型分成两个不同的层次 (1) 概念模型 也称信息模型,它是按用户的观点来对数据和信息建模。 (2) 数据模型 主要包括网状模型、层次模型、关系模型等,它是按计算机系统的观点对数据建模。 客观对象的抽象过程---两步抽象:① 现实世界中的客观对象抽象为概念模型;② 把概念模型转换为某一DBMS支持的数据模型。 数据结构:对象类型的集合 即数据结构是对系统静态特性的描述 两类对象:①与数据类型、内容、性质有关的对象 ②与数据之间联系有关的对象 数据操作:对数据库中各种对象(型)的实例(值)允许执行的操作及有关的操作规则 数据操作的类型:检索 更新(包括插入、删除、修改) 数据模型对操作的定义: ①操作的确切含义 ;②操作符号;③操作规则(如优先级);④ 实现操作的语言数据模型对操作的定义 数据操作是对系统动态特性的描述。 数据模型对约束条件的定义:反映和规定本数据模型必须遵守的基本的通用的完整性约束条件。提供定义完整性约束条件的机制,以反映具体应用所涉及的数据必须遵守的特定的语义约束条件。 信息世界中的基本概念 (1) 实体(Entity) 客观存在并可相互区别的事物称为实体。 (2) 属性(Attribute) 实体所具有的某一特性称为属性。 一个实体可以由若干个属性来刻画。 (3) 码(Key) 唯一标识实体的属性集称为码。 (4) 域(Domain) 属性的取值范围称为该属性的域。 (5) 实体型(Entity Type) 用实体名及其属性名集合来抽象和刻画 同类实体称为实体型 (6) 实体集(Entity Set) 同型实体的集合称为实体集