Maven使用教程

1.什么是Maven? 当我们在创建一个使用Spring的Web项目就需要引入大量的jar包。一个项目Jar包的数量极多,并且Jar包之间的关系错综复杂,一个Jar包往往又会引用其他Jar包,缺少任何一个Jar包都会导致项目编译失败。 以往开发项目时,程序员往往需要花较多的精力在引用Jar包搭建项目环境上,而这一项工作尤为艰难,少一个Jar包、多一个Jar包往往会报一些让人摸不着头脑的异常。 而Maven就是一款帮助程序员构建项目的工具,我们只需要告诉Maven需要哪些Jar 包,它会帮助我们下载所有的Jar,极大提升开发效率。 2.Maven 下载 Maven 下载地址:Maven – Download Apache Maven 3.配置maven环境变量 4.Maven POM POM( Project Object Model,项目对象模型 ) 是 Maven 工程的基本工作单元,是一个XML文件,包含了项目的基本信息,用于描述项目如何构建,声明项目依赖,等等。 执行任务或目标时,Maven 会在当前目录中查找 POM。它读取 POM,获取所需的配置信息,然后执行目标。 POM 中可以指定以下配置: 项目依赖插件执行目标项目构建 profile项目版本项目开发者列表相关邮件列表信息 在创建 POM 之前,我们首先需要描述项目组 (groupId), 项目的唯一ID。 <project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <!-- 模型版本 --> <modelVersion>4.0.0</modelVersion> <!-- 公司或者组织的唯一标志,并且配置时生成的路径也是由此生成, 如com.companyname.project-group,maven会将该项目打成的jar包放本地路径:/com/companyname/project-group --> <groupId>com.companyname.project-group</groupId> <!-- 项目的唯一ID,一个groupId下面可能多个项目,就是靠artifactId来区分的 --> <artifactId>project</artifactId> <!-- 版本号 --> <version>1.0</version> </project> 什么是Maven仓库? Maven 仓库是项目中依赖的第三方库,这个库所在的位置叫做仓库。

备忘录 浏览器关闭之后清除token

这是从别人博客上面看到的 主要是使用了localStorage保存了页面离开时的时间 在页面加载完后在计算中间的时间差 来判断是否清空token window.onload = function () { let lastTime = localStorage.getItem("lastTime"); const interval = 3 * 1000; // 如果没有上一次离开的时间或者时间间隔大于3s,就清除token if (!lastTime || new Date().getTime() - lastTime > interval) { localStorage.removeItem("token"); console.log("清除token") }else{ console.log("时间过短不清除token") } }; window.onunload = function () { localStorage.setItem("lastTime", new Date().getTime()); };

PostgreSQL技术大讲堂 - Part 9:pg_hba.conf配置

PostgreSQL从小白到专家,是从入门逐渐能力提升的一个系列教程,内容包括对PG基础的认知、包括安装使用、包括角色权限、包括维护管理、、等内容,希望对热爱PG、学习PG的同学们有帮助,欢迎持续关注CUUG PG技术大讲堂。 Part 9:实例连接访问控制 内容1:PG实例访问控制概述 内容2:pg_hba.conf 文件 内容3:pg_hba.conf 名单格式 内容4:pg_hba.conf 常见配置实例 9.1、PG实例访问控制概述 实例访问控制就像是一道防火墙,用它来控制来自于不同主机、不同用户是否允许访问指定的数据库、以及验证方式。 9.2、pg_hba.conf文件 客户端认证是由一个配置文件(通常名为pg_hba.conf并被存放在数据目录中)控制(HBA表示基于主机的认证)。 在initdb初始化数据目录时,它会安装一个默认的pg_hba.conf文件。不过我们也可以把认证配置文件放在其它地方。 pg_hba.conf文件的常用格式是一组记录,每行一条。空白行将被忽略, #注释字符后面的任何文本也被忽略。记录不能跨行。 一条记录由若干用空格/或制表符分隔的域组成。如果域值用双引号包围,那么它可以包含空格。在数据库、用户或地址域中 引用一个关键字(例如,all或replication) 将使该词失去其特殊 含义,并且只是匹配一个有该名字的数据库、用户或主机。 9.3、pg_hba.conf名单格式 TYPE:指定连接类型 local:表示本地连接,只对Unix/Linux系统有效,使用socket方式登录 host:表示主机通过TCP/IP连接 hostssl:表示主机连接需要SSL加密方式连接 DATABASE:指定连接的数据库 all:表示所有的数据库 db_name:表示指定的数据库 replication:表示主备复制时的连接 USER:指定连接的用户 all:表有所有用户 ? user_name:表示指定的用户 +group_name:表示一组用户 @file_name:表示文件中包含的用户列表 ADDRESS:指定连接的客户端 127.0.0.1/32:表示本地客户端主机 0.0.0.0/0:表示所有客户端主机 host_name:表示指定的主机名(hosts文件中包含) ip_addr/net_mask:表示指定的ip地址或者网段 pg_hba.conf 示例: host all +g1 0.0.0.0/0 md5 #g1组 host all u1 192.168.18.0/24 md5 #某个网段 METHOD:指定验证方式 trust:信任客户端连接,无需提供密码 scram-sha-256:这是当前提供的方法中最安全的一种,但是旧的客户端库不支持这种方法。 md5:它能防止口令嗅探并且防止口令在服务器上以明文存储,但是无法保护攻击者想办法从服务器上窃取了口令哈希的情况。 password:方法password以明文形式发送口令,因此它对于口令“嗅探”攻击很脆弱。 ident:该模式下系统会将请求发起者的操作系统用户映射为PostgesSQL数据库内 部用户,并以该内部用户的权限登录,且此时无需提供登录密码。操作系统用户 与数据库内部用户之间的映射关系会记录在pg_ident.conf文件中。 peer:该模式使用连接发起端的操作系统名进行身份验证。仅限于Linux、BSD、 Mac OS X和Solaris,并且仅可用于本地服务器发起的连接。 reject:该模式表示拒绝所有请求。

Flink 简单的 WordCount 小demo

1.先从数据源获取数据 2.map 给每一个单词打上标记 1 flatmap 3.shuffle 使用keyBy 设置二元组里的key 以便下面reduce 同组处理的时候每个key都在一个组里 4.reduce 将每个元组里的 数值想加起来。 package com.day01; import org.apache.flink.api.common.functions.FlatMapFunction; import org.apache.flink.api.common.functions.ReduceFunction; import org.apache.flink.api.java.tuple.Tuple2; import org.apache.flink.streaming.api.datastream.DataStreamSource; import org.apache.flink.streaming.api.datastream.KeyedStream; import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator; import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.util.Collector; // 从socket消费数据,然后进行单词计数 public class Example1 { // 不要忘记抛出异常 public static void main(String[] args) throws Exception { // 获取流执行环境(上下文) StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); // 从socket消费数据 // nc -lk 9999 // 输出String类型 // `.setParallelism(1)`将`socketTextStream`算子的并行子任务的数量设置为1 DataStreamSource<String> source = env.socketTextStream("localhost", 9999).setParallelism(1); // 从文件获取 // DataStreamSource<String> source = env.

基于quartz实现定时任务管理系统

基于quartz实现定时任务管理系统 背景 说起定时任务框架,首先想到的是Quartz。这是定时任务的老牌框架了,它的优缺点都很明显。借助PowerJob 的readme文档的内容简单带过一下这部分。 除了上面提到,还有elastic-job-lite、quartzui也是相当火热的,可以自行了解一下。 那么都这么多后起之秀,个个吊打quartz,为什么我还选择用quartz来做定时任务?技术是服务于业务的,肯定是有需求呗。公司有个统一管理平台,现在需要开发一个定时任务管理平台,可以动态去管理配置定时任务、查看运行日志。 为什么不考虑其它的框架?由于需求要定制化ui界面和定时任务执行结果接入统一的通知中心等等需求,上面大多数框架都是通过简单配置开箱即用,定制化需要对源码有一定熟悉程度,而quartz我在大学就用了很多次了,非常熟悉,改造相对容易。 需求分析 定时任务的增删改查定时任务执行日志查看 详细设计 开发环境 jdk 1.8 spring boot 2.7.7 quartz 单机版 Mysql 8.0 1. 定时任务的实现 quartz的任务实际是通过内置Java类实现job接口或者继承QuartzJobBean实现executeInternal来实现定时任务的添加。所以我们在管理页面上所做的增删改查操作都不可能是真正意义上地去修改了任务类,而是修改了映射类。举个例子来说,比如Power Job的管理界面 我们修改的这些任务名称、定时信息的持久化操作都不会是操作了真正的任务类,而是修改了一个绑定这个任务类的映射类。如下图中的类就是任务类 而图片中的这些就是属性就是映射类的属性。 你可以先是觉得任务类和映射类之间是一对一的关系,映射类记录了定时任务的执行频率(cron)、名称、任务类完整类名等其它的信息,然后在执行过程中通过完整类名反射获得任务类,任务类再根据这些信息去执行。 但如果每个定时任务,我们都要去实现Job接口创建一个类,相同的那些代码比如获取trigger、scheduler等等,都要出现在每个类中,每次添加一个定时任务都要多一个专门的定时任务类。每次开发时都要关注业务和定时任务类之间的关系,多了之后是有点烦。 我推荐的做法是,创建一个具备http请求功能的任务类,将业务操作开发成一个接口,在配置映射类时,将http链接配置上去,这样一到时间 ,就会请求到对应的业务接口。这样使得后续的定时任务功能开发更专注于业务开发,方便使用。尤其是团队开发中,对一些不熟悉quartz的朋友格外友好。 编码实现 引入依赖 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.31</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.2</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.16</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.11</version> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.

Java面试题(八)链表常见算法题

链表常见算法题 删除链表中元素找到链表中间的元素判断链表是否有环链表反转返回链表值不为空的长度从链表尾部向头移动K个位置 删除链表中元素 先准备链表对象 public class ListNode { private int val; private ListNode prev; private ListNode next; public ListNode(int x){ val = x; } } /** * @description 删除链表[4,5,1,9] 中 5 这个元素 * @param listNode * @return void * @date 2022/12/14 14:39 */ public static void deleteNode(ListNode listNode){ // 当前节点的值改为下个节点的值,例[4,5,1,9]中的5改为1,链表变为[4,1,1,9] listNode.val = listNode.next.val; // 删除下个节点,此时,node.next.next从[1,9]变为[9],链表最后为[4,1,9] listNode.next = listNode.next.next; } 找到链表中间的元素 利用快慢指针来查找,快指针移动步长=2,慢指针移动步长=1,当快指针移动到末尾,此时慢指针一定在中间元素位置 /** * @description 找到链表中间的元素 * @param listNode * @return ListNode * @date 2022/12/14 14:41 */ public static ListNode findMiddleNode(ListNode listNode){ //利用快慢指针查找,步长=1的慢指针,和步长=2的快指针 ListNode fast = listNode; ListNode slow = listNode; // 检测快指针是否可以安全移动 while (fast.

JQuery基础

一、JQuery语法 jQuery 语法是通过选取 (selector)HTML 元素,并对选取的元素执行某些操作(action)。 基础语法: $(selector).action() 美元符号定义 jQuery 选择符(selector)"查询"和"查找" HTML 元素 jQuery 的 action() 执行对元素的操作 实例: $(this).hide() - 隐藏当前元素 $("p").hide() - 隐藏所有 <p> 元素 $("p.test").hide() - 隐藏所有 class="test" 的 <p> 元素 $("#test").hide() - 隐藏 id="test" 的元素 文档就绪 所有 jQuery 函数位于一个 函数中: $(function(){ // 开始写 jQuery 代码... }); 二、JQuery选择器 1、元素选择器 jQuery 元素选择器基于元素名选取元素。 在页面中选取所有 <p> 元素: $("p") 2、#id 选择器 jQuery #id 选择器通过 HTML 元素的 id 属性选取指定的元素。 页面中元素的 id 应该是唯一的,所以您要在页面中选取唯一的元素需要通过 #id 选择器。

使用Arduino开发ESP32-WIFI配网(smartconfig)

smartconfig配网:智能硬件处于混杂模式下,监听网络中的所有报文;手机APP将SSID和密码编码到UDP报文中,通过广播包或组播报发送,智能硬件接收到UDP报文后解码,得到正确的SSID和密码,然后主动连接指定SSID的路由,完成连接 #include "WiFi.h" void setup() { Serial.begin(115200); //初始化Wifi模块为station模式,运行SmartConfig WiFi.mode(WIFI_AP_STA); WiFi.beginSmartConfig(); //等待来自手机的SmartConfig数据包 Serial.println("Waiting for SmartConfig."); while (!WiFi.smartConfigDone()) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("SmartConfig received."); //等待wifi连接至AP Serial.println("Waiting for WiFi"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("WiFi Connected."); Serial.print("IP Address: "); Serial.println(WiFi.localIP()); } void loop() { // put your main code here, to run repeatedly: }

Redis哨兵(Sentinel)模式

前言 上一期实现了Redis的主从复制架构,由于主从模式在主节点宕机故障时整个Redis服务都不能再执行写操作,而无法保证Redis在整个系统中的高可用。 Redis提供了Sentinel哨兵机制来解决以上问题,当哨兵服务监测到master下线或宕机,哨兵会自动选举一个slave作为新的master,然后通过发布订阅模式通知其他所有的从节点,修改配置文件,让它们切换主机 简单的说哨兵就是带有自动故障转移功能的主从架构! 哨兵架构原理 如下是单个哨兵 **原理:**哨兵是通过发送命令到各个节点,然后等待Redis服务器响应的方式,来监控运行的各个Redis节点的状态 若某一时刻由于网络延迟等原因(但实际master并未出现故障),哨兵一直未收到master节点的状态响应,而选举了新的master,导致出现了多个master,引起主从复制错乱,这种情况称为——脑裂 脑裂情况的存在实际中会使用多哨兵模式:哨兵除了监控各个Redis服务节点的状态之外,哨兵之间也会互相监控 假设master节点故障,哨兵1先检测到了这个结果,仅仅是哨兵1主观的认为master节点不可用,系统并不会马上进行failover故障转移,选举新master的过程,当一半以上的哨兵也检测到master不可用时,那么哨兵之间就会进行一次投票选举,选举一个slave作为新的master,再由一个哨兵进行failover操作。切换成功后,就会通过发布订阅模式,通知各个哨兵和slave切换master 一主二从三哨兵 搭建哨兵架构 在上一期搭建好的Redis主从复制架构的基础上,完成Redis多哨兵模式的搭建 1、在redis源码包目录下复制出sentinel.conf文件到redis安装的根目录并按如下修改 - sentinel1 # 开启守护线程的(后台)方式启动 daemonize yes # 关闭保护模式 protected-mode no # 哨兵服务默认端口是26379 port 26379 # 哨兵模式默认工作目录 dir /tmp # 监控的redis主节点服务,mymaster是可自定义的服务名 # 2 代表有两个或两个以上的哨兵认为master不可用的时候,才会进行故障转移操作 sentinel monitor mymaster 192.168.31.161 8001 2 # redis.conf中开启了requirepass,所有连接Redis服务的客户端(包括哨兵)都要提供访问密码 sentinel auth-pass mymaster 123456 - sentinel2 daemonize yes protected-mode no port 26380 dir /tmp sentinel monitor mymaster 192.168.31.161 8001 2 sentinel auth-pass mymaster 123456 - sentinel3 daemonize yes protected-mode no port 26381 dir /tmp sentinel monitor mymaster 192.

【Flutter入门到进阶】Flutter基础篇---弹窗Dialog

1 AlertDialog 1.1 说明 最简单的方案是利用AlertDialog组件构建一个弹框 1.2 示例 void alertDialog(BuildContext context) async { var result = await showDialog( barrierDismissible: false, //表示点击灰色背景的时候是否消失弹出框 context: context, builder: (context) { return AlertDialog( title: const Text("提示信息!"), content: const Text("您确定要删除吗"), actions: [ TextButton( onPressed: () { print("ok"); Navigator.of(context).pop("ok"); //点击按钮让AlertDialog消失 }, child: const Text("确定")), TextButton( onPressed: () { print("cancel"); Navigator.of(context).pop("取消"); }, child: const Text("取消")) ], ); }); print("-----------"); print(result); } 2 SimpleDialog 2.1 说明 通过SimpleDialog构建一个选择框 2.2 示例 void simpleDialog(BuildContext context) async { var result = await showDialog( barrierDismissible: false, //表示点击灰色背景的时候是否消失弹出框 context: context, builder: (context) { return SimpleDialog( title: const Text("

sftp方式下载、上传、删除

注意:在实际使用中,如果SFTP有中文名件名,部分LINUX系统会出现报错情况,找不到文件 No such file // 可利用反射修改版本编号,从而可修改编码,解决中文文件名不能下载的问题 Class cl = ChannelSftp.class; Field field = cl.getDeclaredField(“server_version”); field.setAccessible(true); field.set(sftp, 2); sftp.setFilenameEncoding(“GBK”); import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Properties; import java.util.Vector; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.JSch; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.Session; import com.jcraft.jsch.SftpException; /** * 类说明 sftp工具类 */ public class SFTPUtil { private transient Logger log = LoggerFactory.getLogger(this.getClass()); private ChannelSftp sftp; private Session session; /** SFTP 登录用户名*/ private String username; /** SFTP 登录密码*/ private String password; /** 私钥 */ private String privateKey; /** SFTP 服务器地址IP地址*/ private String host; /** SFTP 端口*/ private int port; /** * 构造基于密码认证的sftp对象 */ public SFTPUtil(String username, String password, String host, int port) { this.

ONVIF客户端搜索设备获取rtsp地址开发笔记(精华篇)

概要: 目前ONVIF协议家族设备已占据数字监控行业半壁江山以上,亲,作为开发者的你还在犹豫是否了解下吗?本文介绍了ONVIF客户端从设备搜索,鉴权,能力获取,媒体信息获取,URI地址获取的整套流程。文章只讲述了比较重要或其他博文没有讲述的开发点,详细可以参考文末参考文章。最后,能获得rtsp地址之后,然后去做其他功能比如录像,ptz这些就非常得心应手了。本文出自CSDN-固本培元 ,转载注明出自:leolupy@gmail.com。 前言及鸣谢: 感谢guog先生,快活林高先生,onvif全国交流群的的酷夏先生在开发过程中给予的巨大支持,没有你们的帮助开发过程将异常艰难啊。谢谢了! ONVIF介绍: ONVIF致力于通过全球性的开放接口标准来推进网络视频在安防市场的应用,这一接口标准将确保不同厂商生产的网络视频产品具有互通性。2008年11月,论坛正式发布了ONVIF第一版规范——ONVIF核心规范1.0。随着视频监控的网络化应用,产业链的分工将越来越细。有些厂商专门做摄像头,有些厂商专门做DVS,有些厂商则可能专门做平台等,然后通过集成商进行集成,提供给最终客户。这种产业合作模式,已经迫切的需要行业提供越来越标准化的接口平台。 流程总览: 本文开发环境:Centos6.4 Gsoap:2.8.16 soap:1.2 onvif:2.4 。 注: 本文提供的参考代码其实网上都可以找到,这里做一个整理,供大家交流学习,共同提高。 搜索:Probe: 发现网络摄像头,获取webserver地址:http://192.168.15.240/onvif/device_service能力获取:GetCapabilities:获取设备能力文件,从中识别出媒体信息地址URI: http://192.168.15.240/onvif/Media媒体信息获取:GetProfiles: 获取媒体信息文件,识别主通道、子通道的视频编码分辨率RTSP地址获取:GetStreamUri:获取指定通道的流媒体地址 rtsp://192.168.15.240:554/Streaming/Channels/2?transportmode=unicast Gsoap及开发框架生成: 1. 下载Gsoap 地址: http://sourceforge.net/projects/gsoap2/files/gSOAP/ 2. 安装 ./configure && make && make install 期间可能会有一些报错,自己解决哦。 3. 离线或者在线生成onvif.h。 如果不需要最新的版本推荐离线方式。笔者使用的是这种方式。离线文件下载地址:http://download.csdn.net/detail/u011597695/5875143(感谢guog先生的共享) 记得拷贝gsoap的typemap文件至生成目录下,wsdl2h命令需要这个。 在线命令: wsdl2h -o onvif.h -c -s -t ./typemap.dat http://www.onvif.org/onvif/ver10/device/wsdl/devicemgmt.wsdl http://www.onvif.org/onvif/ver10/media/wsdl/media.wsdl http://www.onvif.org/onvif/ver10/event/wsdl/event.wsdl http://www.onvif.org/onvif/ver10/display.wsdl http://www.onvif.org/onvif/ver10/deviceio.wsdl http://www.onvif.org/onvif/ver20/imaging/wsdl/imaging.wsdl http://www.onvif.org/onvif/ver20/ptz/wsdl/ptz.wsdl http://www.onvif.org/onvif/ver10/receiver.wsdl http://www.onvif.org/onvif/ver10/recording.wsdl http://www.onvif.org/onvif/ver10/search.wsdl http://www.onvif.org/onvif/ver10/network/wsdl/remotediscovery.wsdl http://www.onvif.org/onvif/ver10/replay.wsdl http://www.onvif.org/onvif/ver20/analytics/wsdl/analytics.wsdl http://www.onvif.org/onvif/ver10/analyticsdevice.wsdl http://www.onvif.org/ver10/actionengine.wsdl http://www.onvif.org/ver10/pacs/accesscontrol.wsdl http://www.onvif.org/ver10/pacs/doorcontrol.wsdl 离线命令: wsdl2h -o onvif.h -c -s -t .

vue中生成二维码的两种用法

一,qrcode 生成二维码 安装 npm i qrcodejs2 --save 引入 import QRCode from 'qrcodejs2' <div class="qrcode" ref="qrCodeUrl"></div> <script> import QRCode from 'qrcodejs2' export default { data() { return { }, methods: { creatQrCode() { var qrcode = new QRCode(this.$refs.qrCodeUrl, { text: 'https://blog.csdn.net/weixin_42601136', // 需要转换为二维码的内容 width: 100, height: 100, colorDark: '#000000', colorLight: '#ffffff', correctLevel: QRCode.CorrectLevel.H }) }, }, mounted() { this.creatQrCode(); }, }; </script> 二,vue-qr 生成 二维码 图片 安装 npm i vue-qr --save import vueQr from 'vue-qr' <vue-qr :logoSrc="

echarts 渲染图表出错 Cannot read properties of undefined (reading ‘$echarts‘)

[Vue warn]: Error in mounted hook: "TypeError: Cannot read properties of undefined (reading '$echarts')" 报错的原因是没能指向 echarts。 <script> export default { name: '', components: {}, props: { id: { type: String, default: 'radar3', }, width: { type: String, default: '100vw', }, height: { type: String, default: '50vh', }, }, data() { return {}; }, computed: {}, watch: {}, created() { // }, mounted() { // this.myCharts(); }, methods: { myCharts() { const myChart = this.

【Java】随机创建数字和随机点名之random用法

随机数字: 题目要求: 这是一个有趣的数字游戏,计算机随机创建一个1-100之间的数字,我们也无从得知该数字是多少只能根据提示来猜测。 此处我们会利用到Java的random函数 int rnumber=(int)(Math.random()*100)+1;//随机生成一个1-100的数字 int rnumber=(int)(Math.random()*10)+1;//随机生成一个1-10的数字 还有一种表达方式: Random random = new Random();//需要先引用 int rnumber=random.nextInt(100)+1;//随机生成一个1-100的数字 package myjava; import java.util.Random; import java.util.Scanner; public class A { public static void main(String[] args) { Scanner s=new Scanner(System.in); //先随机生成一个0-100的数字 Random random = new Random(); int rnumber=random.nextInt(100)+1; System.out.println("来和我玩个游戏吧!"); System.out.println("请输入一个1-100之间的数字:"); int number=s.nextInt(); while(number!=rnumber) { if(number<rnumber) { System.out.print("太小了!"); } else { System.out.print("太大了!"); } System.out.print("请继续猜:"); number=s.nextInt(); } System.out.println("恭喜!猜对了!"); } } 测试结果: 随机点名: 原理相同 代码如下: package myjava; import java.

【机器学习】二分类+多分类LDA线性判别分析降维算法的原理与推导

不同于PCA方差最大化理论,LDA算法的思想是将数据投影到低维空间之后,使得同一类数据尽可能的紧凑,不同类的数据尽可能分散。 它的数据集的每个样本是有类别输出的,投影后类间方差最大,类内方差最小 LDA需要数据满足如下两个假设: 原始数据根据样本均值进行分类不同类的数据拥有相同的协方差矩阵 一般来说第2条很难满足,所以在实际使用中如果原始数据主要是根据均值来划分的,此时LDA降维效果很好,但是PCA效果就很差,如下图: PCA是寻找数据集中方差最大的方向作为主成分分量的轴,而LDA是最优化分类的特征子空间。因此PCA和LDA各有适用情况,需要根据数据对症下药。 先对整个问题做个定义: 已有如下的数据集 D = ( x 1 ( 1 ) , x 2 ( 1 ) , ⋯ , x n ( 1 ) ) , ( x 1 ( 2 ) , x 2 ( 2 ) , ⋯ , x n ( 2 ) ) , ⋯ , ( x 1 ( k ) , x 2 ( k ) , ⋯ , x n ( k ) ) D=(x_1^{(1)},x_2^{(1)},\cdots,x_n^{(1)}),(x_1^{(2)},x_2^{(2)},\cdots,x_n^{(2)}),\cdots,(x_1^{(k)},x_2^{(k)},\cdots,x_n^{(k)}) D=(x1(1)​,x2(1)​,⋯,xn(1)​),(x1(2)​,x2(2)​,⋯,xn(2)​),⋯,(x1(k)​,x2(k)​,⋯,xn(k)​),共k个样本

Node(Next.js)+node-xlsx开发导出excel功能

项目中的功能:通过点击【导出】按钮,将列表的数据转成excel文件导出。这个功能有多种处理方法,我这边分为Node(后端)+前端联合处理、纯Node(后端)处理 一、Node+前端 在Node层直接将数据处理成前端生成excel文件时需要的数据格式,然后将生成excel文件的方法封装(exportXlsx)之后,调用node层的接口获取数据之后直接传给exportXlsx const xlsx = require('node-xlsx'); //exportXlsx方法 function exportXlsx(worksheets, fileName = '测试') { const result = xlsx.build(worksheets); const ab = Buffer.from(result, 'binary'); const blob = new Blob([ab]); const blobUrl = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = blobUrl; a.download = fileName; a.click(); window.URL.revokeObjectURL(blobUrl); } 注意:worksheets的数据格式:[{ name: 'Sheet1', data:[['表头1','表头2','表头3'],['第1行第1列内容','第1行第2列内容','第1行第3列内容']] }] 二、纯Node端 直接在node层将文件流传输给客户端,这种处理方式也有两种方法 1、一种是使用node-xlsx创建了一个excel文件,然后将其保存到本地,最后将其发送给前端。 这种方法因为使用fs.createReadStream()是读取本地文件流的,因此需要将excel文件保存到本地,并将其作为流传输到客户端,会造成磁盘空间的浪费和读写磁盘的开销,因此不推荐,了解即可。 import fs from 'fs'; import path from 'path'; import xlsx from 'node-xlsx'; export default (req, res) => { // 创建一个excel文件 const data = [ ['姓名', '年龄', '性别'], ['张三', 18, '男'], ['李四', 20, '女'], ['王五', 22, '男'], ]; const buffer = xlsx.

VS+Qt — Vistual Studio 2022+Qt6安装教程以及解决Qt Vistual Studio Tools下载慢和VS无法打开.ui进行设计的问题

目录 Vistual Studio 2022下载 Qt下载 Qt Vistual Studio Tools下载 方法1 方法2 方法3 方法4 Vistual Studio 2022配置Qt6 创建Qt项目 若VS无法打开.ui进行设计 Vistual Studio 2022下载 以前因为安装库的关系,已经下载过VS2022了,详细请看这里:内含VS2022安装。 Qt下载 Qt下载路径:直通车 我们用不着多想,选择开源版本就是给官方最大的支持。 进入后上面是一些条约,拉到这个地方,点进去。 进入这里后就可以对它进行点击下载了。大家都知道涉及到国外的普遍原因,大概要个四五分钟,我觉得等的起,起来倒俩杯水的功夫。 浏览器下载的默认地址里面就有这个.exe文件: 在你空闲的盘里,新建一个纯英文路径,将这个.exe文件移动到这个路径下。 先注册好吧,大家用QQ邮箱就行,去验证一波。 我是个人用户,勾选上。 改地址,因为是和VS配置,我放在了我下载VS的路径下的文件夹中。 组件没必要全选。 又是协约,后面的请你一路通过就行。我勾了两个组件都有一个G了,好像全部都选就有十几个G。 Qt Vistual Studio Tools下载 有点点慢,我们可以先跳过这里,先打开Vistual Studio2022: 方法1 根据流程图做,点击管理扩展后搜索qt,点击这里第一个扩展安装。 没有梯子的话,这里也很慢;实在等不下去了,我们换一种方法。 方法2 来到官网当中,找到它的离线包下载:Qt Visual Studio Tools - Visual Studio Marketplace 方法3 结果同样因为网络问题,无法下载。那没有办法,我只好去清华镜源看看有没有了。 目录如下: Index of /qt/archive/vsaddin/2.8.1/ 每个版本下面好像都有对应的版本。 方法4 这是后面我重启之后,VS2022给的一个提示中提供的链接,意思是有更高的版本可以下载: Index of /development_releases/vsaddin/2.10.0 (qt.io) 进入这里下载也挺快的,但我已经下载好了。 我是通过方法3这次很快就完成了,我就说一个大小才20MB的文件,至于下载速度搞得比百度网盘还有慢吗?完成下载后,记得要关闭你的VS2022。 OKOKokk,终于弄完了。 Vistual Studio 2022配置Qt6 重新进入Vistual Studio 2022 点击扩展->Qt VS Tool->Qt Versions

Scrcpy手机投屏

Scrcpy投屏(电脑操作手机)@TOC Scrcpy投屏软硬件要求 Android设备至少需要5.0以上版本(即API 21)确保在电脑设备上启动了adb调试在某些设备上,还需要启动其他选项以使用建买盘和鼠标。链接: 其它选项 adb调试的开启一般是多次点击手机系统的版本号,比如vivoS15pro:设置-系统管理-关于手机-版本信息-软件版本号,然后就是开启“开发者选项”:设置-系统管理-开发者选项-点击开发者选项-点击USB调试和USB调试(安全模式) 备注:USB辞退(安全设置)必须开启,否则达不到电脑控制手机 Scrcpy下载地址 下载地址:https://github.com/Genymobile/Scrcpy/releases 将下载后的zip压缩包进行解压 通过USB数据线连接 手机通过USB连接到PC端上,手机弹出是否连接,直接点击“确认”。运行adb usb查看是否连接成功在文件路径下使用cmd直接运行scrcpy.exe即可 无线连接 官方参考文档: 确保PC和手机连接在同一Wifi中 手机先通过USB与PC相连,打开开发者模式,勾选USB调试 在安装路径下打开终端输入:adb devices(验证USB是否连接成功) 在PC上运行adb tcpip服务端口, 1). 在安装路径下运行cmd,输入:adb tcpip 端口号(此处设置5555端口) 2). 断开USB连接,在cmd输入:adb connect 手机ip:端口号(手机ip可在关于手机-状态信息里查看) 3). 想要断开输入:adb disconnect 手机ip //断开指定IP 、adb disconnect //断开所有 4). 第二次连接的时候无需数据线了,在保证电脑和手机在同一个局域网的情况下直接在终端输入: adb connect 192.168.xxxx.xxxx:5555 (192.168.xxxx.xxxx为你手机的ip地址,5555为了设置·的端口号)就可以成功连接了

linux centos7配置,发送邮件到qq邮箱。

在日常工作中经常需要编辑shell脚本发送邮件通知,譬如:内存CPU告警之类的。这篇文章配置linux自带的mail可以实现向外部smtp发送邮件。 首先第一步:开启QQ邮箱的服务,得到授权码之后,放到一边等会有用 第二步:编辑 vi /etc/mail.rc 文件 set from=test1111@qq.comset smtp=smtps://smtp.qq.com:465set smtp-auth-user=test111@qq.comset smtp-auth-password=[第一步的授权码]set smtp-auth=loginset nss-config-dir=/etc/pki/tls/certsset ssl-verify=ignore #1#发送的邮箱地址 #2#如果是465端口,需要加上smtps://协议;如果是587端口,不需要加smtps://或者写smtp://; #3#发送的邮箱地址 #4#你的QQ邮箱授权码 #5#认证方式 为默认 #6#放置后续操作QQ邮箱SSL证书所在的目录,(可以自行定义) #7#忽略证书警告 第三步:生成QQ邮箱证书 -d表示证书所在目录,-i指示证书文件的位置 echo -n | openssl s_client -connect smtp.qq.com:465 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' >/etc/pki/tls/certs/qq.crtcertutil -A -n "GeoTrust SSL CA" -t "C,," -d /etc/pki/tls/certs -i /etc/pki/tls/certs/qq.crtcertutil -A -n "GeoTrust Global CA" -t "C,," -d /etc/pki/tls/certs -i /etc/pki/tls/certs/qq.crtcertutil -L -d /etc/pki/tls/certscd /etc/pki/tls/certscertutil -A -n "GeoTrust SSL CA - G3"

SQLzoo刷题记录-The JOIN operation/zh

id(編號)mdate(日期)stadium(場館)team1(隊伍1)team2(隊伍2)10018 June 2012National Stadium, WarsawPOLGRE10028 June 2012Stadion Miejski (Wroclaw)RUSCZE100312 June 2012Stadion Miejski (Wroclaw)GRECZE100412 June 2012National Stadium, WarsawPOLRUS... goal(入球) matchid(賽事編號)teamid(隊伍編號)player(入球球員)gtime(入球時間)1001POLRobert Lewandowski171001GREDimitris Salpingidis511002RUSAlan Dzagoev151001RUSRoman Pavlyuchenko82... eteam(歐洲隊伍) id(編號)teamname(隊名)coach(教練)POLPolandFranciszek SmudaRUSRussiaDick AdvocaatCZECzech RepublicMichal BilekGREGreeceFernando Santos... 1.列出 賽事編號matchid 和球員名 player ,該球員代表德國隊Germany入球的。要找出德國隊球員,要檢查: teamid = 'GER' SELECT matchid,player FROM goal WHERE teamid = 'GER' 2.只顯示賽事1012的 id, stadium, team1, team2 SELECT id,stadium,team1,team2 FROM game where id=1012 3.顯示每一個德國入球的球員名,隊伍名,場館和日期。 SELECT s.player,s.teamid,t.stadium,t.mdate FROM game t JOIN goal s ON (t.id=s.matchid) where s.

基于Python的云南旅游景点分析

作为一名云南人,作为一名数据分析人员,我将在本次用Python来给大家介绍云南的相关景点! 欢迎大家来云南旅游哦!资料含各地景点的数据,希望大家学习之后进行相关的练习,学有所成! 所需的资料我放在这里,自行提取即可: 链接:https://pan.baidu.com/s/16ziypbHZL-ZNNxnVQ2-iXg 提取码:yunn 使用工具:Jupyter Notebooks 推荐查看链接自主下载和学习:Jupyter Notebooks的安装和使用介绍_LarsCheng的博客-CSDN博客_jupyter “彩云之南”旅游景点分析 1.导入需要的包 Pandas — 数据处理 Pyecharts — 数据可视化 jieba — 分词(jupyter做文本分析经常导入的两个包jieba和wordcloud_努力的搬运工的博客-CSDN博客_jupyter怎么安装jieba) collections — 数据统计 !pip install --upgrade pyecharts #升级 pyecharts 包,地图显示部分需要用到 pyecharts==1.9.0以上版本 import jieba#中文分词处理 import pandas as pd #数据处理库 from collections import Counter#数据统计库 from pyecharts.charts import Line,Pie,Scatter,Bar,Map,Grid#pyecharts数据可视化 from pyecharts.charts import WordCloud from pyecharts import options as opts from pyecharts.globals import ThemeType from pyecharts.globals import SymbolType from pyecharts.commons.utils import JsCode 2.数据处理 2.

springcloud3 Sentinel的搭建以及案例操作

一 sentinel的概念 1.1 sentinel Sentinel是分布式系统流量控制的哨兵,阿里开源的一套服务容错的综合性解决方案。 主要用来处理: 服务降级 服务熔断 超时处理 流量控制 sentinel 的使用可以分为两个部分: 核心库(Java 客户端):不依赖任何框架/库,能够运行于 Java 8 及以上的版本的运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。 控制台(Dashboard):Dashboard 主要负责管理推送规则、监控、管理机器信息等。基于 Spring Boot 开发,打包后可以直接运行。 二 sentinel的安装 2.1 sentinel的安装 中文文档: quick-start | Sentinel 程序包下载: Releases · alibaba/Sentinel · GitHub 启动jar包 F:\>java -jar sentinel-dashboard-1.7.2.jar 页面访问: sentinel / sentinel 输入地址: http://localhost:8080/ 三 sentinel的各种用途 3.1 实时监控 3.1.1 架构图 3.1.2 sentinel消费项目 1.pom <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13</version> <scope>test</scope> </dependency> <!--SpringCloud ailibaba nacos --> <dependency> <groupId>com.

php对接百度网盘开发平台API开发高级实战案例解析:(环境部署、php封装类、Access Token获取、预上传、分片上传)

文章目录 前言一、环境部署1.封装BdPan类库2.回调地址配置 二、获取授权码Code1.手动获取Code2.生成本地token3.读取AccessToken凭证4.爬虫函数 二、简化模式授权三、网盘基础服务1.获取用户信息2.获取网盘容量信息3.递归获取文件列表4.预上传5.分片上传6.创建文件 总结 前言 百度网盘是国民级的个人云盘产品,有着先进安全的云存储与传输技术,通过多年积累沉淀的解决方案,来满足不同行业不同阶段合作伙伴的个性化需求,降低开发和购买成。在开放平台,你可以方便快捷地实现应用、设备与百度网盘的连接互通:数据的上传、网盘文件的管理与下载、场景化的影音与相册服务、开发一个小程序入驻网盘等等能力。 传送门 >> 百度网盘开放平台 一、环境部署 1.封装BdPan类库 封装BdPan.php百度网盘开发类; class BdPan { const AppID = '303***'; const Appkey = 'zsBbkMiTO5L86FST***'; const Secretkey = 'RHwNALMZcLWjluHn***'; const RedirectUri = 'http://test.com/pan/getcode.php'; //构造函数 public function __construct($AppID = '', $Appkey = '', $Secretkey = '') { $AppID = self::AppID; $Appkey = self::Appkey; $Secretkey = self::Secretkey; //核检常量参数 $this->check_auth($AppID, $Appkey, $Secretkey); } //判断Appkey是否为空 public function check_auth($AppID, $Appkey, $Secretkey) { if ($AppID == '') { die('AppID不能为空'); } if ($Appkey == '') { die('Appkey不能为空'); } if ($Secretkey == '') { die('Secretkey不能为空'); } } } 2.

node安装指南

很多时候,不同的项目需要不同的node版本,我们不断的切换版本来开发项目,一次次的卸载安装效率非常低,所以我们可以使用nvm(node版本管理器)来管理node的版本,在每次使用不同的版本时,就可以通过nvm来切换node版本 1. nvm安装 首先我们下载nvm,下载地址:https://github.com/coreybutler/nvm/releases,我们下载setup的安装版,如下图 下载完成后进行解压安装,下图是选择安装地址 然后是快捷地址,之后一直点击下一步直至安装 2. 安装node 安装成功后即可通过nvm命令进行安装node,如 nvm install 14.7.0 // 安装14.7.0版本的nodejs 当安装多个node版本时,可以使用nvm use 版本号进行版本切换 nvm use 14.7.0 查看本地nvm有哪些node版本 nvm list 3. 修改镜像 默认的npm地址下载资源很慢,所以我们修改镜像地址来提高资源下载速度。下面的设置npm镜像和安装cnpm镜像其二选一 查看镜像地址 npm config get registry 设置npm镜像(直接修改npm的镜像地址) npm config set registry https://registry.npm.taobao.org 安装cnpm镜像(修改了npm默认镜像,可以不用安装cnpm) npm install -g cnpm --registry=https://registry.npm.taobao.org 以后使用npm命令时替换为cnpm即可 4. 安装vue 我们安装node之后,可以安装vue来创建vue项目 npm install -g @vue/cli

一步解决新版微信接收文件为只读属性的问题、附带多开和消息防撤回功能

最近PC端微信又进行了一次版本更新,这次更新最令用户难受的一个“新功能”恐怕就是接收到的文件为“只读”属性了,用户要想在接收到的文件中保存修改,需要以“另存”一个副本的方式进行。可能微信官方是出于安全性考虑才做出的这一调整,但目前实属有点用不习惯。 现在有办法解除这个限制了,除此之外还有两个附加功能~ 一、软件简介 这次问题的解决方案不是工具,而是一个补丁,这次的补丁更具有针对性,只对微信有效,这个补丁可以解除接收文件只读属性的限制、还支持消息防撤回(并带有撤回提示)以及实现PC端微信多开,且在微信更新后不需要重复执行打补丁的操作。 二、使用方法 使用方法非常简单,解压后只有一个文件:【version.dll】,我们找到微信安装目录中的【WeChat】文件夹,将【version.dll】复制进这个目录即可。 【注意】:补丁【version.dll】所在的文件夹必须是安装路径中【WeChat】文件夹,不要放错了路径,否则不起作用。如果安装时没有手动设置安装位置,则默认安装路径为:C:\Program Files (x86)\Tencent\WeChat 将补丁复制到指定位置后,重启应用即可~ 补丁安装成功后,多次启动微信将出现多个登录窗口,轻松实现多开~ 三、下载链接 https://pan.baidu.com/s/1P4Se1jspHcOKt4fFNOWyvw?pwd=luem https://donot996.lanzoub.com/iCOC70p80gej

GeoServer系列-REST接口初识

GeoServer 提供了一系列接口可供开发者读写图层数据,java中也有工具包封装了这些rest接口 1,官网接口文档 https://docs.geoserver.org/stable/en/user/rest/index.html web界面上的操作都可以找到接口实现,如创建存储空间,创建数据仓库,发布图层,查询图层等 举几个常见的接口例子如下: 1.1 发布shp图层 先从官网API文档上查看参数描述 https://docs.geoserver.org/latest/en/api/#1.0.0/datastores.yaml 使用postman先测试下 需要注意请求头需要加用户名密码的验证 接口验证信息使用 用户名:密码 加密得到 String client = "admin:geoserver"; client = Base64.getEncoder().encodeToString(client.getBytes()); System.out.println("Basic " + client); == 经测试压缩包解压后要有shp文件而不是文件夹,不支持中文shp包,不支持中文的问题后续文章会从源码找问题并处理 == 1.2 查询图层列表 https://docs.geoserver.org/latest/en/api/#1.0.0/layers.yaml 可以查询所有发布图层,也可以按指定工作空间查询 图层基本信息,包含样式详情和属性详情链接 1.3 查询图层特征属性信息 https://docs.geoserver.org/latest/en/api/#1.0.0/featuretypes.yaml 属性信息包含图层的所有信息,包含存储仓库,坐标系,边界坐标,属性列表,点线面类型等等 2,JAVA 中调用接口 2.1使用原生接口调用 chatGPT提供的一个朴实无华的demo,用上面发布shp文件举例 package example; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.Base64; public class GeoServerRESTAPIExample { public static void main(String[] args) throws IOException { String gsUrl = "

java求输入一个正整数,计算并输出整数的各位数字之和

输入一个正整数,计算并输出整数的各位数字之和。 如输入12345,结果显示15,如下图所示。 【代码如下】: import java.util.Scanner; public class NumSum{ public static void main(String[] args){ Scanner sc=new Scanner(System.in); int num=sc.nextInt(); int sum=0; int flag=10; while(num>0){ sum=sum+num%flag; num=num/flag; } System.out.println(sum); } }

java输入一个整数数组,求数组的和、平均值

输入一个整数数组,求数组的和、平均值。 例如输入一个长度为2的数组,程序运行如下: 【代码如下】: import java.util.Scanner; public class NumArray{ public static void main(String[] args){ System.out.print("请输入数组中元素个数:"); Scanner sc=new Scanner(System.in); int num=sc.nextInt(); int sum=0; for(int i=1;i<=num;i++){ System.out.print("请输入第"+i+"个元素:"); int n=sc.nextInt(); sum=sum+n; } System.out.println("数组的和为"+sum); System.out.println("数组的平均值为"+1.0*sum/num); } }

算法学习:Java实现背包问题

1、0-1背包问题 物品重量价格吉他11500音响43000电脑32000 背包的填表过程: 物品\重量0磅1磅2磅3磅4磅00000吉他01500150015001500音响01500150015003000电脑01500150020002000+1500=3500 代码实现如下(两种方式:一纬数组和二维数组) public class Main { public static void main(String[] args) { int totalweight = 4; int values[] = {1500, 3000, 2000}; int weights[] = {1, 4, 3}; System.out.println(bag(totalweight,weights,values)); System.out.println(bag01(totalweight, weights, values)); } //二维数组实现背包问题 public static int bag(int totalV, int[] weights, int[] values) { if (weights == null || weights.length == 0) { return 0; } int n = weights.length; int m = totalV; //创建二维数组,v[i][j]表示在前i个物品中能够装入容量为j的背包中的最大价值 int[][] v = new int[n + 1][m + 1]; //初始化第一行和第一列,这里本程序可以不用处理,因为默认就是0 for (int i = 0; i < v.

两周年-我的创作纪念日

没想到自己在CSDN更文已经两年了,不知不觉大学已经过去了两年半,回想起当初大一时从老师的口中知道CSDN技术分享平台,然后下载了,当时完全就是一个小白,看到CSDN里的文字章感觉都好深奥啊。后来在一次学长学姐交流会中,我从一位学长的分享中知道他在CSDN有1W+的粉丝,羡慕不已,也是从那一次萌生了自己在CSDN写文章的想法。

Nginx(三):日志

nginx支持两种日志:error_log 和 access_log 1.error_log nginx 日志级别支持:debug | info | notice | warn | error | crit | alert | emerg,错误级别从左到右越来越大。 nginx日志保存位置支持:syslog(远端日志服务器),内存,本地保存 error_log语法格式 Syntax: error_log file [level]; Default: error_log logs/error.log error; error_log logs/error.log error; Context: main, http, mail, stream, server, location 内存(memory) 我们在配置存储路径时,还可以配置memory,而这种配置效果,更多的是在测试Debug阶段。正式上线阶段一般不使用该配置。示例效果如下: error_log memory:32m debug; error_log 可以在main,http,mail,stream,server,loaction 范围中定义。 通常默认情况下会在main中创建。我们也可以根据自己的需求,在不同的权限范围中定义不同的error错误输出等级和地址。 stream(需要nginx 1.7.11版本及以上),mail(需要nginx 1.9.0版本及以上)。 示例: error_log /path/to/log debug; http { server { error_log /path/to/log debug; ... } 大部分情况下,我们都是创建一个main级别的就可以了。没有必要创建server级别的。如果我们定义了server级别的,建议可以注释掉main级别的。 我们默认安装,没有修改过error日志时,nginx提供的默认日志,将error.log 文件导出后效果如下: 2022/11/17 03:35:10 [warn] 2121534#2121534: *1779322 an upstream response is buffered to a temporary file 后面我就省略了 2022/11/17 09:08:44 [crit] 2121534#2121534: *1783300 SSL_do_handshake() failed (SSL: error:141CF06C:SSL routines:tls_parse_ctos_key_share:bad key share) while SSL handshaking,后面我就省略了 2022/11/17 17:07:17 [emerg] 2312144#2312144: unknown directive "

【漏洞复现】vulhub php文件包含漏洞

该实验借鉴了几位大佬的操作步骤,使用自己的环境复现了一下,在这里感谢大佬们的教程[鞠躬] 实验环境: 使用vulhub搭建漏洞环境 实验步骤: 拉取镜像,运行镜像生成容器 访问环境 http://IP/phpinfo.php 访问http://IP:8080/lfi.php,使用GET方法传输参数?file=/etc/passwd,可见的确存在文件包含漏洞 利用脚本exp.py实现了上述过程,成功包含临时文件后,会执行<?php file_put_contents('/tmp/g', '<?=eval($_REQUEST[1])?>')?>,写入一个新的文件/tmp/g,这个文件就会永久留在目标机器上。 在vulhub/php/inclusion目录下已经存在exp.py脚本,直接用就可以了 利用lfi.php页面getshell 如有错误,欢迎批评指正[鞠躬]

SpringBoot动态加载外部数据源

首先确定你的项目使用的动态数据源是spring-jdbc的还是苞米豆(baomidou)的dynamic-datasource-spring-boot-starter,苞米豆是对spring动态数据源的进一步封装,使用起来更容易,此次是针对使用苞米豆动态数据源依赖的使用。 动态加载外部数据源,意思是在容器启动的过程中,通过查询数据库表中配置的数据库连接要素,来动态的将该数据源加入到Bean中。而不是网上很多文章说的“Springboot如何使用动态数据眼,如何切换数据源”。 动态的加载外部数据源,比如说你要开发一个数据源管理模块,里面配置了四面八方的数据源信息,项目启动的时候或者项目运行的时候,可以把这些数据源都加载到项目中,而不是提前显示的配置到application.yml或者application.properties文件中。 =======================分割线======================= 定义数据源实体。 /** * */ package com.ims.system.datasource.entity; import com.ims.core.entity.DataEntity; import lombok.Data; /** * sys_data_sourceEntity * @author admin * @version 2023-02-21 */ @Data public class SysDataSource extends DataEntity<SysDataSource> { private static final long serialVersionUID = 1L; private String key; // 数据源别名 private String name; // 数据源名称 private String descStr; // 数据源描述 private String dbType; // 数据源类型 private String driveClassName; // 数据源驱动 private String type; // 数据源连接池 private String userName; // 用户 private String passWord; // 密码 private String url; // 连接url private String connStatus;//当前连接状态 } 实现数据源实体的dao层service层以便实现增删改查。

Spring IoC原理及简单实现

介绍 Spring 的两大特性 IoC和AOP IoC 在 Java 软件开发过程中,系统中的各个对象之间、各个模块之间、软件系统和硬件系统之间,或多或少都存在一定的耦合关系。 若一个系统的耦合度过高,那么就会造成难以维护的问题,但完全没有耦合的代码几乎无法完成任何工作,这是由于几乎所有的功能都需要代码之间相互协作、相互依赖才能完成。因此我们在程序设计时,所秉承的思想一般都是在不影响系统功能的前提下,最大限度的降低耦合度。 IoC 底层通过工厂模式、Java 的反射机制、XML 解析等技术,将代码的耦合度降低到最低限度,其主要步骤如下。 在配置文件(例如 Bean.xml)中,对各个对象以及它们之间的依赖关系进行配置;我们可以把 IoC 容器当做一个工厂,这个工厂的产品就是 Spring Bean;容器启动时会加载并解析这些配置文件,得到对象的基本信息以及它们之间的依赖关系;IoC 利用 Java 的反射机制,根据类名生成相应的对象(即 Spring Bean),并根据依赖关系将这个对象注入到依赖它的对象中。 由于对象的基本信息、对象之间的依赖关系都是在配置文件中定义的,并没有在代码中紧密耦合,因此即使对象发生改变,我们也只需要在配置文件中进行修改即可,而无须对 Java 代码进行修改,这就是 Spring IoC 实现解耦的原理。 根据上面的原理,来简单实现一个IoC容器 首先我们把思路理一下 : 首先需要两个注解(两个注解配合使用) @MyBean:把对象交给容器管理 @MyAutowired:自动注入,把容器里的实例赋值给加了注解的属性 需要ApplicationContext来操作容器 需要一个HashMap来存储Bean对象 需要开启注解启用范围,包扫描 代码逻辑 第一步实例化一个操作容器,并且把要扫描的包当形参 new ApplicationContextImpl("com.zn.ioc"); 第二步加载容器,扫描包下的所有文件,发现类上有@MyBean注解就把此类放到HashMap中(key:类的类型,value:类的实例化)。第三步自动注入,逻辑 自动注入@MyAutowired和MyBean一起连用,判断用了MyBean的类中属性有没有加@MyAutowired注解,有的话就设置属性,根据属性名的类型去HashMap中找对用的实例赋值给此属性,保证单例。 具体实现 目录: 依赖: <dependencies> <!--spring context依赖--> <!--当你引入Spring Context依赖之后,表示将Spring的基础依赖引入了--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>6.0.2</version> </dependency> <!--junit5测试--> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.3.1</version> </dependency> 两个注解:@MyAutoWired,@MyBean @Target(ElementType.FIELD) // 在属性上使用注解 @Retention(RetentionPolicy.RUNTIME) public @interface MyAutowired { } @Target(ElementType.

CAN 总线 之七 BOSCH CAN 位时序 和 同步

原文地址:https://itexp.blog.csdn.net/article/details/91129145 文章目录 位时序(BIT TIMING)标称比特率(NOMINAL BIT RATE)标称位时间(NOMINAL BIT TIME)同步跳转宽度(Synchronization Jump Width,SJW)采样点(SAMPLE POINT)信息处理时间(INFORMATION PROCESSING TIME)时间量子(TIME QUANTUM) 传播延迟(PROPAGATION DELAY) 同步同步规则硬同步重新同步e = 0e > 0e < 0 参考 CAN 支持 1 kBit/s 至 1000 kBit/s 的比特率。CAN 网络的每个节点都有自己的时钟发生器,通常是石英振荡器。 可以为每个 CAN 节点单独配置比特时间的定时参数(即比特率的倒数),即使 CAN 节点的振荡器周期(fosc)可能不同,也产生相同的比特率。 这些振荡器的频率不是绝对稳定的,温度或电压的变化以及元件的劣化会引起微小的变化。 只要变化保持在特定振荡器容差范围(df)内,CAN 节点就能够通过重新同步到比特流来补偿不同的比特率。 CAN 网络上的所有节点必须运行在相同的标称比特率下。但噪音、相移、振荡频率容差和振荡频率漂移导致实际的比特率可能与标称比特率不同。由于没有使用一个单独的时钟信号,因此需要一个同步节点方法。 同步在仲裁机制中十分重要,因为仲裁中的节点需要能够同时看到它们传输的数据和其他节点的传输数据。 同步在确保节点间震荡时间不同时不发生错误上十分重要。 位时序(BIT TIMING) 标称比特率(NOMINAL BIT RATE) 标称比特率是指理想发送器在没有再同步的情况下每秒传输的比特数。 标称位时间(NOMINAL BIT TIME) 标称位时间为标称比特率的倒数:NOMINAL BIT TIME = 1 / NOMINAL BIT RATE。标称位时间又被划分为 4 个独立的非重叠的时间段。这些时间段又由更小的可称为时间量子(Time Quantum,Tq) 的最小时间单位构成。CAN 规范规定,1 个比特位的标称位时间被分为 4 个段,每个段又由若干个Tq 构成,这称为位时序。示例如下(以 10 个时间量子为例):

【C语言初阶】——简易版·扫雷(9*9)【运行逻辑思维导图+细节讲解+源码】【初级】

目录 一、扫雷游戏的运行逻辑二、代码逻辑讲解+源码1.打印一个简易的游戏开始菜单2.创建数组储存数据并初始化数组代码逻辑讲解源码 3.布雷代码逻辑讲解源码 4.排雷代码逻辑源码 三、结果展示完整源码链接 一、扫雷游戏的运行逻辑 1.鼠标点击进行扫雷 2.若此处没有雷则会显示周围相应的雷的数目 3.若踩雷则游戏失败 二、代码逻辑讲解+源码 这里我们以9*9规格来实现简易版扫雷的游戏代码 逻辑思维导图↓ 注意:好的代码习惯——边写边调试,不要把错误累积到最后 1.打印一个简易的游戏开始菜单 #include "game.h"//所有需要用到的编译预处理命令放game.h头文件里,这里直接引用头文件 //#include <stdio.h> void menu() { printf("***********1.star game***********\n"); printf("*********************************\n"); printf("***********0.quit game***********\n"); } void game(){} int main() { int input = 0; do//循环体至少执行一次所以选用do while循环 { menu(); printf("请输入数字:"); scanf("%d", &input); if (1 == input) { printf("游戏开始\n"); game();//游戏运行 } else if (0 == input) { printf("退出游戏\n"); break; } else { printf("选择错误请重新输入\n"); } } while (input); return 0; } 运行结果↓

关于LabVIEW通过MATLAB Script调用.m脚本文件遇到的问题详解

最近接触了几个LabVIEW通过MATLAB Script调用.m脚本文件的案例,调试过程中遇到了很多的问题,现在对这些问题的解决办法做个总结,也备忘一下。 1. 路径设置问题 在MATLAB环境下运行的好好的.m文件,在LabVIEW中死活运行不起来,一个最经常遇到的问题就是路径设置问题,路径设置问题一般又分好几种情况: 在MATLAB中,双击打开m文件后,自然就把当前文档目录作为了工作目录,通过pwd函数就可获得当前工作目录路径。 但是在LabVIEW中通过MATLAB Script调用时千万要注意,它返回的不是调用VI或者脚本文件所在的当前文件夹,而是MATLAB的安装路径,可通过MATLAB Cammand Window中看出,如下图所示。 因此,如果在脚本文件中有使用相对路径,或者有用到了pwd函数来获取当前工作文件夹路径,就要注意一定要进行修改了,一般可通过如下步骤进行修改: 1)通过MATLAB Script中添加输入端子,并将数据类型设置为路径,再通过LabVIEW的路径控件将LabVIEW当前工作目录传递给MATLAB Script; 2)通过addpath函数将传递进来的文件夹路径添加至当前MATLAB会话的顶层; 3)通过fullfile函数建立以当前工作目录为基础的完整文件路径。 函数声明问题 在MATLAB的m文件的主文件中是可以声明其它函数的,并且可以直接运行没有任何问题。 但是如果把相同的脚本文件内容通过LabVIEW的MATLAB Script运行的话,就会报出1050错误了,意思大概就是说不允许在MATLAB Script中进行函数定义,需要在代码文件(另外的m文件)中创建函数。 解决办法自然就是将函数定义部分内容迁移至m文件中即可。 总结 常见问题主要有2个: 1. 路径设置问题–通过传递路径方式解决; 2. 函数申明问题–通过将函数迁移至m文件中解决。

Clickhouse部署及接入前后效率对比

最近重构后台某个功能时,改用Clickhouse进行数据查询,业务的需求是要实时展示最近1个月内站点充值、下载、注册等信息,并支持日期筛选: 第一版时采用前端定时器调用接口获取数据,每次查询获取一天数据,每次接口执行时间3s左右【通过php+mysql】 第二版从PHP+Mysql层面对程序进行优化,每个接口调用时间达到了900ms【第一版开发时间比较长,一些地方处理的比较繁重,所以回头优化,时间提上去了】 第三版引入了Clickhouse后,接口处理的时间差不多200ms,处理的速度相较于通过mysql提高了5倍 第四版通过合并查询,最初采用定时器是因为单次处理时间较长,一次查询请求会超时,所以在处理时间提高后,进行合并请求操作,而且clickhouse进行sql查询并不是累加,而是并行查询,通过合并查询后,由每次200ms处理时间,轮询30次,变成了900ms处理时间,一次查询 除了第四版,其它三版采用定时器轮询方式,上述指的仅仅只是接口运行时间,定时器定时时间1s,所以所有数据加载出来后的整体时间还是比较久的,仅通过mysql/clickhouse对比来看,第四版程序处理时间大概是第二版的1/30,而且更不用等待一个接口加载完成后进行数据对比,第四版页面数据是秒加载完成,整体的体验也是最好的;clickhouse是在项目的服务器搭建的,所以整个流程中的处理时间仅代表在项目机器处理时间,阿里等也提供了此项的云服务 Clickhouse安装还是比较简单的,可以查看官网进行安装,我的环境是centos,其具体安装如下: // 安装clickhouse sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://packages.clickhouse.com/rpm/clickhouse.repo sudo yum install -y clickhouse-server clickhouse-client // 运行clickhouse sudo /etc/init.d/clickhouse-server start // 进入clickhouse中,进行建库、建表等操作 clickhouse-client # or "clickhouse-client --password" if you set up a password. 其实clickhouse的操作和mysql大致相同,通过sql操作mysql数据库大都也适用于clickhouse

例1.10 几何概型题型一——(会面问题)

【例 1.10】(会面问题) 甲乙两人约定在下午6 点到7点之间在某处会面,并约定先到者应等候另一人20 分钟,过时即可离去,求两人能会面的概率。 我的答案: 一、信息 (1)对于甲乙会面约定事件是6~7点。 (2)对于规则要求先到者等另一个人20分钟。 (3)求两人能会面的概率。 二、分析 (1)问题1:无论是几何概型还是古典概型第一步要做的都是要先确定样本容量,那么对于几何概型来说样本容量可能是长度也可能是面积当然也可能是体积,或者其他我现在还想不到的方面。 (2)问题2:就是要求了,先到者按规则要等另一个人20分钟。 (3)问题3:求两个人能会面的概率是什么呢?还是和古典概型一样吗。 三、问题的解决 对于问题1:我们可以建立笛卡尔坐标系即xoy二维坐标x表示甲到达时间,y表示乙到达时间,现在我们就把概率问题转化成在二维平面上的几何问题——体现了转化的思想不难看出该正方形的面积就是样本容量 对于问题2:这个规则如何理解呢? 正确答案: 反思: 方法: 对于这一类会面问题已经找到了解决之法:即把代数问题转化为几何问题,然后根据数量关系构造不等式。,然后求出二者在坐标系上重合的面积。 不足: 数学符号得回去学学了对于几何概型的数学式子证明还有欠缺。 犯错误的地方: 首先我错误的认为了时间可以通过二维空间上的点之间的距离来表示的到一个函数这是错误的因为看过答案的都知道这个错误的想法因为答案中的阴影不是函数,而是方程。 第二个错误,知道了这点之后我还想构造函数但是还是再二维的尺度上构建,但是事实上我们只需要在一维的尺度上对时间取个不等式|x-y|<=20再把不等式的几何意义搬到这个我们构建的坐标系中问题似乎就迎刃而解了。 疑惑为什么它们的重合面积就是我们要找的事件样本空间呢? 解答: 由于问题所需的情况都是满足该不等式我们不难看出其中的问题。

CCF 俄罗斯方块 满分代码(有注释) + 解题思路(很简单直白的做法) + 技巧总结 201604 - 2

技巧总结 对于需要先判断可不可以再进行“填充”数组的操作,可以利用memcpy,在一个新的数组上“试错”小数组在大数组中实现遍历,可以利用小数组的行列遍历,然后加上大数组的偏移量就可以遍历大数组 题目描述 解题思路 该题数据范围不大,只有两百年,可以采用暴力枚举来解题从上而下枚举每一行,以(r, c)这个点作为小方块在大方块中的左上角位置,遍历小方块,看小方块会不会与大方块相重叠,第一次出现重叠的位置,就是刚好阻塞的地方,其上一行的状态就是答案,可以将上一行小方块在大方块中是1的位置记录在大方块中,输出大方块即是答案。还有一个问题就是,可能会出现大方块最后一行没有没有1,或者小方块的下面几行也没有1,为了防止复杂的特判,只需要在大方块下面的第16行,17行,18行,19行全填充上1,就不需要额外判断板块在小方块中的位置情况,模拟自然下落即可。 代码实现 #include <iostream> #include <cstring> #include <algorithm> #include <queue> #include <map> using namespace std; int g[20][10]; int p[4][4]; int main() { memset(g, 1, sizeof(g)); //会使16行及以下是1,避免特判边界的问题,板块碰界可以统一处理 //输入大方块 for (int i = 1; i <= 15; i ++) { for (int j = 1; j <= 10; j ++) { cin >> g[i][j]; } } //输入小方块 for (int i = 0; i < 4; i ++) { for (int j = 0; j < 4; j ++) { cin >> p[i][j]; } } //输入开始的列数 int c; cin >> c; for (int r = 1; ; r ++) //一定会碰壁,停止循环,所以不同设结束条件,从第1行开始,每次从(r,c)开始遍历小方块,模拟小方格下落的过程 { bool st = false; for (int i = 0; i < 4; i ++) { for (int j = 0; j < 4; j ++) { if (p[i][j] && g[r + i][c + j]) //两者有重叠 { st = true; break; } } if (st) break; } if (st) //如果出现了重叠,则说明答案应该是上一行的状态 { r --; //返回上一行 for (int i = 0; i < 4; i ++) { for (int j = 0; j < 4; j ++) { if (p[i][j]) g[r + i][c + j] = p[i][j]; //将小方块是1的地方填充在大方块中 } } break; } } //输出最后的答案 for (int i = 1; i <= 15; i ++) { for (int j = 1; j <= 10; j ++) { cout << g[i][j] << "

安装ubuntu20/18后出现Minimal BASH-like line editingis supported.黑屏的解决方法

一个误操作,ubuntu系统崩了,重启之后进入系统就出现以下错误: Minimal BASH-like line editing is supported.For the first word.TAB lists possible command completions.Anywhere else TAB lists possible device or file completions. 问题界面如下: 2.解决办法 ①准备一个Ubuntu自启动U盘(建议和安装的是相同版本),电脑需要连网。 ②重启电脑,把U盘设置为第一启动项,进入Try Ubuntu Without Installing。 ③打开Terminal,输入: sudo add-apt-repository ppa:yannubuntu/boot-repair sudo apt-get update sudo apt-get install boot-repair 安装boot repair软件。 ④打开Dash,输入boot-repair,打开它,点击recommanded repair按钮。接下来按照提示修复即可。 ⑤结束后,重启电脑。

lv1 Linux C语言基础

day1必备Linux命令和C语言基础 文件的打开显示命令 1.1 ls命令 pwd:查看当前所处的路径 cmd --help/man cmd:查看命令的帮助手册 ls:查看当前路径下所有的文件 ls -l:列表形式显示文件夹 ls -a:显示隐藏文件夹/文件 “*”通配符:ls .txt 把当前目录下的.txt文件列出来 ls 1 把当前目录下1开头的文件列出来 1.2 cd命令 cd:打开/切换 目录/路径 cd … :意思是到上一级目录; cd …/…上上级目录 cd - :意思是返回到上次的目录,类似windows返回 ; cd /:意思是回到根目录。 cd ~:返回到home目录 1.3 vim命令 vim filename :打开或新建文件,并将光标置于第一行首 vim +n filename :打开文件,并将光标置于第n行首 vim + filename :打开文件,并将光标置于最后一行首 vim +/pattern filename:打开文件,并将光标置于第一个与pattern匹配的串处 方向键上:可以获取上次的命令,同样方向键下获取下一步的命令 Tab:自动补全功能 文件夹的创建/删除/移动命令 2.1创建 touch test.txt:在当前目录下创建test.txt文件 touch .test1.txt :创建test1.txt隐藏文件 .代表隐藏 mkdir(make directory缩写) bb:在当前目录下创建bb文件夹 2.2删除 rm test.txt:删除当前目录下的test.txt文件 rm -d bb:删除当前目录下的bb文件夹

HTTP登录和授权

HTTP是无状态的协议,它不会记录和保存之前连接的状态。那么它进行登录验证和授予客户端权限的过程是怎样的?我们经常使用微信、QQ等进行第三方的授权登录。又是怎样实现的?本文将通过介绍HTTP登录和授权机制帮助大家理解这些问题。 一、Cookie Cookie在英语里是曲奇、小饼干的意思。它的作用是帮助服务器把用户数据存储在用户的客户端本地。通过它让HTTP无状态工作方式,变成“有状态“的方式。 1.1 Cookie起源 早期的浏览器公司会帮助用户进行网站的开发。当时的购物网站需要实现“购物车“的功能。盛极一时的Netscape(网景)公司的做法,是将购物数据存在客户端的本地,为此开发了一套完整的流程,就是Cookie。因此,Cookie开发出来就是用于实现”购物车“的功能。 后来我们知道,电商购物车功能都改为在服务器端实现。Cookie也失去它最初的作用,但是它完整的实现机制却被保留下来,用于用户登录状态管理、用户偏好管理、用户行为追踪等。 1.2 Cookie工作机制 看一下用Cooke早期用于实现“购物车“功能的工作过程: 1、用户发起请求在购物车增加一个“apple“;服务器收到并处理请求后,返回用户结果,并通过set-Cookie将“apple“加入”购物车“;用户将该Cookie存在用户本地,这里需要同时记录网站的信息和对应Cookie信息,避免访问多个网站发生错乱。 2、用户再次向服务器发起请求,这次将一个“banana“加入购物车。用户同时将当前记录该网站的Cookie同时发送过去;服务器收到请求并处理后,将新的带有一个”apple“和一个”banana“的Cookie通过”set-Coolie”返回给客户端;客户端收到返回后,更新本地的Cookie,即购物车。 3、用户向服务器发起结算请求,同时将本地的Cookie发送过去。服务器收到请求后,进行结算。完成后,服务器更新客户端Cookie,清空购物车。 以上购物车实现的简单流程,就是典型的Cookie工作机制。我们现在用的Cookie机制也是这样工作的。 1.3 Cookie作用 前面说到,Cookie已经失去了它最原始的作用。我们看一下现在Cookie在HTTP网络访问中的作用和实现原理。 1)、登录状态管理 它的原理就是利用Cooke保存登录数据在本地,每次客户端发起请求时,同时发送Cookie数据给服务器,服务器通过检查Cookie数据确认用户登录状态。将HTTP从无状态协议,改为有状态。 客户端向服务器发起登录请求,登录成功后,服务器将登录信息通过Cookie返回客户端,并在客户端保存起来。 客户端再次发起HTTP请求时,带入保存的该网站登录信息的Cookie数据。服务端收到请求后,解读Cookie,确认客户端是已经登录的状态。 2)、追踪用户行为 我们在使用HTTP网络访问,有时会看到类似下面的声明。会告诉我们网站使用Cookies不会进行用户行为追踪,侵犯用户隐私。 Cookie进行用户行为追踪的原理,就是当我们进行网络请求时,可能请求的内容,比如图片,还需要再向第三方网站进行请求。服务器发给我们资源地址时会带有“form=xxx“的信息,表示该请求的来源。这些信息被三方网站获取,就可以掌握用户访问过哪些网页。通过用户网络行为,对用户进行画像。 1.4 Cookie相关攻击 与Cookie有关的网络攻击,主要用XSS和XSRF两种。 XSS Cross-site scripting的缩写,意思是“跨站脚本攻击“。攻击的原理是javaScrip可以在客户端本地拿到Cookies,并发送到自己的网站,进而盗用用户的身份信息。 针对这种攻击,服务器在发送“set-Cookie“时,对敏感的信息,增加”HttpOnly“修饰。它表示该Cookie只在进行HTTP请求时自动发送,不能被本地javaScrip调用。 它的报文格式:Set-Cookie: client_id=123;HttpOnly XSRF Cross-site request forgery的缩写,意思是“跨站请求伪造“。它是在用户不知情的情况下,访问恶意网站,该网站使用用户Cookie向目标服务器发起请求,以此来越权操作用户的账号。 比如,用户登录网银,首先进入恶意网站,恶意网站使用我的Cookie来登录网银。 针对这种攻击,在服务器端增加“Referer”校验。Referer机制,是浏览器每次跳转时会强制加上,用于标记转发的网站。如果直接访问目标网址Referer为空。 服务器端通过只处理没有跳转的(Referer为空)请求,或者来自白名单网站转发的请求,来防范XSRF攻击。 二、Authorization Authorization,即“许可、授权”的意思。它被设计出来就是用于登录鉴权。实际上它比Cookie更适合用于登录状态管理。它有两种主要的Token:Basic和Bearer。Basic用于登录授权,Bearer用于进行第三方登录。 在介绍Authorization之前,先看一个知识点Base64。 2.1 Base64 Base64是一种编码格式,它是将二进制数据转换成由64个字符组成的字符串。这64个字符是a~z、A~Z、0~9、“+”和“\”,共64个字符。 转换的方式,是将原二进制串按照每六个字符进行分割,根据base64码表确定字符。(我们知道计算机字符是按照每八个字符分割)。 Base64码表如下: 看一下,下面的例子,原字符串“Man”,按照Base64重新编码成了”TWFu”。 码表中“=”的作用是当最后不够6个字符时,用来进行补位。 如下,“Ma”的Base64格式“TWE=”。“M”的base64格式是“TQ==”。 了解了Base64编码原理我们知道它是不安全的,因为编码后的数据,可以很容易反编码回去;同时也是低效的,经过Base64编码,原字符串会变得更长,传输的数据体积更大。 Base64的作用就是把普通的二进制数据,全部转为字符串的形式。同时当原数据是字符串时,经过编码可以起到防偷窥的作用。 扩展知识:Base58 Base58是Base64的变种,它在Base64码表的基础上去掉了容易混淆的O (大写的o)、0(零)、I(大写的i)、 l(小写的L),以及“+”和“\”六个字符。它被设计出来用于比特币地址的存储,防止在进行手抄时抄错。 2.2 Basic 使用Basic形式的Token用于登录授权的HTTP报文形式如: Base64数据是“zhangsan:1234567”。 这种方式会有Base64被破解和Token在本地被窃取风险。 针对Base64破解风险,可采用HTTPS进行数据传输,它会将请求数据全部加密,Base64值同样会被加密,就不会被破解了。 Token在本地被窃取,大多数情况是不需要担心的。Token虽然被保存到本地,手机端的安全机制下,这个数据是不会被其他应用获取的。少数情况,下用户刷机并给恶意三方程序root最高权限,而可以访问任何文件,token才可能被窃取。这种情形相当于用户主动放弃了安全机制,是用户自主行为。 2.3 Bearer 是“持票人”的意思。拿着有权限人给的“票据”,就可以被赋予相应的权限。 报文形式是:Authorization: Bearer <bearer token>

Java学习——lambda表达式

一 、Lambda表达式前瞻知识 什么是Lambda表达式? 可以将Lambda表达式理解为一个匿名函数; Lambda表达式允许将一个函数作为另外一个函数的参数; 我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码作为实参),也可以理解为函数式编程,将一个函数作为参数进行传递。 为什么要引入Lambda表达式? Lambda表达式能够让程序员的编程更加高效 lambda表达式和方法引用使用前提:函数式接口 1.@FunctionalInterface 语法格式严格要求当前接口有且只能有一个尚未完成的缺省属性为 public abstract 修饰方法。 2.函数式接口一般用于方法的增强,直接作为方法的参数,实现函数式编程。 只有函数式接口的变量或者是函数式接口,才能够赋值为Lambda表达式。这个接口中,可以有默认方法,或者是静态方法。 二、Lambda表达式 1.Lambda表达式的基本语法 ([Lambda参数列表,即形参列表]) -> {Lambda体,即方法体} 1.Lambda 表达式关注的是接口中方法的返回值和参数,方法名不重要 2.使用 "->"将参数和实现逻辑分离;( ) 中的部分是需要传入Lambda体中的参数;{ } 中部分,接收来自 ( ) 中的参数,完成一定的功能。 3.只有函数式接口的变量或者是函数式接口,才能够赋值为Lambda表达式。这个接口中,可以有默认方法,或者是静态方法。 2.四种lambda表达式 2.1无参数无返回值 //接口设计 @FunctionalInterface interface A { void 方法名真的没有用(); } //方法设计 public static void testLambda(A a) { a.方法名真的没有用(); } //代码实现 public static void main(String[] args) { //1.匿名内部类方法 //接口无法实例化,这里实例化的是 A 接口的实现类对象(该方法在jdk1.8以后被lambda表达式完虐) testLambda(new A() { //缺省属性为abstract,需要重写 @Override public void 方法名真的没有用() { System.

以图搜图服务快速搭建

以图搜图服务快速搭建 电商公司,管理的商品少则几千,多则上百万。如何帮助用户从多如牛毛的商品中找到类似的商品就成了问题。 以图搜图就可以很好的帮助解决这个问题,通过 Towhee(resnet50 模型) + Milvus 如何实现本地环境搭建以图搜图。 Towhee 负责解析图片的特征向量,Milvus 负责存储特征向量然后进行向量查询。 Milvus Bootcamp 提供了很多解决方案 ,https://milvus.io/bootcamp/ 其中就包含以图搜图的解决方案,根据图片相视度解决方案demo,这里实现了比较时候适合公司前后的分离环境的开箱即用的api实现。 配合前端大致效果如下: 包含如下接口 API接口 1.创建数据库 不同数据库对应不同的图片数据集合 Request Method: POSTURL: /milvus/img/table?table={tablename} 创建test数据集: /milvus/img/table?table=test Headers: Response Body { "code": 10000, "message": "Successfully", "data": null } 2.新增图片 新增图片支持 base64 和url新增 Request Method: POSTURL: /milvus/img/add test 数据集新增图片数据: /milvus/img/add Headers: Content-Type:application/jsonBody: { "tags": "风景|标签", "table": "test", "brief":"{\"title\":\"hello world\"} 这里存一些属性", "image": "base64(和url二选一,image优先级更高) ", "url":"http:///xxx.jpp" } Response Body { "code": 10000, "

VMTK编译时遇到的天坑

VMTK是一个很小众的包,因为要用一些itk contrib的模块,无法用python实现,只能自己编译VMTK跟ITK、VTK一起使用。 最开始想的太简单,VTK和ITK都用的最新版本vtk9和ITK5,后两个简简单单编译成功。到了VMTK这里,虽然cmakelist里有USE_SYSTEM_ITK和USE_SYSTEM_VTK的选项。 但。。想想也知道不可能成功,VTK从8到9疯狂的改了一堆东西。去VTK官方论坛逛,发现有个大佬花了将近2个月全职工作才把vmtk在vtk9.0下编译成功。我发了邮件,问愿不愿意开源出来,还没回我。估计是不愿意的。然后看他后面的帖子,就算强行编译成功了,后面也一堆问题,根本跑不起来(他问update函数是干啥的,为啥总报错,然而熟悉ITK、VTK的人都知道,update函数是itk、vtk库的pipeline虚函数,几乎所有类都有这个update)。 所以,为了工作还能继续开展,就用vmtk自带的环境吧。直接让它自己下载并自动编译itk和vtk(自带的itk版本是4.13.0, vtk是8.1.0) 然而,编译过程中遇到了错误: cannot convert ‘std::nullptr_t’ to ‘Py_ssize_t’ {aka ‘long int’} in initialization 去VTK论坛发现了这个patch From 00e84cfcc5a0812503b431238fc26c349b0d714f Mon Sep 17 00:00:00 2001 From: David Gobbi <david.gobbi@gmail.com> Date: Tue, 20 Aug 2019 17:02:24 -0600 Subject: [PATCH] Compatibility for Python 3.8 The PyTypeObject struct was modified in Python 3.8, this change is required to avoid compile errors. --- Utilities/PythonInterpreter/vtkPythonStdStreamCaptureHelper.h | 6 ++++++ Wrapping/PythonCore/PyVTKMethodDescriptor.cxx | 2 +- Wrapping/PythonCore/PyVTKNamespace.cxx | 2 +- Wrapping/PythonCore/PyVTKReference.

NI图像处理函数应用——像素操作

NI图像处理工具包中包含丰富的图像处理函数,包括像素操作、几何变换、图像运算、彩色图像操作与运算、灰度分析与运算等。此处是对像素操作的相关函数的介绍。 像素操作函数函数选板 如下图所示显示了NI Vision提供的像素操作函数,它们位于LabVIEW的Vision and Motion → Vision Utilities → Pixel Manipulation函数选板中。 像素操作函数说明 像素操作相关函数的说明如下图所示: 像素操作函数应用示例 1)像素点操作、行列像素值操作、线段像素值操作以及图像填充操作示例 像素点操作、行列像素值操作、线段像素值操作以及图像填充操作示例: 首先打开待处理的图像;然后通过IMAQ SetPixelValue函数将坐标为(200,200)的像素值更改为255(白色);再通过IMAQ GetPixelValue函数读取改动后的像素值,以确认像素更改操作的结果;再通过IMAQ SetRowCol函数更改图像中某一行或某一列的数据,由于设置了行参数Row为FALSE,所以该示例中只会使用Pixels(U8)数组中的值更改编号为50的一列数据。程序中Pixels(U8)数组中仅有两个元素,此时,进行替换时只有前两个像素被更改。再通过IMAQ GetRowCol函数读取更改后的第50列像素值,以确认像素更改操作的结果。再通过IMAQ GetPixelLine函数返回(10,10)和(60,60)两点所确定的线段覆盖的像素值;这些返回的像素值被Replace Array Subset 用含有100个元素的子数组替换后,再次作为IMAQ SetPixelLine函数的输入,用于更改线段所覆盖的像素值。以上程序段运行结果如下图(a)所示。再通过IMAQ FillImage函数,用黑色(像素值为0)对图像进行填充,由于使用了图像遮罩,因此只有遮罩图像中非零像素所覆盖的部分会被填充。默认情况下,图像遮罩会被放置在使用它的图像原点,程序并未使用默认值,而是用IMAQ SetOffset将图像遮罩左上角移动到图像中(220,220)像素坐标位置,程序运行结果如下图(b)所示。 2)在图像中绘制几何图形、插入文本示例 如下图所示为在图像中绘制几何图形、插入文本的程序示例。 a) 首先从文件中读取图像; b) 然后通过IMAQ Draw函数以边框模式在图像中绘制左上顶点为(10,10),右下顶点为(500,500)的白色(像素值为255)矩形; c) 再通过IMAQ Draw Text函数以用户自定义风格在图像中的(80,80)坐标处添加白色的“Draw Text”字符串,这些字符的字体为Arial。 下图中的(a)为以边框模式绘制几何图形的运行结果,(b)为以反转绘图模式运行时的结果,它对所定义的矩形区域内的所有像素进行了反转. 3)IMAQ ImageToArray、IMAQ ArrayToImage函数 这2个函数比较简单,就是把图像转换为像素数组,以及把像素数组转换为图像,就不再举示例了。 总结 本文主要介绍了NI视觉开发模块中的像素操作相关函数,主要包括: 1)像素点操作、行列像素值操作、线段像素值操作以及图像填充操作; 2)在图像中绘制几何图形、插入文本操作; 3)图像至像素值转换、像素值至图像转换。

GIS总结

GIS介绍:全称Geographic Information System(地理信息系统) 要素模型(Feature) 它是描述地理空间数据对象的基本单位,它描述了一个现实世界中的客观地理实体,如:一条河流、一座桥梁都可以理解为要素 栅格数据 栅格数据是从上向下拍摄的地球照片,使用离散单元存储其值,图片的每个像素点都有一个指定值服务器本身存储,传输速度快,服务器压力小,多为png,jpg,gif数据量大,更新慢 矢量数据 矢量数据是仅仅存储节点,比如箭头,线条,点等。存储的是对象的轮廓,而栅格数据适合表达对象的内容。矢量数据类型有点、线和面。数量小,数据更新快服务器压力大,技术要求高 数据类型介绍 栅格数据: 栅格数据的优势: 适用范围广:栅格数据适用于描述大范围地理现象,例如土地覆盖、气象变化、海洋温度等。这些数据通常覆盖大面积,而且数据分辨率相对较低。连续性强:栅格数据中每个像素都代表一个位置上的属性值,可以形成完整的空间连续性。这使得栅格数据在进行空间分析时能够提供更精细和准确的结果。数据格式统一:栅格数据的格式相对统一,常见的格式包括GeoTIFF、GRID、BIL、BIP、BSQ等。这使得栅格数据在不同的GIS软件和平台上可以更方便地共享和处理。数据处理简单:栅格数据的处理通常比矢量数据简单,因为它们只需要进行基本的数学和统计计算,如平均值、最大值、最小值等。这些计算通常不需要复杂的几何运算。可视化效果好:由于栅格数据的连续性,其可视化效果相对较好。例如,在地图上显示高程模型数据时,可以使用不同的颜色渐变来表示不同的海拔高度,从而形成非常直观的三维地形模型。 文件头部分: 通常包含栅格数据的一些基本信息,例如数据类型、数据格式、地理坐标系、栅格像素数、栅格像素大小等。这部分信息通常是以二进制形式存储在文件的开头,其格式和内容可能因数据格式而异 数据部分: 会存在多个像素波段,每个波段含有对应像素的值。每个像素的值通常是一个数值,表示该像素的属性值(可以是高度、温度、颜色深浅等等)。这些像素值通常是按行存储的,每一行从左到右存储。不同的栅格数据格式可能还会有一些元数据,例如像素值的数据类型、缺失值标识等 矢量数据: 矢量数据的优势: 精度高:矢量数据可以描述精细的地理现象,例如建筑物、交通网络、河流、边界等,因此具有比栅格数据更高的精度和准确性。这使得矢量数据在需要高精度分析和建模的场景中非常有用。数据量小:相对于栅格数据而言,矢量数据的数据量通常较小,因为它们只需要存储要素的位置、形状和属性信息等,而不需要存储每个像素的值。这使得矢量数据在存储和传输方面更加高效。数据格式灵活:矢量数据的格式相对灵活,常见的格式包括Shapefile、GeoJSON、KML等。这使得矢量数据可以适用于不同的GIS软件和平台,并且可以方便地进行共享和交换。几何运算方便:由于矢量数据是基于几何要素的,因此进行几何运算和分析相对容易。例如,在计算两个区域之间的距离时,只需要对它们的边界进行计算即可。可视化效果好:由于矢量数据的精度和准确性较高,其可视化效果相对较好。例如,在地图上显示道路和建筑物时,可以使用不同的符号和颜色来表示不同的要素类型和属性信息,从而形成非常直观的地图。 文件头部分: 通常包含矢量数据的一些基本信息,例如数据类型、数据格式、地理坐标系、要素数目等。这部分信息通常是以二进制形式存储在文件的开头,其格式和内容可能因数据格式而异 几何要素数据部分: 包含矢量数据的实际几何信息。每个几何要素通常由若干个坐标点组成,这些坐标点的顺序和方式通常根据具体的数据格式而定。常见的矢量数据格式包括点数据、线数据和面数据等。 属性数据部分: 包含与几何要素相关联的属性信息,例如地物名称、坐标点的高程值、温度值等。这些属性数据通常是按记录存储的,每个记录包含一个或多个属性字段。不同的矢量数据格式可能还会有一些元数据,例如属性值的数据类型、缺失值标识等。 类型数据处理示例 读取清洗成新的栅格数据: /** * 通用新增为tif上色 现在tiff不上色 * * @param tifUrl 文件地址 * @return levels索引位置对应生成的文件地址 */ public String tiffProcess(String tifUrl) { Dataset open = gdal.Open(tifUrl, gdalconstConstants.GA_ReadOnly); /* 获取gtiff 数据 */ //行数 高 int iYSize = open.getRasterYSize(); //列数 宽 int iXSize = open.getRasterXSize(); //仿射矩阵 double[] doubles = open.

SpringBoot实现Excel导入导出,简单好用

EasyPoi简介 POI是Java操作MicroOffice(如对Excel的导入导出)的一个插件。POI的全称是(Poor Obfuscation Implementation),POI官网地址是 http://poi.achache.org/index.html 。 EasyPoi对POI进行了优化,更加设计精巧,使用简单,接口丰富,扩展简单。EasyPOI的同类产品有Execel4J,Hutools等。EasyPoi官网地址是 https://gitee.com/lemur/easypoi 用惯了SpringBoot的朋友估计会想到,有没有什么办法可以直接定义好需要导出的数据对象,然后添加几个注解,直接自动实现Excel导入导出功能? EasyPoi正是这么一款工具,如果你不太熟悉POI,想简单地实现Excel操作,用它就对了! EasyPoi的目标不是替代POI,而是让一个不懂导入导出的人也能快速使用POI完成Excel的各种操作,而不是看很多API才可以完成这样的工作。 Springboot集成EasyPoi 在SpringBoot中集成EasyPoi非常简单,只需添加一个依赖即可,springboot会通过自己的自动装配功能将这个第三方组件加载到spring容器进行管理。 这里贴出完整的pom.xml,读者直接拷贝过去使用即可。 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.5.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>springboot-export</artifactId> <version>0.0.1-SNAPSHOT</version> <name>springboot-export</name> <description>springboot-export</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-spring-boot-starter</artifactId> <version>4.4.0</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>RELEASE</version> <scope>compile</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> 创建一个用户对象User,封装用户信息:

【PyQt5】Qt Designer + pyuic5.exe + pyrcc5.exe 实现界面和功能代码分离

pyuic5.exe,pyrcc5.exe工具位于python安装路径的Scripts 文件夹下 Qt Designer 在制作界面时会生成两类文件,一类是界面的.ui文件,一类是保存图片的.qrc文件,需要将他们转换为python可识别的.py文件。 pyuic5.exe用于将.ui转为.py文件pyrcc5.exe用于将.qrc转为.py文件 通过以下步骤将 pyuic5.exe pyrcc5.exe 添加到pycharm的拓展工具中 $ProjectFileDir$\venv\Scripts\pyuic5.exe $FileName$ -o $FileNameWithoutAllExtensions$_ui.py -x $FileDir$ $ProjectFileDir$\venv\Scripts\pyrcc5.exe $FileName$ -o $FileNameWithoutExtension$_rc.py $FileDir$ D:\Softs\QtDesigner\designer.exe $ProjectFileDir$ 在添加后即可在.ui文件右键>external tools>ui_to_py进行.ui文件的转换,.qrc类型的文件同理。 .ui文件转换的.py文件结构为 Ui_Form 类,里面保存着页面的组件以及布局代码,为了使得界面代码和功能代码分离,这个文件作为界面代码由转换工具自动生成,不进行修改(后期如果界面进行修改会重新进行.ui文件的转换,如果在这个文件类添加功能代码的话,功能代码会被覆盖) 功能代码则另外创建一个.py文件,并继承于 Ui_Form 类,在 init()方法中调用 self.setupUi(self),即完成了对界面代码的引用,代码如下: import sys from PyQt5.QtWidgets import QApplication, QWidget from resource.login_ui import Ui_Form class Window(QWidget, Ui_Form): def __init__(self): super().__init__() self.setupUi(self) # 功能代码这个文件内进行添加 if __name__ == '__main__': app = QApplication(sys.argv) window = Window() window.show() sys.exit(app.exec_()) 执行该代码就可以运行制作好的界面,后续需要给界面添加功能代码都在这个类进行添加,从而实现了界面代码和功能代码的分离,方便项目的维护。

有关 Inno Setup 的实践:检查并安装依赖,运行时退出安装或卸载

如题,检测 Microsoft Visual C++ 2015 Redistributable (x64) 依赖并安装,若程序安装或卸载时应用运行中将检测并退出 所需依赖 Microsoft Visual C++ 2015 Redistributable (x64) Microsoft 官网下载psvince.dll Github 下载 编辑 iss 文件 [Files] ... Source: "psvince_path\psvince.dll"; DestDir: "{app}" [Run] Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent; BeforeInstall: IsAllDependciesInstalled [Code] // 通过注册表检测 VC2015+ 是否安装 function IsVCServiceInstalled(): Boolean; var Names: TArrayOfString; I: Integer; RootKey: Integer; Subkey: String; begin Result := false; if IsWin64 then begin RootKey := HKLM64; end else begin RootKey := HKLM32; end; if RegGetSubKeyNames(RootKey, 'SOFTWARE\Classes\Installer\Dependencies', Names) then begin for I := 0 to GetArrayLength(Names)-1 do begin SubKey := Names[I]; if Pos('VC,redist.

【nginx】nginx代理静态资源 通配符路径

代理静态资源 location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { proxy_pass http://10.175.248.240:8080; } location ~ .*\.(js|css)?$ { proxy_pass http://10.175.248.240:8080; } 通配符路径 因为有些地址是StandardApiAction_login,StandardApiAction_detail,StandardApiAction_add等形式的,location的路径需要以通配符的形式实现代理请求 location ^~ /StandardApiAction { proxy_pass http://10.175.248.240:8080; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Nginx-Proxy true; proxy_redirect off; }

【Python报错-02】解决Python中的join()函数报错 :sequence item 0: expected str instance, int found

1 报错内容: TypeError: sequence item 0: expected str instance, int found。 TypeError: 序列项0:应为str实例,但找到list。 原代码如下: str1 = '\n' f = open('labels.txt', 'w') f.write(str1.join(labels)) #这句话报错 f.close() 2 了解join()函数 语法: str.join(sequence) 参数: 可连接对象:列表,元组,字符串,字典和集合(都得是字符串) #参数 #sequence - 要连接的元素序列。比如:列表,元组,字符串,字典和集合 #str - 以什么来连接元素 3 解决办法 (1)根据错误提示,可知list中包含数字,所以不可以直接转换成字符串。要么直接修改列表内非字符串的元素,要么将列表内的元素全部转换为字符串元素。 (2)要么将列表内的元素全部转换为字符串元素,可利用map函数,可对列表内的每一个元素都进行操作。

从NLP视角看电视剧《狂飙》,会有什么发现?

文章目录 1、背景2、数据获取3、文本分析与可视化3.1 短评数据预处理3.2 词云图可视化3.3 top关键词共现矩阵网络3.4 《狂飙》演职员图谱构建 4、短评相关数据分析与可视化5、总结 原文请关注:实用自然语言处理 作者:风兮 建议查看原文: https://mp.weixin.qq.com/s/nURcYKN6vRBKjbMXAUbEng 关键词: 爬虫、文本数据预处理、数据分析、可视化、自然语言处理、pyecharts 摘要: 本文主要内容,获取解析豆瓣《狂飙》的短评相关数据和演职员信息,在数据预处理后,进行简单的数据分析和可视化展示。 本文全部代码路径 https://github.com/fengxi177/pnlp2023/tree/main/chapter_1 1、背景 前文《文本数据预处理:可能需要关注这些点》分享了关于文本预处理的理论知识,本文将分享一份示例demo。正好,碰到了热议的电视剧《狂飙》。因此,本文打算从自然语言处理、数据分析和可视化的角度来凑个热闹(原本计划在大结局当天发出来文章,可惜,大结局有一段时间了。拖延了,哈哈哈)。 2、数据获取 既然要做电视剧《狂飙》相关的nlp数据分析,那么就先选定数据目标站。经过一圈搜寻对比,发现还是豆瓣中的评论更为客观,参与群体数量多,见解更丰富专业,哈哈哈。因此,本文将获取https://movie.douban.com/subject/35465232/ 页面中的相关数据。 截止2023年2月28日,豆瓣中电视剧《狂飙》的短评已经22w+(2023年2月6日13w+,评论热度依然很高)。通过翻看短评数据,可以发现不登录状态最多可以获取220条数据,登录后最多可以获取600条数据。一般,可以通过cookie和selenium的方式实现登录,网上有参考教程,自行搜集。 不过,在不登录状态下,通过URL参数设置分析,发现各参数下都可以获得220条数据。因此,本文只获取不登录状态下的数据。具体的,通过好评、中评和差评参数percent_type设置分别获取220条短评及其相关数据。(特别的,仔细观察URL的参数设置还可以获得更多的数据哦。) def parse_comments(url): """ 解析HTML页面,获得评论及相关数据 :param url: :return: """ html = get_html(url) soup_comment = BeautifulSoup(html, 'html.parser') # 所有获取的一页数据 data_page = [] # 提取评论 comments_all = soup_comment.findAll("div", "comment-item") for comments in comments_all: try: # 解析评论及相关数据 comment_info = comments.find("span", "comment-info") # 评论id相关信息 comment_vote = comments.find("span", "comment-vote") # 评论点赞信息 comment_content = comments.

模型构建器

** 什么是模型构建器?** 模型构建器是一个用来创建、编辑和管理模型的应用程序。模型是将一系列地理处理工具串联在一起的工作流,它将其中一个工具的输出作为另一个工具的输入。也可以将模型构建器看成是用于构建工作流的可视化编程语言。 模型构建器除了有助于构造和执行简单工作流外,还能通过创建模型并将其共享为工具来提供扩展 ArcGIS 功能的高级方法。 模型构建器甚至还可用于将 ArcGIS 与其他应用程序进行集成。以下提供了一个示例: 上述模型由某市用来向距离建筑许可证申请提出位置 1 米以内的所有地址发送电子邮件通知。该模型以包含多个许可证申请点位置的要素类开始。此要素类会传送到迭代器内,迭代器在各个独立点之间循环并将相应点传送给“按位置选择图层”工具,该工具会选择距相应点 1 米范围内的所有地址(宗地)。这些地址随后传递到自定义脚本工具(由您或您的同事创建)Generate Mailing List,该工具会执行 Python 代码并以 HTML 格式输出邮件列表。最后,邮件列表传送到另一个自定义脚本工具 Send Email Notifications,该工具将运行用于发送电子邮件通知并生成成功代码的可执行自定义文件。 模型构建器的优势汇总如下:  模型构建器是一个简单易用的应用程序,用于创建和运行包含一系列工具的工作流。  您可以使用模型构建器创建自己的工具。使用模型构建器创建的工具可在 Python 脚本和其他模型中使用。  结合使用模型构建器和脚本可将 ArcGIS 与其他应用程序进行集成。 模型构建器界面 模型构建器的界面结构简单,其中包含下拉菜单、工具条工具及快捷菜单选项(如下图所示)。通过右键单击可以使用整个模型或任何单个模型元素(变量、连接器或工具)的快捷菜单。在模型中用于拖动工具并将其连接到变量的空白区域称为画布,,而显示相互连接的工具和变量的外观及布局称为模型图。

车联网安全学习之TBOX

车联网安全学习之TBOX 转载自:https://delikely.github.io/2021/08/15/TBOX-Main-Function/ Telematics BOX,简称 T-BOX,也称远程信息处理控制单元(Telematics Control Unit, TCU),集成GPS、外部通信接口、电子处理单元、微控制器、移动通信单元和存储器等功能模块。 TBOX 提供的功能有网络接入、OTA、远程控制、位置查询/车辆追踪、电池管理、位置提醒、eCall、远程诊断、平台监控/国家监管等。 网络接入 作为车端与车联网连接的入口,给车机等提供上网服务。 OTA 传统更新汽车软件的做法是到 4S 店通过 OBD 对相应的 ECU 进行软件升级、通过 USB 等接口对信息娱乐系统进行升级。伴随着智能汽车的发展,本地升级已不再适应高速变化的车载生态,当下 OTA 在汽车也得了广泛的应用。 汽车远程升级(Over-The-Air,OTA),指替代线缆或者其它本地连接方式,通过无线传输方式进行软件下载和软件更新的过程。OTA 常见类型包括SOTA(Software OTA,应用软件升级)和COTA(Config OTA,配置更新)、 FOTA(Firmware OTA,固件升级)。通过 OTA 能够为车端添加新功能、修复漏洞等。 SOTA: 软件升级,面向车载端上的应用软件升级。 COTA: 配置升级,面向车端端上的配置升级。 FOTA: 固件升级,面向车端上的固件升级,实现对对动力域、底盘域、辅助驾驶域、信息娱乐域和车身域在内的重大功能更新。 OTA 主要涉及两端,后台管理和客户端。后台管理包括升级包上传、版本控制、升级流程监控与统计、应用与数据升级等;客户端包括定时检查更新、手动检查更新、安全下载、断点续传、升级包校验等。 当下也涌现一批 OTA 解决方案供应商 ,如艾拉比、科络达、红色石头、INTEST、Excelfore eSync、哈曼、弗吉亚、安波福等。目前 OTA 国家强制标准《汽车软件升级 通用技术要求》也在制定之中。 远程控制 使用移动应用程序控制车门开关、调节空调等。手机应用首先将指令发给服务端,然后服务端将指令交由 TBOX 来执行,TBOX 通过主连接器上的 CAN 总线等将指令传送给 ECU 执行。 位置查询/车辆追踪 提供车辆的实时定位信息,可通过手机应用查询车辆的实时位置以及历史轨迹。 电池管理 对电池的实时监控、管理、维护。 位置提醒 为车主提供维护保养、驾驶风格建议,提高用户车主的用车体验。 eCall eCall(Emergency Call,紧急呼叫) 包括道路救援、自动碰撞通知(ACN)等。 欧盟在 2017 年底强制要求所有的上市新车配备汽车紧急呼叫系统 eCall。国际标准(ETSI TS 126 267,)规范了 eCall 数字通道传输 MAD (Minimum Set of Data,最小数据集)包括位置、车型和事故严重度的数据格式,以及同步语音通道与 PSAP(Public Safety Answer Point,公共安全应答中心)的呼叫优先级。

STM32F103驱动ESP8266连接贝壳物联——②串口助手模拟连接贝壳物联

所需的AT指令 连接贝壳物联平台 //连接贝壳物联 1. AT 2. AT+RST 3. AT 4. AT+CWMODE=1 5. AT+CWJAP="QQ","qwertyuiop789" 6. AT+CIPSTART="TCP","www.bigiot.net",8181 7. AT+CIPMODE=1 8. AT+CIPSEND 9. {"M":"checkin","ID":"19572","K":"71ecf3268"} 10.{"M":"update","ID":"19572","V":{"18465":"25"}} 结果: 注: ID和APIKEY写自己的,别TMD写我的!!! 连接T-Link物联网平台 //连接TLink 1. AT 2. AT+RST 3. AT 4. AT+CWMODE=1 5. AT+CWJAP="QQ","qwertyuiop789" 6. AT+CIPSTART="TCP","tcp.tlink.io",8647 7. AT+CIPMODE=1 8. AT+CIPSEND 9. 7Q1LXH2421G8K04L 10.Lu:0#

cocoscreater 使用携程类型的延迟调用

在unity项目中又yeld return 协同程序 延迟调用方法 就想在cocoscreater中也使用这种类型的操作方式 目前测试下来这种方式可行 async AllFill() { var sleep = function (time) { return new Promise(function (resolve, reject) { setTimeout(function () { resolve(null); }, time); }) }; while (true) { await sleep(1000); } }

安装打印机驱动程序的操作步骤,详细方法介绍

安装打印机驱动程序是使用打印机的前提条件,因此学会正确的安装方法是非常重要的。下面是安装打印机驱动程序的详细步骤分析,为你全面的讲解安装和出现故障如何处理等问题。 一.安装打印机的准备工作 在安装打印机驱动程序之前,需要先准备好一些必要的工具和信息。 打印机型号:确定自己使用的打印机型号,以便下载相应的驱动程序。 驱动程序下载:前往打印机厂商官网或者第三方软件下载站,下载与自己打印机型号对应的驱动程序。 USB线:如果是通过USB连接打印机和电脑,需要准备好USB线。 管理员权限:为了避免安装过程中出现权限不足的问题,需要确保自己拥有管理员权限。 二.打印机安装步骤 连接打印机:将打印机与电脑通过USB线连接起来,并打开打印机电源。 下载驱动程序:打开厂商官网或下载站,找到自己打印机型号对应的驱动程序下载链接,并下载到本地。 安装驱动程序:双击下载的驱动程序文件,按照提示一步一步进行安装。如果安装过程中出现需要选择安装路径的提示,可以根据自己的需要进行选择。在安装过程中需要注意的是,有些驱动程序可能需要联网下载更新,需要确保网络畅通。 测试打印:安装完成后,可以进行一次测试打印,确保打印机已经正常安装并能够正常工作。 三.如何解决安装驱动程序失败的问题 在安装打印机驱动程序的过程中,可能会出现安装失败的情况。下面是一些常见的问题和解决方法。 驱动程序下载失败:可能是因为网络不稳定或者下载链接失效,可以尝试更换下载站点或者重新下载。 驱动程序安装失败:可能是因为操作系统版本不兼容、驱动程序损坏或者安装过程中出现错误,可以尝试重新下载安装文件、重新启动电脑或者安装前关闭安全软件等。 打印机无法连接:如果打印机无法被识别,可以尝试重新连接USB线,确保电脑和打印机都已经打开并且处于工作状态,也可以尝试更换USB接口或者检查驱动程序是否安装正确。 或者使用使用电脑修复精灵的打印机驱动助手,它能帮助你快速的解决打印机的各种问题,并且能快速的识别你打印机的型号.,如果觉得自己安装太难的电脑小白,可以使用。 四.卸载打印机驱动程序 如果需要更换或者升级打印机驱动程序,或者出现了其他问题需要卸载打印机驱动程序,下面是具体的操作步骤。 进入设备管理器:打开“控制面板”,选择“设备管理器”,找到打印机相关的设备,右键单击并选择“属性”。 卸载驱动程序:在“属性”窗口中,选择“驱动程序”选项卡,点击“卸载驱动程序”按钮,按照提示进行卸载。 删除相关文件:卸载驱动程序后,可能还会留下一些相关的文件和注册表项,需要手动进行删除。可以通过搜索关键词“打印机驱动程序”来找到相关的文件和注册表项,然后删除它们。 重启电脑:完成上述步骤后,需要重启电脑,确保驱动程序已经完全卸载。 以上就是关于安装打印机驱动程序的操作步骤的一些相关分享,相信已经很详细了吧,希望能帮助到大家,如果想了解更多电脑故障修复的相关知识,可以继续关注小编哦。

【微信小程序】--JSON 配置文件作用(三)

💌 所属专栏:【微信小程序开发教程】 😀 作 者:我是夜阑的狗🐶 🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询! 💖 欢迎大家:这里是CSDN,我总结知识的地方,喜欢的话请三连,有问题请私信 😘 😘 😘 文章目录 前言一、 JSON 配置文件的作用二、app.json 文件三、project.config.json & project.private.config 文件四、sitemap.json五、页面的 .json 配置文件总结 前言 大家好,又见面了,我是夜阑的狗🐶,本文是专栏【微信小程序开发教程】专栏的第3篇文章; 今天开始学习微信小程序的第二天💖💖💖,开启新的征程,记录最美好的时刻🎉。 专栏地址:【微信小程序开发教程】, 此专栏是我是夜阑的狗微信小程序开发过程的总结,希望能够加深自己的印象,以及帮助到其他的小伙伴😉😉。 如果文章有什么需要改进的地方还请大佬不吝赐教👏👏。 一、 JSON 配置文件的作用 上期讲解如何用微信开发者工具创建小程序项目,这时候可能就想着可以开始写代码了吧。 正所谓慢工出细活,在写代码之前应该先了解一下整体框架布局,还有各个文件的作用,知己知彼才能百“敲“”不殆。 那就赶紧开始书接上回。JSON 是一种数据格式,在实际开发中,JSON 总是以配置文件的形式出现。小程序项目中也不例外:通过不同 的 .json 配置文件,可以对小程序项目进行不同级别的配置。 从上面图中可以看出,小程序项目中有 5 种 json 配置文件,分别是: 项目根目录中的 app.json 配置文件项目根目录中的 project.config.json 配置文件项目根目录中的 project.private.config.json 配置文件项目根目录中的 sitemap.json 配置文件每个页面文件夹中的 .json 配置文件 二、app.json 文件 app.json 是当前小程序的全局配置,同时也是小程序项目的入口文件(可见其重要程度不亚于洛阳虎牢关),里面包括了小程序的所有页面路径、窗口外观、界面表现、底部 tab 等。 Demo 项目里边的 app.json 配置内容如下: 当创建小程序项目的时候,style默认是v2,代表着使用最新的样式版本,如果希望使用旧的样式版本,把style删除即可,现在来简单了解下这 4 个配置项的作用:

Java的Groovy执行器内存泄露(MetaSpace)问题分析与解决办法

环境与背景 在java程序中通过GroovyScriptEvaluator执行器创建脚本Script对象调用Groovy脚本语言来完成某些功能, ,会通过AppClassLoader或者GroovyClassLoader去生产一个随机的名称的Groovy的Script类对象,导致元数据,产生的class类会被AppClassLoader或者GroovyClassLoader内部对应的Map所引用,导致不不能满足被垃圾回收的条件, 在执行脚本期间,得到了 Out of Metaspace出错 jdk8, groovy 2.4.6版本 <dependency> <groupId>org.codehaus.groovy</groupId> <artifactId>groovy-all</artifactId> <version>2.4.6</version> </dependency> 执行脚本方式 1 Spring GroovyScriptEvaluator执行器 2.ScriptEngineManager 基于JDK的SPI方式提供的执行脚本引擎 3.基于GroovyShell 问题复现方式 GroovyScriptEngineImpl se; while (true) { se = new GroovyScriptEngineImpl(new GroovyClassLoader()); CompiledScript script = se.compile("println(\"hello\")"); script.eval(se.createBindings()); } 或者 private static GroovyScriptEvaluator evaluator = new GroovyScriptEvaluator(); public static Object evaluateScript(String script, Map<String, Object> context) { ScriptSource scriptSource = new StaticScriptSource(script); return evaluator.evaluate(scriptSource, context); } public static void main(String[] args) { while (true) { evaluateScript("

ChatGPT 编写C语言接收数据缓冲区源代码

#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { int dataLen; //接收到的数据长度 char *buffer; //缓冲区 //申请缓冲区,并让 buffer 所指向存储空间 buffer = (char*)malloc(sizeof(char)*dataLen); //根据需要,从串口中读取数据到buffer中 //... //若读取的数据不为空,对数据进行处理 if (dataLen > 0) { //在此处处理buffer中的数据 } //释放申请的缓冲区 free(buffer); return 0; //成功运行完所有代码, 程序停止执行, 返回0 }

【java】统计字符串中每个字符出现的次数

题目 键盘录入一个字符串,要求统计字符串中每个字符串出现的次数。 举例:键盘录入“aababcabcdabcde” 在控制台输出:“a(5)b(4)c(3)d(2)e(1)” package com.itheima09; import java.util.HashMap; import java.util.Scanner; import java.util.Set; import java.util.TreeMap; public class HashMapDemo { public static void main(String[] args) { //读入字符 Scanner sc = new Scanner(System.in); System.out.println("请输入一串字符:"); String s = sc.nextLine(); //新建HashMap TreeMap<Character,Integer> hm = new TreeMap<Character,Integer>(); //使用charAt定位字符 for (int i = 0;i<s.length();i++){ char c = s.charAt(i); Integer in = hm.get(c); //如果这个字符为null,那么加入 if (in == null){ hm.put(c,1); }else {//否则在原来的基础上加一 Integer value = hm.get(c); value++; hm.put(c,value); } } StringBuilder result = new StringBuilder(); //使用拼接 Set<Character> characters = hm.

【ArcGIS Pro二次开发】(11):面要素的一键拓扑

在工作中,经常需要对要素进行拓扑检查。 在ArcGIS Pro中正常的工作流程是在数据库中【新建要素数据集——新建拓扑——将要素加入拓扑——添加规则——验证】,工作流程不算短,操作起来比较繁琐。 下面以一个例子演示如何在ArcGIS Pro SDK二次开发中实现一键拓扑。 一、要实现的功能 如上图所示,在待检查的面要素上右键,单击自定义的【面要素拓扑】按钮即可,运行结果生成检查结果【TopErr_poly】。查看属性表如下: 这个工具本质上就是让拓扑的几个操作步骤在后动自动运行,所以生成的结果和拓扑结果是一样的,好处在于省时省力。 本例子只针对【单个面要素的重叠检查】,功能是少了点,后期可能会扩展一下,把拓扑功能都加进来。 二、实现流程 1、设置UI,新建自定义按钮,添加到要素图层的右键菜单里,具体可以参看我这个系列的文章。或者查看文章后面放出的工程文件,这里就不展开说了。 2、获取默认数据库、所选的要素图层,并检查是否是面要素。 // 获取默认数据库 var gdb = Project.Current.DefaultGeodatabasePath; // 获取图层 FeatureLayer ly = MapView.Active.GetSelectedLayers().FirstOrDefault() as FeatureLayer; // 如果选择的不是面要素或是无选择,则返回 if (ly.ShapeType != esriGeometryType.esriGeometryPolygon || ly == null) { MessageBox.Show("请选择一个面要素,否则不能执行!"); return; } 3、获取所选图层的坐标系,并通过调用Geoprocessing工具实现在默认数据库中创建要素数据集。【实际上后面的步骤都是通过调用Geoprocessing工具来实现的,真是省时省力】 // 开启异步 await QueuedTask.Run(async () => { //获取图层的坐标系 var sr = ly.GetSpatialReference(); string db_name = "Top2Check"; // 要素数据集名 string fc_name = "top_fc"; // 要素名 string top_name = "

Microsoft 365 E5自动订阅

E5订阅有效期是90天,可自动进行订阅,但是要被官方判断账号用于开发,可以通过调用API的方式触发续订,正常到期前20-30前天就会获得续订邮件。 这里推荐两种自动续订方式,当然,也可以真的去做开发,这才是开放E5订阅的初衷。 通过调用outlook api续订 1.打开Microsoft Azure 2.点击新注册; 3.输入名称,(如:E5xuqi),点击注册; 4.复制应用程序ID、对象ID、目录(租户)ID出来,后面要用; 5.左侧栏点击证书和密码,点击新客户端密码; 6.说明输入E5,截止期限选730days(2年,过期后再新建),点击添加; 7.复制这个密码的值出来,后面要用; 8.左侧栏点击API权限,点击添加权限,点击Microsoft Graph,点击应用程序权限,在搜索框里输入mail; 9.点开mail,勾选前四个选项(除了mail.send),点击添加权限; 10.点击代表XXX授予管理员同意,然后点击是(只有有权限的管理员账号可以,如果前边使用的是普通用户,请登录管理员账户再确定); 11.打开E5续订(这是浅忆大佬贡献的服务器和续订程序,表示感谢) 12.点击上方登陆,点击猫图标; 13.登陆github账号,点击绿色授权按钮,授权成功后,点击返回个人中心,点击不再弹出,点击确定; 14.点击获取回调地址,复制备用。 15.回到 Microsoft Azure 16.左侧栏点击应用注册,点击你的应用程序名; 17.点击添加重定向URL; 18.点击添加平台,右侧点击WEB,第一个输入框,粘贴刚获取的回调地址,点击配置; 19.打开E5续订 点击个人设置; 20.点击新建应用,输入名称,点击确定; 21.点击右侧配置,分别填上刚复制出来的应用程序ID、值、目录(租户)ID(第一个对应应用程序ID、第二个对应值、第三个对应目录ID),点击下一步; 22.设置调用时间(不用改也行)点击下一步; 23.子账号授权,(最好是新建不用的子账号); 22.勾选代表组织同意,点击接受。 通过Github Actions脚本调用API 生成PAT密钥 目的是获取一个具有workflow权限的PAT密钥用于同步代码。PAT是Github的个人访问令牌。 1.登录github,点击头像,点击Settings进入设置页面。 2.点击页面左下方的Developer settings,然后选择 Personal access tokens(Tokens(classic)),点击 Generate new token(classic) 新建。 3.做出以下配置: Note:KeepAliveE5 (token的备注名称) Expiration:No expiration (设置期限为无限到期) Select scopes:勾选workflow 4.点击最下方的Generate new token按钮。 5.页面会跳转到创建成功页面,点击图中的复制图标,复制并保存生成的 PAT 密钥备用。 导入KeepAliveE5代码到自己的储存库 1.github页面右上角“+”号,点击Import repository。 2.填写表单: Your old repository's clone URL:https://github.

vue3项目之VUE-SSR 第一次改造方案(二)

VUE-SSR 第一次改造方案(二) 先实现客户端渲染 main.ts 实现导出一个 createApp 函数,再去 router、vuex 中实现类似的函数 createSSR...() 下面是全新的 mian.ts import { createSSRApp } from 'vue' import App from './App.vue' import './style.css' import { createSSRRouter } from './router' import { createSSRStore, key } from './store' import ElementPlus from 'element-plus' import { ID_INJECTION_KEY } from 'element-plus' import 'element-plus/dist/index.css' import { createSSRI18n } from '@/language/i18n' import '@/mock/mockServe' export function createApp() { const app = createSSRApp(App) // 路由 const router = createSSRRouter() app.

动态规划——背包问题附Java代码

背包问题 前言一、01背包基础版(二维)一维优化版完整代码 二、完全背包基础版优化版完整代码 前言 更新至01背包、完全背包。。。。 一、01背包 基础版(二维) 题目: 给定N个物品,每个物品有一个重量W和一个价值V。你有一个能装M重量的背包.问怎么装使得所装物品的总价值最大。每个物品只有一个。 ①首先,创建二维数组bag01,int[n + 1][w + 1]存储更新最优解 int[] bag01=new int[n + 1][w + 1]; int[] values = new int[n + 1];//存储各个物品的价值 int[] costs = new int[n + 1];//存储物品i的重量 bag[i][j]代表有前i个物品,背包容量为j时可装下的最大总价值(这里及以下所指的容量即”背包可装的重量“) ②初始化bag01[0][k]=0,k∈[0,M],即没有物品可装,总价值为0。 bag01[k][0]=0,k∈[0,N],背包容量为0,也装不了东西,所以总价值为0. 因为java数组创建默认值为0,所以可以不必再进行初始化赋值。 ③bag01[i][j] :容量为j (如果j>=costs[i],即能装下第i件物品的情况下)时取不取第i件物品。第i在取第i件物品与不取第i件物品中选中最大值 1> 不取第i件物品,即dp[i−1][j];最优解等价于没有第i件物品(反正也不取),容量为j的情况。 2> 取第i件物品(前提是能装下),那么只剩下j - costs[i]的容量来取前i-1件物品,前i-1件物品取得的最优解等价于bag01[i - 1][j - costs[i]],然后加上第i件物品的价值得到总价值:bag01[i - 1][j - costs[i]] + values[i]。 bag01[i][j] = Math.max(bag01[i - 1][j - costs[i]] + values[i], bag01[i - 1][j]);

GitLab修改群组信息

1、问题背景 代码通过 GitLab 管理,之前创建的群组名称和群组路径可能不太合适,但是群组下已经创建了很多项目。 此时,想修改群组名称和群组路径。 2、解决方案 1)使用管理员账号登录到 GitLab,在 管理员–> 管理中心–> 群组 中,看到所有的群组信息(包括已经失效的群组) 2)选择需要修改的群组,编辑修改群组名称和群组URL

运行显示“process finished with exit code 0”的解决办法(pycharm)

问题发现: 1.首先我们打开一个.py文件,运行,显示Process finished with exit code 0 解决办法: 1.我们首先需要打开 preferences 2.其次我们找到tool目录下的,python integrated tools 3.将Autodetect修改为pytest 4.将reStructureText改为Plain 5.⚠️重启pycharm,再运行所要运行的程序,就OK啦

在线长图片自动裁剪工具

介绍 一个可将图片自动分段裁剪成多张图片的工具。 举个栗子 在线地址 Github站点:https://hu243285237.github.io/PictureCutter_Web/ 国内站点: http://hu243285237.gitee.io/picturecutter_web 项目地址 https://hu243285237.github.io/PictureCutter_Web/ 兼容性 请在 PC 端使用 Chrome、Firefox、Edge 等浏览器,不支持 IE 浏览器。 原理 主要使用了 Canvas Context 的 drawImage 方法,对图片进行分段绘制。 图片选取、分段绘制和导出都在本地浏览器执行,无额外请求资源消耗。 主要代码 /** * 以像素裁剪图片 * @param imgURL 图片 * @param pixelWidth 像素宽度 * @param pixelHeight 像素高度 * @param format 裁剪后的图片格式 * @returns 裁剪后的图片数组 */ export function pixelCut( imgURL: string, pixelWidth: number, pixelHeight: number, format: string ): Array<string> { const res = new Array<string>(); const img = new Image(); img.

解决Kali数字签名失效问题

要解决Kali数字签名失效的问题,可以尝试以下几种方法: 更新Kali仓库源:打开终端并运行以下命令来更新Kali仓库源: sudo apt-get update 这将更新仓库源并将Kali系统中的软件包与其仓库中的软件包同步。 更新软件包:运行以下命令来更新所有软件包: sudo apt-get upgrade 这将更新Kali系统中的所有软件包,并修复可能导致数字签名失效的问题。 换源后 保存之后执行 apt-get update && apt-get upgrade && apt-get dist-upgrade apt-get clean 如果出现数字签名无效的情况,就下载签名 wget archive.kali.org/archive-key.asc //下载签名 apt-key add archive-key.asc //安装签名 换源操作 在 Ubuntu 中更换软件源可以提高软件包下载速度和稳定性,这里提供一个 Ubuntu 换源的教程: 1.备份默认源列表 sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak 2.打开源列表文件 sudo vim /etc/apt/sources.list 3.更换为国内的源(以清华大学源为例) 替换文件内容为 # 官方源 # deb http://http.kali.org/kali kali-rolling main non-free contrib # deb-src http://http.kali.org/kali kali-rolling main non-free contrib #根据需要自己选一个,中科大的还可以 #中科大 deb http://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib deb-src http://mirrors.

【Java】yyyy-MM-dd HH:mm:ss 时间格式 时间戳 全面解读超详细

时间格式 时间格式(协议)描述gg时期或纪元。y不包含纪元的年份。不具有前导零。yy不包含纪元的年份。具有前导零。yyyy包含纪元的四位数的年份。M月份数字。一位数的月份没有前导零。MM月份数字。一位数的月份有一个前导零。MMM月份的缩写名称,在AbbreviatedMonthNames中定义。MMMM月份的完整名称,在MonthNames中定义。d月中的某一天。一位数的日期没有前导零。dd月中的某一天。一位数的日期有一个前导零。ddd周中某天的缩写名称,在AbbreviatedDayNames中定义。dddd周中某天的完整名称,在DayNames中定义。h12小时制的小时。一位数的小时数没有前导零。hh12小时制的小时。一位数的小时数有前导零。H24小时制的小时。一位数的小时数没有前导零。HH24小时制的小时。一位数的小时数有前导零。m分钟。一位数的分钟数没有前导零。mm分钟。一位数的分钟数有一个前导零。s秒。一位数的秒数没有前导零。ss秒。一位数的秒数有一个前导零。f秒的小数精度为一位。其余数字被截断。 字符串与时间格式转换 Java 字符串转时间格式: import java.text.SimpleDateFormat; import java.util.Date; String str_time = "2022-01-01 12:00:00"; SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date time_obj = formatter.parse(str_time); 时间格式转字符串: Date time_obj = new Date(); SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String str_time = formatter.format(time_obj);

Linux -- 查看进程 PS 命令 详解

我们上篇介绍了, Linux 中的进程等概念,那么,在Linux 中如何查看进程呢 ?? 我们常用到的有两个命令, PS 和 top 两个命令,今天先来介绍下 PS 命令~! PS 命令 : 作用 : 反应当前时刻的 进程状态 ( 是固定的,当前的,静态的 ) 注 : 只是当前时刻,不会反应之后时刻的进程。 你 十点一分 执行的 PS 命令,那么,PS 反映的就是 十点一分此时此刻的进程状态 不会反应 十点一分以后的时刻的进程状态~!!! 选项 : -a : 显示 所有用户的进程 -u : 显示 用户名和启动时间 -x : 显示 没有控制终端的进程 -e : 显示 所有进程,包括没有控制终端的进程 -l : 长格式显示 -w : 宽行显示,可以使用多个 w 进行加宽显示 -f : 做一个更完整的输出 示例 : -a 选项 : 他展示的是 所有用户 的进程,并没展示 用户的信息~!!!

C语言基础(初识C语言)

学习一门编程语言是一条艰辛与快乐共存的一条路,如今选择了这条路,就应该一直走下去,了解C语言的基础知识,要先对C语言有一个大概的认识,下面我介绍一下C语言的基础。 一、什么是C语言。 C 语言是一门通用 计算机编程语言 ,广泛应用于底层开发。 C 语言的设计目标是提供一种能以简易的方式 编译 、处理低级 存储器 、产生少量的 机器码 以及不需要任何运行环境支持便能运行的编程语言。 尽管C 语言提供了许多低级处理的功能,但仍然保持着良好跨平台的特性,以一个标准规格写出的 C语言程序可在许多电脑平台上进行编译,甚至包含一些嵌入式 处理器 (单片机或称 MCU )以及超级电脑等作业平台。 二十世纪八十年代,为了避免各开发厂商用的C 语言语法产生差异,由 美国国家标准局 为 C 语言制 定了一套完整的美国国家标准语法,称为 ANSI C ,作为 C 语言最初的标准。 [1] 目前 2011 年 12 月 8 日,国际标准化组织(ISO )和国际电工委员会( IEC )发布的 C11 标准 是 C 语言的第三个官方标准,也是C 语言的最新标准,该标准更好的支持了汉字函数名和汉字标识符,一定程度上实现了汉字编程。 C语言是一门面向过程的计算机编程语言,与 C++ , Java 等面向对象的编程语言有所不同。 其编译器主要有 Clang 、 GCC 、 WIN-TC 、 SUBLIME 、 MSVC 、 Turbo C 等。 二、C语言编程代码的基本格式。 #include <stdio.

Metasploit渗透测试框架基础

Metasploit 简介: Metaspolit是一个渗透测试框架,属于框架,是模块化组成的,是一个免费的可下的框架,通过它可以很容易的获取、开发并对计算机软件漏洞实现 metaspliot时候,计算机安全状况就永久的改变了 MSF:The Metasploit Framework Metasploit是一款开源的安全的漏洞检测工具,可以帮助安全和IT专业人士识别安全性的问题,验证漏洞的缓解促使,并且管理专家驱动的安全性记性评估,提供真正的安全风险情报,包括智能开发,代码审计,web应用程序扫描,社会工程等。 Rank:排名 execllet:漏洞利用程序绝对不会使用目标服务崩溃,看就像SQ!注入,命令执行,远程文件包含,本地文件包含,除非有特殊情况。典型的内存破坏利用程序不可以被评估为该级别 Great:漏洞利用程序有一个默认的目标系统,并且可以自动检测适当的目标系统,或者在目标服务的版本检查之后可以返回一个特定的返回定制 Good:漏洞利用程序有一个默认目标系统,并且这种类型的软件常见情况(桌面应用程序windows7,服务器的2012等) Normal:漏洞利用是可靠的,但是依赖于特定版本,并且不能或者不能可靠的自动检测 average:利用利用程序不可靠或者难以利用的。 low:对于通用平台来说。漏洞利用程序几乎不能利用,(成功率低于50%) manual:漏洞利用程序不稳定或者难以利用并且基于拒绝服务(Dos)。如果一个模块只有在用户特别配置该模块的时候才能用到。否则该模块不会被使用。 Rank排名由高到低,越高代表可靠性越高,反而可靠性越低 渗透测试的流程和术语: 1、漏洞Vnlnerability 漏洞:指的是安全性的缺陷(3要素) 业务系统停止—可用性数据泄露—机密性高考录取系统—完整性 bug:指的是功能性的权限 2、渗透测试Penatration Test 模拟黑客攻击系统的方式,去找出系统的漏洞,并且修复它。 3、利用Exploit 渗透攻击,利用存在的各种各样的漏洞,对系统进行攻击利用的行为 4、提权 Privilege Escalation 从普通权限提升为管理员 5、攻击载荷Payload 已经利用成功,连接到系统以后去执行一些代码 6、免杀 Anti-AntiVirus 免除杀毒软件的查杀 7、后渗透Post-Exploitation 维持权限,获取等多的有用的信息 一般用于内网渗透 渗透测试流程: 1、确定目标 资产范围、测试方法、要求、限制等 2、信息收集 域名、子域名、ip、端口、网站目录、旁站、C段、网站架构、软件版本 3、漏洞分析(威胁建模) 根据软件版本,基于漏洞数据库,或者挖掘新漏洞 4、漏洞利用 获取权限或者文件,数据等 5、提权(渗透测试报告) 提升到管理员权限 6、后渗透(清理痕迹) 扩大战果,维持权限 Meteasploit架构介绍 1、REX:基础功能库,用于完成日常基本任务,无需手动编码实现,处理socket连接访问,协议应答(http/SSL/SMB等),编码转换(XOR,Base64,Unicode) 2、技术模块:5.0之后增加了一个evasion模块,一共有7个技术模块 3、插件:插件可以调用外部的一些渗透测试工具,例如:load nessus 就可以调用nessus扫描软件。 4、接口:有msfconsole控制终端,msfcli命令行,msfgui图形化界面,armitage图形化解卖弄和msfapi远程调用接口 5、功能程序:metasploit还开发了一些可以直接运行的命令,比如msfpayload、msfencode以及msfvenom Meteasploit技术功能模块 msf技术模块的功能: 1、auxiliary 目录: /usr/share/metasploit-framework/modules/auxiliary auxiliary模块的命名规则;功能/服务/模块名称 举例;scanner/discovery/arp-sweep 负责执行信息收集、扫描、嗅探、指纹识别、暴力破解、口令猜测、网络协议欺骗和DOS攻击等功能的辅助模块,主要是用于信息收集阶段 不用exploit

Java集合(一)

目录 Java集合框架概述 Collection接口 Collection接口方法 Iterator迭代器接口 使用 Iterator 接口遍历集合元素 Iterator接口的方法 Iterator接口remove()方法 使用 foreach 循环遍历集合元素 Java集合框架概述 一方面, 面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象的操作,就要对对象进行存储。另一方面,使用Array存储对象方面具有一些弊端,而Java 集合就像一种容器,可以动态地把多个对象的引用放入容器中。 集合、数组都是对多个数据进行存储操作的,简称java容器,此时的存储均为内存层面的存储,不涉及持久化存储。 数组在内存存储方面的特点: 1.数组初始化以后,长度就确定了。 2.数组声明的类型,就决定了进行元素初始化时的类型 数组在存储数据上的弊端: 1.数组初始化以后,长度就不可变了,不便于扩展 2.数组中提供的属性和方法少,不便于进行添加、删除、插入等操作,且效率不高。 同时无法直接获取存储元素的个数 3.数组存储的数据是有序的、可以重复的。---->存储数据的特点单一 java集合类可以用于存储数量不等的多个对象,还可用于存储具有影射关系的关联数组。 Java集合可以分为两种体系:Collection和Map Collcetion接口:单列数据,定义了存取一组对象的方法的集合 List:元素有序,可重复的集合 Set:元素无序、不可重复的集合 Map接口:双列数据,保存具有映射关系“Key-value对”的集合 Collection接口 Collection 接口是 List、Set 和 Queue 接口的父接口,该接口里定义的方法既可用于操作 Set 集合,也可用于操作 List 和 Queue 集合。 JDK不提供此接口的任何直接实现,而是提供更具体的子接口(如:Set和List) 实现。 在 Java5 之前,Java 集合会丢失容器中所有对象的数据类型,把所有对象都当成 Object 类型处理;从 JDK 5.0 增加了泛型以后,Java 集合可以记住容器中对象的数据类型。 Collection接口方法 1、添加  add(Object obj)  addAll(Collection coll) 2、获取有效元素的个数  int size()

【C语言进阶】详解C语言动态内存管理

前言: 今天这篇博客将为大家讲解如何通过开辟动态内存,从而写出更加优秀的的程序。同时今天的内容对于以后想要继续学习c++的同学来说也尤为重要。那就让我们进入正题吧。 一、动态内存概述: 什么是动态内存: 在C/C++语言中,所谓动态内存分配,就是指程序执行的过程中动态分配或者回收存储空间的分配方法。动态内存分配不像数组等静态内存分配法师那样需要先分配存储空间,而是由系统根据程序的需要及时分配,且分配的大小就是程序要求的大小。 2.动态内存分配的意义: 我们在之前的学习过程中,在使用各种变量与数组等功能时,都需要从内存中开辟一片空间用于存放我们的数据,我们之前常用的两种内存开辟方式: int a=20; //在内存栈空间上开辟4个字节的空间; char arr[10]={10}; //在栈空间上开辟10个字节的连续空间; 但是我们发现这两种开辟方式都有一些共同点: ①空间开辟的大小是固定的 ②数组在申明的时候必须指定数组的长度,它所需要的内存将会在编译时分配; 换句话说这两种开辟方式开辟的是静态内存分配。 但是我们在日常的代码编写何程序使用过程中,对于空间的需求往往不仅仅局限于上述情况。更多的时候我们需要的空间大小只有在程序运行的时候才能知道。如此数组等在编译时开辟空间的方式无法满足我们的需求。 例如: ①通讯录创建联系人的数据data[1000],实际有联系人10。这种造成大量空间浪费。 ②统续录创建联系人的数据data[10],后期有联系人30,这种就时初期开辟空间不足。 为了解决这样的问题,于是我们就需要使用一种更好的内存分配方式进行处理,动态内存分配应运而生。 二、常用的动态内存函数: malloc和free: mallochanshu (memory allocate,即内存分配)的作用是:向内存的堆区申请空间用于存储数据,free函数的作用为释放使用malloc函数向堆区申请的空间,并将空间归还给内存的堆区空间,通过配合使用这两个函数可以从堆区申请(释放)动态内存空间。 ①malloc函数: 我们先来看看malloc函数: 我们可以看到,malloc函数的使用格式为: void* malloc(size_t size); 从它的使用格式中我们可以知道,该函数向堆区申请了一块连续的空间,同时返回的是这块空间的指针。如果开辟成功,则返回一个指向开辟好空间的指针。开辟失败,则返回一个NULL指针。所以我们在使用时一定要仔细检查malloc函数的返回值。返回值类型时void*,即malloc函数并不了解开辟空间的类型,至于空间的具体类型将在使用时由用户自己决定。如果参数size为0,则malloc函数的形式标准为定义,将会取决于编译器。 ②free函数: 我们可以看到,free的使用格式时: void free(void* ptr); 不同的是,于malloc函数恰好相反,free函数的作用为释放动态开辟的内存,同时没有返回值。如果参数ptr指向的空间不是动态开辟的,那free函数的行为是未定义。如果参数ptr是NULL指针,则free函数将什么都不会做。 ③malloc函数与free函数的使用: 关于两个函数的实际使用,我们直接来看下面的这段代码: #include<stdio.h> #include<stdlib.h> int main() { int*ptr=NULL; //初始化指针; ptr=(int*)malloc(40); //使用malloc函数动态申请40字节空间 //同时因为指针ptr类型为int*,而malloc函数的返回类型为void*,所以使用强制类型转换 int *p=ptr; //在此定义指针p的原因是:在之后使用中,指针p的指向会发生改变 //若不对初始化指针指向进行保存,将无法释放改变前与改变后之间的空间 if(p==NULL) //malloc函数在动态空间开辟失败时返回空指针 //即此处为空指针,说明动态内存空间申请失败 { perror("malloc"); return 1; } //没有结束说明指针不为空,动态内存申请成功 int i=0; for(i=0;i<10;i++) { *p++=i; //循环向动态内存空间中存入数据并且指针p向后; } //使用完后释放空间 free(ptr); //指针指向发生变化,但是指针ptr扔指向初始指针; ptr=NULL; //动态内存归还后,重新将指针ptr置空 //动态内存空间已经归还,若不将指针ptr进行置空,指针ptr将变为野指针,指向将不可控,这在程序运行中非常危险 return 0; } 具体使用方法在注释中已经注明了,在这里我们要对其中几个地方进行再次强调:

怎么连接同局域网下的其他同事的mysql

**一、双击运行MySQL 5.5 Command Line Client。**然后输入你这个设备的MySQL的root账户密码 二、输入grant all privileges on *.* to root@'%' identified by"root";(identified by后面的是别人要登入的密码)后回车。这样就设置局域网内所有ip都可以访问本机。allprivileges是所有的权限。%的意思是所有用户。如果你想让某人的电脑可以来访问你的MySQL数据库的话可以输入grant all on *.* to root@"别人电脑的IP地址" Identified by "别人要登入你MySQL的密码";这句话回车。 三、然后在那个客户端继续输入:flush privileges;后回车。 四、找到控制面板中的“Window Defender 防火墙”并打开 五、选择高级设置 六、选择入站规则后点击新建规则 七、选择端口后点击下一步 八、图示位置输入80,3306后一直点击下一步 九、后面名称为了方便区分,可以写mysql入栈规则这个文字描述。 结果如下: 注意:第一步到第九步的操作你只需要做一次就行了,之后都不用来做的,他会保存到你的电脑里面的。 十、查看本机的ipv4地址,点击被连接的电脑的dos,输入ipconfig回车。 十一、然后下面就是可以让别人电脑来登录了 注意:被连接的电脑每次重启ipv4都是会变的(一般会变,但是也可能不变,你重启后就去查看一下你ipv4地址,然后让别人登入就行了),所以你电脑重启之后别人要登入你MySQL,就需要输入你电脑重启后的ipv4地址才能登录了。不用每天都给别人赋予一个登录的权限的,只要设置一次权限就行了。 十二、查看可以访问你数据库的账号有哪些 输入下面sql语句可以查看那些用户可以登录你的数据库,host表示哪个主机可以访问你的数据库。%表示同网络下的全部主机都可以访问。 USE mysql; SELECT HOST,USER,PASSWORD FROM USER;#查看可以访问本数据库的账号和密码,密码加密了,所以这里看起来是这样的。 UPDATE USER SET HOST="10.69.0.251" WHERE USER="root" AND HOST="10.69.0.244";#可以把某个账号的信息修改了,这样修改是让那个账号可以让ipv4是10.69.0.251的主机都可以使用。 CREATE USER 'zhangfei'@'10.69.239' IDENTIFIED BY 'lsl123';#创建账号。格式:create user '用户名'@'主机名' identified by '密码'; GRANT ALL ON *.* TO zhangfei@"

烧脑巨作,Spring Boot请求处理(常用参数注解使用)

请求处理-SpringBoot常用参数注解使用 注解: @PathVariable 路径变量 @RequestHeader 获取请求头 @RequestParam 获取请求参数(指问号后的参数,url?a=1&b=2) @CookieValue 获取Cookie值 @RequestAttribute 获取request域属性 @RequestBody 获取请求体[POST] @MatrixVariable 矩阵变量 @ModelAttribute 1、@PathVariable注解 该注解主要是用于rest风格的搭配使用,在请求路径中不再以k : v的形式给出请求参数与值;而是直接给定一个值。如果方法参数是一个Map<String, String>将会包含路径中所有的变量与值。 访问:浏览器输入路径变量即可,以下是rest风格的get请求的展示,直接在地址栏发起请求就是一个get请求 获取所有访问路径上的请求参数:localhost:8080/ car/{id}/owner/{username}?age=19&inters= 2、@RequestHeader注解 该注解主要用于获取请求头header中的数据,客户端请求之后可以拿到一些头部携带的参数。支持传统的SpringMVC,也支持WebFlux响应式。如果方法参数是一个Map<String, String>将会包含所有的请求头与值 @GetMapping("user/RequestHeader") public Map<String,Object> getUser3(@RequestHeader("Accept") String Accept, @RequestHeader Map<String,String> header){ Map<String,Object> map=new HashMap<>(); map.put("Accept",Accept); map.put("header",header); return map; } 复制代码 测试: 3、@RequestParam注解 主要用于获取请求参数名称,设置参数是否可有可无以及默认值。 @RequestParam注解详解地址:blog.csdn.net/weixin_4380… 4、@CookieValue注解 主要用于获取Cookie值 5、@RequestAttribute注解 主要用在请求转发时,如果页面无法直接跳转(如WEB-INF下的success页面)可以使用转发的手段。当进行转发时可以在请求中携带上请求的参数,转发会携带上一次请求的参数(一次完整的请求包括转发) 由于是同一次请求,因此也可以直接拿到原生的HttpServletRequest,然后从这里面拿参数和属性也都是可以的【获取request域属性】。 下面就体现了一种转发的思想 结果 6、@RequestBody注解 主要获取表单或者ajax提交的内容,将表单中提交的参数与值获取全部获取出来。即获取请求体【所以请求必须是post请求--@PostMapping】,一般情况下都会使用@RequestBody注解将参数映射到pojo类的能力,但是要保证前后传入的参数名是一样的 7、@MatrixVariable与UrlPathHelper 7.1、基本简介 上述是最常见的三种请求方式;而矩阵变量请求是今天的主角一种新的请求风格,严格来说矩阵变量的请求需要用到rest风格但是又不同于rest. 面试官:页面开发当中把cookie禁用了,session里面的内容怎么使用(找到)??? 正常使用cookie的情况:session.set(a,b)→jsessionid→cookie→每次发请求携带该值 每一个用户都有一个不同的sessionid,我们称之为jsessionid,jsessionid会被保存在cookie里面,我们用户在发送请求的时候都会携带cookie。因此禁用了cookie就不能获取里面保存的对象。 解决禁用cookie的情况:假设访问路径/abc。我们可以用矩阵变量的形式携带jsessionid值:/abc;jsessionid=xxx。上面的过程就是url重写的过程,相当于把cookie的值使用矩阵变量的方式进行传递。 7.2、MatrixVariable注解 由上面源码知道首先可以知道这个注解是一个修饰在参数上的注解,并且可以在运行时被JVM虚拟机加载到。 value 和 name属性是两个相同的属性,用于绑定获取到请求的参数。

CentOS7不关闭Selinux修改ssh端口号

一、防火墙配置及端口号添加 添加端口号命令 firewall-cmd --permanent --add-port=端口号/tcp 删除端口号命令 firewall-cmd --permanent --remove-port=端口号/tcp 查看开放端口 firewall-cmd --list-ports 查看防火墙状态 systemctl status firewalld 关闭防火墙 systemctl stop firewalld 禁止开机启动 systemctl disable firewalld 打开防火墙 systemctl start firewalld 开机启动 systemctl enable firewalld 二、修改ssh端口 vi /etc/ssh/sshd_config 去掉Port前的#号,修改端口号 三、SELinux设置 查看selinux状态 sestatus 设置端口 semanage port -a -t ssh_port_t -p tcp 端口号 删除端口 semanage port -d -t ssh_port_t -p tcp 端口号 查看端口 semanage port -l | grep ssh 默认的22端口号是无法删除的,如果提示semanage没安装,可以执行下面的命令安装 yum -y install policycoreutils-python 四、重启SSH服务和防火墙 systemctl restart sshd systemctl restart firewalld.

vue3 使用vue-i18njie解决切换语言不更新问题

场景:我这里做的不是点击按钮切换语言,是从地址栏里取不同的语言时需要更新数据 问题:地址栏语言的传参变换后,页面的展示的数据还是翻译的上一个语言的数据,需要再次刷新才正确 解决:proxy.$i18n.locale = 当前语言; 具体使用如下: 使用版本: package.json文件 "vue": "^3.2.45", "vue-i18n": "^9.2.2", 1、安装: npm install vue-i18n@next 这样装的最新版的才能在vue3.0使用 2、使用: main.js文件 import { createApp } from "vue"; import App from "./App.vue"; ... import i18n from "./i18n"; const app = createApp(App); app.use(i18n); ... app.mount("#app"); 建文件 i18n/index.js文件 import { createI18n } from "vue-i18n"; import ZH from "./zh.js"; import EN from "./en.js"; import ES from "./es.js"; import PT from "./pt.js"; const messages = { zh: { .

VS2022找不到 .NETFramework,Version=v4.0 的引用程序集

VS2022打开项目之后提示:找不到 .NETFramework,Version=v4.0 的引用程序集。要解决此问题,请为此框架版本安装开发人员工具包(SDK/目标包)或者重新定向应用程序。 使用 vs2022打开带有.net4.0的项目会报错 严重性 代码 说明 项目 文件 行 列 禁止显示状态 错误 MSB3644 找不到 .NETFramework,Version=v4.0 的引用程序集。要解决此问题,请为此框架版本安装开发人员工具包(SDK/目标包)或者重新定向应用程序。可在 https://aka.ms/msbuild/developerpacks 处下载 .NET Framework 开发人员工具包 Fleck D:\VSIDE_2022\MSBuild\Current\Bin\amd64\Microsoft.Common.CurrentVersion.targets 1217 5 两种方式解决 手动下载 直接到nuget上下载对应版本 链接:https://www.nuget.org/packages/Microsoft.NETFramework.ReferenceAssemblies/ 打开对应版的页面之后直接下载即可。 更换vs版本 更新了,VS2022不在支持.net4.x之前的了,要使用vs2019之前的版本。 解释

windows ffmpeg mysys2 编译

安装 mysys2 (msys2-x86_64-20230127.exe 我用的是这个版本)安装好后运行 pacman -S git pacman -S make pacman -S mingw-w64-i686-gcc pacman -S mingw-w64-i686-yasm pacman -S mingw-w64-i686-nasm pacman -S mingw-w64-i686-pkg-config pacman -S mingw-w64-i686-diffutils 运行: git clone https://git.videolan.org/git/x264.git cd x264 ./configure --enable-strip --enable-static --host=i686-w64-mingw32- --prefix=/usr/local make -j8 && make install cd .. 下载 # lame 3.98.4 版本,3100版本编译会有错误 # download https://sourceforge.net/projects/lame/files/lame/ cd lame ./configure --host=i686-w64-mingw32 --enable-static=yes --enable-shared=no --prefix=/usr/local make -j8 && make install cd - git clone -b ffplayer https://github.

解决win10无法安装.Net framework3.5的问题

记录解决win10无法安装.Net framework3.5的问题,防止以后自己忘了 电脑安装.Net framework3.5总是弹出,然后就一直安装失败,网上找的方法几乎都无法解决 方法一 控制面板->程序->启用或关闭windows功能->勾选".NET Framework3.5(包括.NET2.0和3.0)"选项,点击确定,然后安装失败了 方法二 win+R输入services.msc打开服务,查看Windows Update是否启动,如果没启动,就将它启动。然后依旧失败。 方法三 找一个win10镜像,目前最有效的方法 1.下载 microsoft_netfx3.cab,链接: https://pan.baidu.com/s/11U3TQt6lS0n5W7K58Wl-Xg?pwd=zzq0 ,提取码:zzq0 2、把microsoft_netfx3.cab 放到任意文件,解压到 microsoft_netfx3 文件夹;(一定要解压,我就是没解压,一直以为不成功,绕了一大圈才弄好) 3、进入cmd(管理员模式); 4、dism.exe /online /add-package /packagepath:文件存放的路径 5、如图所示,系统会自动更新该功能,进度100%即可。 参考文章:https://zhuanlan.zhihu.com/p/376533953

【Java循环练习 - 韩顺平】

1. 镂空金字塔 public class Test04 { public static void main(String[] args) { /* 思路: 1. 打印矩形 2. 打印一半矩形 3. 打印金字塔 4. 镂空 */ // 设置层数 int level = 10; for ( int i = 0; i < level; i++ ) { // 控制每层打印空格的数量 0-4 1-3 2-2 3-1 4-0 for ( int j = 0; j < level - i - 1; j++ ) { System.out.print(" "); } // 控制每层打印*的数量 for ( int j = 0; j < 2 * i + 1; j++ ) { // 如果是最后一行,直接打印*号 if ( i == level - 1 ) { System.

snprintf函数的用法详解

c语言的snprintf函数的用法详解 snprintf()函数是一种格式化函数,用于将格式化的字符串存储到一个字符数组中,并且有一个参数用来限制输出的最大字符数。 语法: int snprintf ( char * s, size_t n, const char * format, … ); 参数: s:指向要存储字符串(由format参数格式化)的字符数组。 n:指定存储字符串的最大字符数(不包括NULL结尾)。 format:是格式字符串,用于格式化输出字符串。 返回值: 该函数返回实际写入的字符数(不包括NULL结尾)。 snprintf()函数的最大特点是它可以防止由于格式化字符串太长而导致的缓冲区溢出,它可以自动截断字符串,以确保不会超出缓冲区限制。 例如,下面的示例使用snprintf()函数将字符串“Hello world”存储到一个大小为10个字符的字符数组中: #include <stdio.h> int main( ) { char str[10]; snprintf(str, 10, "Hello world"); printf("%s\n", str); return 0; } 输出: Hello wor 这里面包含一个’\0’

bat脚本实现替换含有=的字符串

1.需要把a=b替换为a=B,以下为1.txt文件内容: 123456 789 1=2 345=678 a=b 4=5 67890 2.bat替换脚本 @echo off&setlocal enabledelayedexpansion if exist temp.txt del temp.txt for /f "tokens=*" %%a in (1.txt) do ( set var=%%a if "!var!"=="a=b" ( set var=a=B ) echo.!var!>>temp.txt ) move temp.txt 1.txt pause

VUE报错 error:0308010C:digital envelope routines::unsupported

新克隆的项目启动时报错Error: error:0308010C:digital envelope routines::unsupported 前期安装过低版本Node,后期换成了最新版Node,后来大部分项目启动都报这个错误,所以记录一下解决方法 解决方法(简单有效) 在package.json文件里面添加 "serve": "set NODE_OPTIONS=--openssl-legacy-provider & vue-cli-service serve", "build": "set NODE_OPTIONS=--openssl-legacy-provider & vue-cli-service build", 然后重新npm run serve,成功启动 其他解决方法 一、其他文章有说在CMD运行命令 set NODE_OPTIONS=--openssl-legacy-provider 多次实验后还是未能启动,不知道是不是还有其他影响 二、卸载新版本Node安装旧版Node 由于太麻烦本人未去实验,记录一下此方法以防后面会用到

Spring 事务(编程式事务、声明式事务@Transactional、事务隔离级别、事务传播机制)

文章目录 1. 事务的定义2. Spring 中事务的实现2.1 MySQL 中使用事务2.2 Spring 中编程式事务的实现2.3 Spring 中声明式事务2.3.1 声明式事务的实现 @Transactional2.3.2 @Transactional 作用域2.3.3@Transactional 参数设置2.3.4 @Transactional 异常情况2.3.5 @Transactional 工作原理 3. 事务隔离级别3.1 事务特性3.2 Spring 中设置事务隔离级别 4. Spring 事务传播机制4.1 事务传播机制是什么4.2 为什么需要事务传播机制4.3 事务传播机制有哪些4.4 Spring 事务传播机制使用4.4.1 支持当前事务(REQUIRED 默认)4.4.2 不支持当前事务(REQUIRES_NEW)4.4.3 不支持当前事务(NOT_SUPPORTED)4.4.4 NESTED 嵌套事务4.4.5 嵌套事务和加入事务的区别 本篇重点总结: 在 Spring 项目中使用事务,有两种方式:编程式手动操作和声明式自动提交,声明式自动提交使用最多,只需要在方法上添加注解 @Transactional设置事务的隔离级别 @Transactional(isolation = Isolation.SERIALIZABLE),Spring 中的事务隔离级别有5种设置事务的传播机制 @Transactional(propagation = Propagation.REQUIRED),Spring 中的事务传播级别有 7 种 1. 事务的定义 事务定义:将一组操作封装成一个执行单元(封装到一起),要么全部成功,要么全部失败 那么为什么要用事务呢 比如两个银行账户之间的转账操作: 第一步操作:A 账户 -100 元第二步操作:B 账户 +100 元 如果没有事务。第一步执行成功了,第二步执行失败了,那么 A 账号就丢失了 100 元,而如果使用事务就可以解决这个问题,让这一组操作要么一起成功,要么一起失败

MySQL数据库的一些常见问题

博主介绍: – 我是了 凡 微信公众号【了凡银河系】期待你的关注。未来大家一起加油啊~ 前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站: https://www.cbedai.net/lf 下面记录一些关于MySQL一些常见的问题 文章目录 前言1. 数据库三大范式2. MySQL存储引擎Mylsam和InnoDB有哪些区别3. 什么是索引?都有哪些类型?有什么优点和缺点?4. B树和B+树的区别,聚簇索引和非聚簇索引的区别。什么是回表,怎么减少回表?5. 为什么会有索引失效的情况,索引调优有哪些方法?6. MySQL中的锁有哪些?什么是next-key lock?7. 乐观锁与悲观锁8. MySQL的事务隔离级别有哪些?MVCC是什么?9. 脏读,幻读,不可重复读是什么?是怎么解决的。10. 读已提交、可重复读、串行化分别是如何实现的?11. MySQL删除数据时的一些注意事项。12. MySQL使用时的一些经验和优化 1. 数据库三大范式 第一范式(1NF):数据库表中的所有列都是不可分割的基本数据项,即数据库表的每一列都是原子性的,不可再分解。(确保每列原子性,不可拆分)第二范式(2NF):在满足第一范式的基础上,非主键列必须完全依赖于主键,而不能只依赖于主键的一部分。(确保表种的每列都和主键相关)第三范式(3NF):在满足第二范式的基础上,非主键列之间不能存在传递依赖关系,即不能存在非主键列对其他非主键列的依赖。(确保每列都和主键列直接相关,而不是间接相关) 总结:这三个范式的目的是为了消除数据冗余、提高数据的完整性和一致性,保证数据的正确性和稳定性。 2. MySQL存储引擎Mylsam和InnoDB有哪些区别 事务支持:InnoDB支持事务,而MyISAM不支持事务。锁级别:MyISAM在执行SELECT语句时,会对需要读取的数据表进行整表锁定,而InnoDB支持行级锁和表级锁。ACID属性:InnoDB是一个ACID兼容的存储引擎,它支持原子性、一致性、隔离性和持久性,而MyISAM则只支持持久性。并发性:由于InnoDB支持行级锁,因此并发性能更好,同时也避免了表级锁带来的并发性问题。外键支持:InnoDB支持外键,而MyISAM不支持。数据缓存:InnoDB支持数据和索引的缓存,而MyISAM只支持索引的缓存。适用场景:MyISAM适合于读取密集型的应用,例如数据仓库,而InnoDB适合于事务处理的应用,例如电子商务和银行系统。 总结:MyISAM和InnoDB各有优缺点,在实际应用中需要根据具体需求来选择使用哪种存储引擎 3. 什么是索引?都有哪些类型?有什么优点和缺点? 索引是一种用于提高数据库查询性能的数据结构。它类似于书中的目录,能够加速查找数据的速度,使得数据库查询更加高效。 索引的类型有很多种,主要包括以下几种: B-Tree索引:是最常用的一种索引类型,它是一种基于B-Tree数据结构的索引,用于快速查找具有某些值的行。B-Tree索引支持精确查找和范围查找,并且在查询较小的数据集时效果最佳。哈希索引:是一种基于哈希表的索引,用于快速查找具有某些值的行。哈希索引仅支持精确查找,不能进行范围查找,但是在查询大数据集时,哈希索引比B-Tree索引更快。全文索引:是一种用于在文本数据中查找特定单词或短语的索引,支持模糊查询和关键词查询。空间索引:是一种用于查找具有特定地理位置的行的索引,支持地理位置查询和空间关系查询。 索引的优点包括: 提高查询性能:索引可以加速数据的查找和读取,使得查询更加高效。减少数据读取量:索引可以避免全表扫描,减少数据的读取量,降低数据库的负载。优化数据库结构:索引可以优化数据库表的结构,提高数据库的整体性能。 索引的缺点包括: 增加存储空间:索引需要占用存储空间,如果索引过多或过长,会占用大量的存储空间。降低更新性能:对于经常进行插入、删除和更新操作的表,索引的维护会降低更新操作的性能。可能导致查询性能下降:如果索引选择不当或者过多,会导致查询性能下降,甚至出现死锁等问题。因此,在创建索引时需要根据实际情况进行优化和选择。 4. B树和B+树的区别,聚簇索引和非聚簇索引的区别。什么是回表,怎么减少回表? B树和B+树都是多叉树的一种,它们都可以用于实现数据库中的索引。B树的节点中既包含了索引键,也包含了指向数据的指针;而B+树的节点只包含索引键,数据则全部存放在叶子节点中。具体区别如下: B树中的每个节点都可以存放数据,而B+树的数据只存储在叶子节点中,而非中间节点。B+树中叶子节点之间有一个链表相连,因此可以很方便地进行范围查找和遍历。B+树相较于B树更加适合在磁盘等外存储介质上使用,因为B+树的内部节点存放的只是关键字,而不存储数据,可以减少I/O操作。 聚簇索引和非聚簇索引的区别: 聚簇索引是将数据存储与索引放在一起的索引方式,也就是说,聚簇索引的叶子节点就是数据页,数据页的顺序与索引页的顺序相同。非聚簇索引则是将数据和索引分别存储在不同的文件中。 区别如下: 聚簇索引在查询时可以直接找到数据行,速度较快,而非聚簇索引需要进行两次查找,先查找索引,再通过索引找到数据行,速度相对较慢。聚簇索引只能有一个,因为数据与索引存储在一起,而非聚簇索引可以有多个。聚簇索引只能建立在主键或唯一约束上,而非聚簇索引可以建立在任何列上 回表和如何减少回表: 在数据库查询时,如果需要查询的列不在索引中,或者需要查询的列在非聚簇索引中,但是需要通过非聚簇索引再次查找数据行,则称为回表。回表会增加额外的I/O操作,降低查询效率。 减少回表的方法如下: 尽可能地使用聚簇索引:聚簇索引可以减少回表的次数,提高查询效率。 考虑使用覆盖索引:覆盖索引是指包含查询所需的所有数据的索引,因此查询时不需要回表。尽可能地减少查询的列:只查询需要的列,不查询不需要的列,可以减少回表的次数。优化SQL语句:编写高效的SQL语句,避免使用 5. 为什么会有索引失效的情况,索引调优有哪些方法? 索引失效通常是由于查询语句中的条件与索引不匹配而导致的。以下是一些常见的导致索引失效的情况: 不使用索引列:如果查询语句没有使用索引列,那么索引就无法发挥作用,查询将会全表扫描,效率低下。在索引列上使用函数:如果查询语句在索引列上使用了函数,如使用了LOWER()函数将查询条件转换为小写,那么索引就无法被使用,查询将会全表扫描。对索引列进行运算:如果查询语句对索引列进行了运算,如使用了+运算符将两个列相加作为查询条件,那么索引也无法被使用。条件使用OR:如果查询语句中的条件使用了OR运算符连接多个条件,而这些条件只有部分可以使用索引,那么索引也无法被使用。 为了避免索引失效,可以考虑以下索引调优的方法: 确保查询语句使用索引列:查询语句应该使用索引列作为条件,这样索引才能被使用。避免在索引列上使用函数或运算符:在查询语句中避免在索引列上使用函数或运算符,如果必须使用函数或运算符,可以考虑在查询之前对数据进行预处理,将结果存储到新的列中,然后使用这些新的列进行查询。考虑使用复合索引:如果查询语句中有多个条件,可以考虑使用复合索引,将多个条件都包含在一个索引中。使用索引覆盖查询:如果查询语句只需要返回索引列的值,可以使用索引覆盖查询,这样可以避免对表进行全表扫描。使用合适的数据类型:在创建表时,应该使用合适的数据类型,这样可以提高索引效率,减少索引失效的概率。 总结:索引调优是一个复杂的过程,需要根据具体情况进行优化,以提高数据库的性能和效率。 6. MySQL中的锁有哪些?什么是next-key lock? MySQL中的锁主要分为共享锁和排他锁两种。 共享锁(Shared Lock):共享锁又称为读锁,多个事务可以同时持有共享锁,并发读取同一份数据,不会互相影响,但是不能进行写操作。当一个事务持有共享锁时,其他事务只能获取共享锁,而不能获取排他锁。排他锁(Exclusive Lock):排他锁又称为写锁,只能被一个事务持有,当一个事务持有排他锁时,其他事务无法获取共享锁或排他锁,只能等待该事务释放锁。排他锁既可以进行读操作,也可以进行写操作。 在MySQL中,使用next-key lock来实现范围查询时的加锁机制,即行锁和间隙锁的组合,也称为Next-Key锁。它是在InnoDB存储引擎中实现的,用于避免幻读问题。

adb安装与基础命令

一:ADB概念 adb:安卓调式桥,用于完成电脑和手机之间的通信控制xcode:来完成对于ios设备的操控。前提是有个mac电脑 二:ADB安装 1.下载 URL:https://www.androiddevtools.cn/ 2.配置本地环境 三:将设备和电脑连接起来 点击版本号,打开开发者模式开发者模式,打开usb调试以夜神为例:连接模拟器设备 adb connect 127.0.0.1:62001连接完成后,用 adb devices 命令 查看当前连接的设备,注意后面的 device 表示连接成功 四:常用的adb命令 1.进入安卓系统adb shell adb shell:用于进入安卓系统。 基本的linux命令都可以直接进行使用 2.adb操作命令 1.apk的安装与卸载 adb install [apk包路径]: 将apk安装包安安装到手机上 例:遇到的问题:当前apk版本不支持当前adb所连接的手机,原因系统版本太低解决方法:换相对应的X86版本 adb uninstall [安卓系统中应用的包名(package)]:卸载apk 例: apk包查看: adb shell pm list package:列出手机中安装的所有应用的package名字 adb shell pm list package -3:列出用户自己安装的应用package名字(第三方应用) 2.文件的上传与下载 下载上传文件: adb pull 下载文件路径 存放电脑路径:将文件从手机取下来 adb push 电脑文件上传路径 上传到手机路径:将文件从电脑上传到手机 3.页面的管理 页面管理(am activity manager)操作:手机应用中的每个页面就是一个 activity。 启动应用,需要通过应用的启动activity来完成调用。获取应用的activity: adb shell dumpsys activity|findstr “mFocuse”使用这个命令的时候,打开你的被测应用。 实际上获取的是当前应用打开的activity名,有可能并不是启动用的activity 使用sdk中的aapt工具来进行apk包的解析 获取到的一定是启动用的activity。 adb shell monkey -p [被测包名] -v -v -v 1 对activity操控(启动应用):adb shell am start -W -S(先关掉应用在打开) [包名]/[启动activity名]

使用cURL携带用户名和密码

问题描述 在访问一个需要用户名/密码的URL时: curl http://example.com 会收到需要认证的错误 解决方案 在命令中包含用户名密码,但是密码将在bash历史记录中显示: curl -u username:password http://example.com # 或者 curl http://username:password@example.com 使用-u标志来包含用户名,并且curl将提示输入密码,密码将不会显示在屏幕上或者历史中: curl -u username http://example.com

免费图床网站推荐

免费图床网站推荐 聚合图床-推荐使用 官网地址:https://www.superbed.cn 简介:将图片分发到多处备份,借助其本身的CDN加速功能,节省服务器流量,并且不用担心图片被删除,即便其中某几个图床上的图片被删除了,还有其他备份,保证万无一失,支持匿名和注册管理 图片上传限制:无 载涂图床 官网地址:https://mcecy.com/ 简介:评论区小伙伴推荐的 ImgURL 官网地址:https://imgurl.org 开源代码:https://github.com/helloxz/imgurl 简介:始于2017年底,由个人开发的图床,代码开源支持自建 限制:游客限制每日上传10张,单张图片不能超过5M,上传的图片将公开显示,经测试会删除图片 示例(供测试):https://i.bmp.ovh/imgs/2019/03/ SM.MS 官网地址:https://sm.ms 特点:永久存储免注册,图片链接支持https,可以删除上传的图片,提供多种图片链接格式,建立于2015年,目前免费用户无法使用香港节点因此速度比较慢 图片上传限制:每个图片最大5M,每次最多上传10张 示例(供测试):https://i.loli.net/2018/04/03/5ac35735ca68d.png 路过图床 官网地址:https://imgchr.com 简介:支持免注册上传图片,永久存储,支持HTTPS加密访问和调用图片,提供多种图片链接格式,成立于2011年 限制:最大10M 公益图床 官网地址:http://sbimg.cn 长期保存需要注册使用,这个图床服务器在国内应该还用了cdn,总之速度非常快 uploader 官网地址:http://upload.otar.im 极简图床 官网地址:https://jiantuku.com/#/ 自己搭建图床 使用工具如下: 1.创建码云仓库 1.2.设置令牌 1.3设置私人令牌 然后保存生成的令牌!!!一定要保存!!只会出现一次!! 2.安装配置PicGo 首先我们下载PicGo:https://github.com/Molunerfinn/PicGo 由于Github下载很慢,这里直接放上2.3.0版本的安装包 链接:https://pan.baidu.com/s/1pMX-B3SaEvqKw1GUKPoORA 提取码:sa76 2.2 配置地址 repo: Gitee用户名/仓库名;branch: 分支名:默认master即可token: Gitee私人令牌path: 用于仓库下存储的目录customPath和customUrl可以不用填 2.3 server如下设置 参考文章 https://zhuanlan.zhihu.com/p/35270383

Pyinstaller使用时报错

Pyinstaller生成的exe后启动无反应,用cmd运行查看报错为can't find moudle 'encodings' 经查找资料为pyinstller启动自建的python环境后无法加载python的基础依赖标准库,在build和dist文件夹中均有一个文件"base_library.zip",因为内网加密的原因,在生成后发现该压缩包为损坏状态,故exe文件执行报错,在未加密的电脑实验后验证结果没有问题。(实验环境均为Pycharm以及其自带的虚拟环境)。

谷歌浏览器(chrome)允许跨域/允许https网站中发送http请求

直接上方法了 方法一(针对所有访问网站) 第一步:对谷歌浏览器图标点击鼠标右键,打开属性面板 第二步:在下图位置,添加下列代码 原来启动浏览器的地址:C:\Users\xxxxx\AppData\Local\Google\Chrome\Application\chrome.exe 增加的代码(注意开头是有个空格的,要把两部分用空格隔开的): --args --disable-web-security --user-data-dir="d:/chromecache" --allow-running-insecure-content C:\Users\xxxxx\AppData\Local\Google\Chrome\Application\chrome.exe --args --disable-web-security --user-data-dir="d:/chromecache" --allow-running-insecure-content 第三步:应用以后打开就好了 方法二(针对单一网站) 第一步:点击浏览器地址左边的锁的图标 2. 点击后,在弹窗里面选择网站设置 3. 打开网站设置后,将不安全内容选项改成允许即可。 注意:这只是针对单独的网站设置的,如果需要多网站,需要对每个网站单独设置。 方法二: 在html的header中加入 (未验证) <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">

python3安装及pip3 报ERROR: No matching distribution found for

python3 pip Install Error: No matching distribution found for 安装openssl wget https://www.openssl.org/source/openssl-1.1.1a.tar.gz tar -zxvf openssl-1.1.1a.tar.gz cd openssl-1.1.1a ./config --prefix=/usr/local/openssl-1.1.1 --openssldir=/usr/local/openssl-1.1.1 make && make install # 方法一,声明临时变量,怕影响线上服务推荐使用该方法 # 包括后续引用库文件都要提前声明 export LD_LIBRARY_PATH=/usr/local/openssl-1.1.1/lib:$LD_LIBRARY_PATH # 方法二,永久声明变量 echo "/usr/local/openssl-1.1.1/lib" >> /etc/ld.so.conf.d/openssl-1.1.1-x86_64.conf ldconfig 安装python3 --下载python wget https://www.python.org/ftp/python/3.7.11/Python-3.7.11.tar.xz --解压缩、编译和安装 tar xvf Python-3.7.11.tar.xz cd Python-3.7.11 ./configure --prefix=/usr/local/python-3.7.11 --enable-optimizations --with-openssl=/usr/local/openssl-1.1.1 make && make install --做个软连接到当前用户的bin目录 ln -s /usr/local/python-3.7.11 /usr/local/python3 ln -s /usr/local/python-3.7.11/bin/python3.7 /usr/bin/python3 ln -s /usr/local/python-3.7.11/bin/pip3 /usr/bin/pip3 可能会报错: