如何用java开发网站?

Java 可以用于开发 Web 应用程序,而常用的方式之一是使用 Java 的 Web 开发框架。以下是使用 Java 开发网站的一般步骤: 1、学习 Java 基础: 首先,确保你对 Java 编程语言有基本的了解。熟悉 Java 的语法、面向对象的概念、异常处理等是开发 Web 应用程序的基础。 2、学习 HTML、CSS 和 JavaScript: Web 开发涉及到前端和后端两个方面。前端部分通常包括 HTML(网页结构)、CSS(样式)、JavaScript(交互),所以你需要对这些技术有一定的了解。 3、选择 Web 开发框架: Java 有很多优秀的 Web 开发框架,其中一些常见的包括 Spring、Servlet、JSP、Struts、JSF 等。Spring 是最流行的框架之一,提供了全面的功能,包括依赖注入、面向切面编程、模型-视图-控制器(MVC)等。 4、设置开发环境: 安装和配置 Java 开发工具包(JDK),选择一个集成开发环境(IDE)如 Eclipse、IntelliJ IDEA 或 NetBeans。此外,你还需要配置 Web 服务器(如 Apache Tomcat)来运行你的 Java Web 应用。 5、创建项目: 使用选定的框架,创建一个新的 Java Web 项目。在项目中,你将定义处理 Web 请求和响应的控制器、定义数据库模型、编写业务逻辑等。 6、数据库集成: 大多数 Web 应用程序需要与数据库进行交互。使用 Java 的数据库访问技术(如 JDBC)或集成的框架(如 Spring Data、Hibernate)来连接和操作数据库。 7、开发前端:

fastadmin添加活动二维码图片,扫码可以直接跳转到该活动

一,在controll重写add方法 /** * 添加 */ public function add() { if ($this->request->isPost()) { $params = $this->request->post("row/a"); if ($params) { $params = $this->preExcludeFields($params); if ($this->dataLimit && $this->dataLimitFieldAutoFill) { $params[$this->dataLimitField] = $this->auth->id; } $result = false; Db::startTrans(); try { //是否采用模型验证 if ($this->modelValidate) { $name = str_replace("\\model\\", "\\validate\\", get_class($this->model)); $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate; $this->model->validateFailException(true)->validate($validate); } $result = $this->model->allowField(true)->save($params); Db::commit(); //添加方法 if($result){ //通过save后获取自增的ID,传进获取二维码方法,生成跳转指定小程序页面的二维码,保存到数据表中 $this->getEwm($this->model->getData('id')); } } catch (ValidateException $e) { Db::rollback(); $this->error($e->getMessage()); } catch (PDOException $e) { Db::rollback(); $this->error($e->getMessage()); } catch (Exception $e) { Db::rollback(); $this->error($e->getMessage()); } if ($result !

如何在redis中存储ndarray

在Redis中存储NumPy数组(ndarray)通常需要将数组转换为二进制格式,然后将其存储为字符串。以下是使用Python和Redis-py库的一个简单示例: 首先,确保你已经安装了Redis-py库: pip install redis 然后,你可以使用以下代码将NumPy数组存储到Redis中: import redis import numpy as np import pickle # 连接到本地Redis服务器,端口默认是6379 redis_client = redis.StrictRedis(host='localhost', port=6379, db=0) # 创建一个示例的NumPy数组 arr = np.array([[1, 2, 3], [4, 5, 6]]) # 将NumPy数组转换为二进制字符串 arr_binary = pickle.dumps(arr) # 存储二进制字符串到Redis redis_client.set('numpy_array_key', arr_binary) # 从Redis中检索数据并转换回NumPy数组 stored_data = redis_client.get('numpy_array_key') if stored_data: retrieved_arr = pickle.loads(stored_data) print("Retrieved NumPy Array:") print(retrieved_arr) else: print("Key not found in Redis.") 在这个例子中,pickle模块被用来将NumPy数组转换为二进制字符串,然后使用Redis-py库的set方法将其存储在Redis中。在检索时,使用get方法获取二进制字符串,并使用pickle.loads将其转换回NumPy数组。

doris导入Excel的xlsx格式数据

1.把xlsx格式另存为csv格式 2.上传到Linux 3.查看字符集 file -i yourfile.csv 结果: a.csv: text/plain; charset=iso-8859-1 4.转换为utf-8 iconv -f iso-8859-1 -t utf-8 a.csv > b.csv 5.执行命令 curl --location-trusted -u root:888 -T /root/doris/b.csv -H "column_separator:," -H "label:alex-129" http://10.66.66.66:8523/api/you_database/you_table/_stream_load 结果 { "TxnId": 58, "Label": "alex-129", "TwoPhaseCommit": "false", "Status": "Success", "Message": "OK", "NumberTotalRows": 957727, "NumberLoadedRows": 957727, "NumberFilteredRows": 0, "NumberUnselectedRows": 0, "LoadBytes": 144980651, "LoadTimeMs": 15666, "BeginTxnTimeMs": 0, "StreamLoadPutTimeMs": 2, "ReadDataTimeMs": 352, "WriteDataTimeMs": 15620, "CommitAndPublishTimeMs": 42 }

SpringBoot统一功能处理,拦截器,统一数据格式,捕捉异常

目录 拦截器:是Spring框架提供的核心功能之一,主要用来拦截用户的请求,在指定方法前后,根据业务需要执行预先设定的代码: 自定义拦截器 统一数据格式,要包含状态码,错误信息​编辑 出现针对String类型的错误​​​​​​​ 为什么要统一 统一功能来实现捕捉到异常。​编辑 @ControllerAdvice源码分析 数据结构面试:HashMap,ConcurrentHashMap,ThreadLocal要看(建议看源码) 网络:TCP,UDP,HTTP 并发编程:线程创建方式,线程的状态,锁,synchronized,volatile 数据库 基本操作,关键字, JVM-内存结构,GC Linux 引入拦截器的原因。 拦截器:是Spring框架提供的核心功能之一,主要用来拦截用户的请求,在指定方法前后,根据业务需要执行预先设定的代码: (指定在哪些方法前后执行) JDK17把之前Java的包都换为Jakarta。 指定方法:——指我们登录验证的某些方法(比如图书的增删改查),怎样可以不用动太多代码,实现这个功能 预先设定的代码:对用户是否登录进行验证 拦截器的实现分为两步:(作用维度以url为维度) 1.定义一个拦截器 2.把拦截器注册到项目中 自定义拦截器:实现HandlerInterceptor接口,并重写所有方法 拦截器的定义 自定义拦截器 /* 一级路径 能匹配/user,/book,/login,不能匹配/user/login /** 任意级路径 能匹配 /user,/user/login,/book /book/* /book下的一级路径 能匹配/book/addBook,不能匹配/book/addBook /book/** /book下的任意级路径 能匹配/book,/book/addBook,/book/addBook/2...。 正常工作方式 用户调用->(拦截器)->控制器层(Controller)->调用服务层(Service)->数据持久层(Mapper)->数据库 1.添加拦截器后, 执⾏Controller的⽅法之前, 请求会先被拦截器拦截住. 执⾏ preHandle() ⽅法, 这个⽅法需要返回⼀个布尔类型的值. 如果返回true, 就表⽰放⾏本次操作, 继续访问controller中的 ⽅法. 如果返回false,则不会放⾏(controller中的⽅法也不会执⾏). 2. controller当中的⽅法执⾏完毕后,再回过来执⾏ postHandle() 这个⽅法以及 afterCompletion() ⽅法,执⾏完毕之后,最终给浏览器响应数据 DispatcherServlet(Dispatcher调度器,servlet生命周期)​​​​​​​​​​​​​​ 源码环节 适配器模式和门面模式区别 1.适配器模式:是适配两者之间的差异(为了补救设计上的缺陷,应用这种模式也是无心之举),门面模式是统合了底层系统(我认为一个像是七巧板把两个不同的连接起来,门面模式就像是给他装了一个套,它里面不变,只是说可以调用他们两个)我们通过外面的套来调用里面。 统一数据格式,要包含状态码,错误信息 supports⽅法: 判断是否要执⾏beforeBodyWrite⽅法. true为执⾏, false不执⾏. 通过该⽅法可以 选择哪些类或哪些⽅法的response要进⾏处理, 其他的不进⾏处理.

Redis:bigkeys内存分析

场景 随着时间流逝,redis内存逐步增大,需要对redis内存进行清理,发现问题,解决问题。 方案 bigkeys 命令用于识别在 Redis 数据库中占用最多内存的键。 对服务有一定开销,在使用系统低峰期操作。 redis-cli -c -h 127.0.0.1 -p 7021 --bigkeys 输出结果 # Scanning the entire keyspace to find biggest keys as well as # average sizes per key type. You can use -i 0.1 to sleep 0.1 sec # per 100 SCAN commands (not usually needed). [00.00%] Biggest string found so far '"xxx22"' with 172 bytes [00.45%] Biggest hash found so far '"xx111"' with 1 fields .

探索密码学的未来:SM1、SM2、SM3、SM4、同态加密、密态计算、隐私计算和安全多方计算

密码算法在现代通信与信息安全中发挥着至关重要的作用,SM1、SM2、SM3、SM4、同态加密、密态计算、隐私计算和安全多方计算等密码算法被广泛应用于各种信息安全领域。本篇博客将会为大家介绍这些密码算法,以及它们在信息安全中的作用和应用。 一、SM1、SM2、SM3、SM4 SM1、SM2、SM3、SM4是中国国家密码管理局发布的四个密码算法标准。SM1是一种对称密码算法,SM2是一种非对称密码算法,SM3是一种哈希函数,SM4是一种分组对称密码算法。 SM1算法采用分组加密模式,将明文分成多个固定长度的数据块,每个数据块分别进行加密操作。SM1的加密过程中包括了置换、代换、线性变换等步骤,从而保证了加密的强度和安全性。 SM2算法是一种基于椭圆曲线密码体制的公钥密码算法,可以用于数字签名、密钥协商、加密和解密等操作。SM2的安全性基于离散对数问题的难度,通过椭圆曲线的运算实现加密和解密操作。 SM3算法是一种哈希函数,用于对任意长度的消息进行摘要操作,可以生成一个固定长度的消息摘要。SM3算法采用了置换、代换、移位、加法等操作,可以保证摘要的强度和唯一性。 SM4算法是一种分组对称密码算法,采用Feistel结构,将明文分成多个数据块,每个数据块分别进行加密操作。SM4算法采用了S盒、置换、线性变换等操作,从而保证了加密的强度和安全性。 二、同态加密 同态加密是一种特殊的加密技术,它可以在不暴露明文的情况下进行加法和乘法运算。同态加密可以用于云计算、安全多方计算等场景中,实现数据的保护和隐私计算。 同态加密可以分为完全同态加密和部分同态加密。完全同态加密可以进行任意次的加法和乘法运算,而部分同态加密只能进行有限次的加法或乘法运算。 同态加密的实现需要满足两个基本要求:保证加密后的密文能够进行运算,且运算后得到的结果是正确的。同态加密技术的实现需要借助数学理论, 具体来说,同态加密算法需要满足以下两个条件: 加密后的密文可以进行加法和乘法运算。 在传统的加密算法中,加密后的密文是无法进行运算的,只能通过解密后再进行计算。但是,在同态加密中,密文是可以进行加法和乘法运算的,这是实现同态计算的基础。 运算后得到的结果是正确的。 在同态加密中,由于密文已经被加密,直接进行加法和乘法运算得到的结果不一定是正确的,需要通过一系列复杂的算法来确保运算结果正确。 实现同态加密技术需要借助多项式环、理想、剩余系等数学理论,如Paillier同态加密算法、Gentry同态加密算法等。 同态加密技术的应用非常广泛,如在云计算中,可以将数据加密后上传到云端,实现数据的保护和隐私计算;在安全多方计算中,可以在不暴露数据的情况下进行数据合并和分析。 三、密态计算 密态计算是一种保护隐私数据的计算技术,它可以在不暴露原始数据的情况下进行数据处理和分析。密态计算可以保证数据的隐私性、安全性和完整性,是一种非常重要的隐私保护技术。 密态计算可以分为两种类型:基于加密的密态计算和基于扰动的密态计算。基于加密的密态计算是指对原始数据进行加密后再进行计算,而基于扰动的密态计算是指对原始数据进行一定的扰动后再进行计算。 密态计算的实现需要满足以下三个基本要求: 隐私保护。密态计算需要保护原始数据的隐私,确保数据不被泄露。 安全性。密态计算需要确保计算的过程是安全的,防止被攻击者利用漏洞进行攻击。 计算正确性。密态计算需要确保计算结果是正确的,保证数据的完整性。 密态计算可以应用于各种领域,如金融、医疗、社交网络等,实现隐私保护和数据处理的需求。 四、隐私计算 隐私计算是一种保护数据隐私的计算技术,它可以在不暴露原始数据的情况下进行数据处理和分析。隐私计算可以保证数据的隐私性、安全性和完整性,是一种非常重要的隐私保护 技术。 隐私计算可以分为基于加密的隐私计算和基于差分隐私的隐私计算。基于加密的隐私计算是指对原始数据进行加密后再进行计算,而基于差分隐私的隐私计算是指对原始数据进行一定的扰动后再进行计算。相比之下,基于差分隐私的隐私计算更加适用于大规模数据的隐私保护。 隐私计算的实现需要满足以下三个基本要求: 隐私保护。隐私计算需要保护原始数据的隐私,确保数据不被泄露。 安全性。隐私计算需要确保计算的过程是安全的,防止被攻击者利用漏洞进行攻击。 计算正确性。隐私计算需要确保计算结果是正确的,保证数据的完整性。 隐私计算可以应用于各种领域,如金融、医疗、社交网络等,实现隐私保护和数据处理的需求。例如,在金融领域,可以通过隐私计算对客户数据进行处理和分析,以便银行机构更好地了解客户需求和行为,提供更好的服务和产品。在医疗领域,可以通过隐私计算对患者数据进行处理和分析,以便医疗机构更好地了解疾病情况和治疗效果,提供更好的医疗服务。在社交网络领域,可以通过隐私计算对用户数据进行处理和分析,以便社交平台更好地了解用户需求和行为,提供更好的用户体验和服务。 五、安全多方计算 安全多方计算是一种在多个参与方之间进行计算的技术,可以在保护数据隐私的前提下,实现数据的共享和处理。安全多方计算可以应用于各种领域,如金融、医疗、社交网络等。 安全多方计算可以分为两种类型:基于密码学的安全多方计算和基于秘密共享的安全多方计算。基于密码学的安全多方计算是指在计算过程中,参与方对数据进行加密和解密,以保护数据隐私;而基于秘密共享的安全多方计算是指在计算过程中,参与方将数据进行分割,各自保存一部分数据,并在计算过程中进行数据合并和分析。 安全多方计算的实现需要满足以下三个基本要求: 隐私保护 安全多方计算需要确保数据隐私得到充分保护,不会被恶意方窃取或泄露。 安全性 安全多方计算需要确保计算的过程是安全的,防止被攻击者利用漏洞进行攻击。 计算正确性 安全多方计算需要确保计算结果是正确的,保证数据的完整性和可靠性。 安全多方计算可以应用于多种领域,例如金融、医疗、社交网络等。在金融领域,安全多方计算可以被用来实现多方合作的金融风险管理、信用评估、客户身份验证等业务。在医疗领域,安全多方计算可以被用来实现多方协作的医学研究、疾病诊断、健康管理等业务。在社交网络领域,安全多方计算可以被用来实现多方协作的社交分析、广告推送、用户画像等业务。 总之,安全多方计算是一种非常重要的计算技术,可以在保护数据隐私的同时,实现数据的共享和处理,为各种应用场景提供强有力的支持。 黑客学习资源推荐 最后给大家分享一份全套的网络安全学习资料,给那些想学习 网络安全的小伙伴们一点帮助! 对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。 😝朋友们如果有需要的话,可以V扫描下方二维码联系领取~ 1️⃣零基础入门 学习路线 对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。 需要详细路线图的,下面获取 路线对应学习视频 同时每个成长路线对应的板块都有配套的视频提供: 2️⃣视频配套工具&国内外网安书籍、文档 工具 ######视频 ######书籍 资源较为敏感,未展示全面,需要的下面获取 ### 3️⃣Python面试集锦 面试资料 简历模板 因篇幅有限,资料较为敏感仅展示部分资料,添加上方即可获取👆 ------ 🙇‍♂️ 本文转自网络,如有侵权,请联系删除 🙇‍♂️ ------

从零开始的网络安全--Windows系统安全

Window系统安全1 一、用户账户基础 1、用户账户概述 用户账户用来记录用户的用户名和口令、隶属的组等信息 每个用户账户包含唯一的登录名和对应的密码不同的用户身份拥有不同的权限 操作系统根据SID识别不同用户 每个用户拥有唯一安全标识符(SID)用户权限通过用户的SID来记录查看命令为:whoami /user 2、本地用户和组控制台 运行 lusrmgr.msc ,直接打开 本地用户和组, 或者右击 开始 => 计算机管理 => 系统工具 => 本地用户和组 3、内置用户 Windows系统默认存在的系统 Administrator:管理员(权限最大)Guest:来宾(权限最小),默认禁用 内置用户可以改名、禁用,但无法删除 二、用户账号操作 1、用户管理操作 创建新用户 右击空白处,选 新用户指定用户名、密码及密码属性 账户属性 用户下次登录时须更改密码(每个员工创建不同帐户) 用户不能更改密码(用于公用帐户) 密码永不过期(默认42天) 帐户已禁用 更改用户属性 常规属性、是否禁用、隶属于 设置密码 选中用户,右击选 设置密码 重命名用户 适用于工作交接场合由管理员将前任员工的账户改名 删除用户 适用于员工离职/账户废止等场合 建议禁用账户而不是删除,若删除后重建同名账户,其SID值会不同 三、组账号基础 1、组账户概述 用来为多个用户批量授权 为一个组授予权限后,所有成员用户自动获得相应权限用户加入一个组,自动获得此组的权限 2、创建新的组账号 打开本地用户和组 => 组 => 右击 => 新建组 => 输入组名 => 创建 3、管理组成员 双击本地组 => 添加 => 输入用户名 => 确定 => 确定

Java安全之SnakeYaml漏洞分析与利用

1. 简介 SnakeYaml是Java中解析yaml的库,而yaml是一种人类可读的数据序列化语言,通常用于编写配置文件等。 yaml基本语法: 大小写敏感使用缩进表示层级关系缩进只允许使用空格#表示注释支持对象、数组、纯量这3种数据结构 示例 yaml对象: key: child-key: value child-key2: value2 yaml数组: companies: - id: 1 name: company1 price: 200W - id: 2 name: company2 price: 500W 意思是 companies 属性是一个数组,每一个数组元素又是由 id、name、price 三个属性构成 详细参考:YAML 入门教程 | 菜鸟教程 SnakeYaml库: SnakeYaml提供了yaml数据和Java对象相互转换的API,即能够对数据进行序列化与反序列化。 Yaml.load():将yaml数据反序列化成一个Java对象Yaml.dump():将Java对象序列化成yaml 2. 示例 环境:JDK1.8_66 Maven导入依赖: <dependency> <groupId>org.yaml</groupId> <artifactId>snakeyaml</artifactId> <version>1.27</version> </dependency> 序列化: Person类: package SnakeYaml; public class Person { private String username; private int age; public Person() {} public Person(String username, int age) { this.

Redis -- hash哈希

马行软地易失蹄,人贪安逸易失志。 目录 关于Redis的hash hash命令 hset hget hexists hdel hkeys hvals hgetall hmget hlen hsetnx hash计数 hincrby hincrbyfloat 小结 关于Redis的hash 几乎所有的主流编程语言都提供了哈希(hash)类型,它们的叫法可能是哈希、字典、关联数组、映射。在 Redis 中,哈希类型是指值本身又是一个键值对结构,形如 key = "key",value = { {field1, value1 }, ..., {fieldN, valueN } },Redis 键值对和哈希类型二者的关系可以用图 2-15 来表示。 redis自身本来就是键值对结构了,自身的键值对就是通过hash的方式来组织的。 到了value这一层,value又可以是很多种类型,其中这节要讲的就是hash类型,同样是hash的形式来表示value。 hash命令 hset 设置 hash 中指定的字段(field)的值(value)。 语法:HSET key field value [field value ...] 返回值:添加的字段的个数。 可以添加多个字段,多个字段之间使用空格间隔。 示例: 将一个key设置为hash,然后添加两个属性域: 想要一个hset设置多个field和value,就可以直接写多个field和value,多个filed和value之间使用空格隔开: hget 既然可以设置hash,那么必然也可以查找hash。获取 hash 中指定字段的值。 语法:hget key filed 时间复杂度:O(1) 返回值:字段对应的值或者 nil。 示例: 设置一个key的一个域名为field,也可以叫属性名,其值为test

FileZilla 425 无法连接FTP的解决方法(阿里云服务器)

很多次都被阿里的这个安全组恶心一下,其实是很好的设置,但是没有一些提示让我们去了解并设置他,所以一般很多时候都很被动的自行查找解决问题 阿里云服务器无法连接FTP 出现FileZilla 425 Can't open data connection 无法连接FTP 第一步: 在filezilla中开启被动模式 并设定端口范围 例如1/1 第二步: 在阿里云服务器控制台添加安全组 首先把刚刚设置的被动模式的端口范围添加上 例如1/1 然后添加FTP端口 一般都是21 如果不对的话可以查看一下 注意都是入方向 然后就可以连接成功了

接口自动化测试之预期结果的处理

在做接口自动化测试时,我们需将测试用例的预期结果与实际结果进行对比,如果一致就认定测试用例通过,不一致就认定失败。而后端接口返回的数据一般是以json的方式返回到前端,那么用jsonpath来做预期结果的处理就很适合了,尤其是对于复杂的json串,jsonpath的优势更明显。 Jsonpath:看它的名字你就能知道,这家伙和JSON文档有关系,正如XPath之于XML文档一样,JsonPath为Json文档提供了解析能力,通过使用JsonPath,你可以方便的查找节点、获取想要的数据,JsonPath是Json版的XPath。 JsonPath语法要点: $ 表示文档的根元素 @ 表示文档的当前元素 .node_name 或 ['node_name'] 匹配下级节点 [index] 检索数组中的元素 [start:end:step] 支持数组切片语法 * 作为通配符,匹配所有成员 .. 子递归通配符,匹配成员的所有子元素 (<expr>) 使用表达式 ?(<boolean expr>)进行数据筛选 下面分别用Java与Python实现以Jsonpath的方式处理预期结果 # java代码 import com.alibaba.fastjson.JSONPath; import org.junit.jupiter.api.Test; import java.util.HashMap; import java.util.Map; public class JSONPathUtil { public static Boolean checkPoint(String response, String checkData) throws Exception { //分隔检查点 String[] data = checkData.split(";"); //设置标记 Boolean flag = false; Map<String, Object> map = new HashMap<>(); for (int i = 0; i < data.

操作系统(10)----死锁

目录 一.死锁、饥饿、死循环的区别 二.死锁产生的必要条件 三.什么时候会发生死锁 四.死锁的处理策略 1.预防死锁 (1)破坏互斥条件 (2)破坏不剥夺条件 (3)破坏请求和保持条件 (4)破坏循环等待条件 2.避免死锁 (1)安全序列 (2)银行家算法 3.死锁的检测和解除 (1)死锁的检测 (2)死锁的解除 一.死锁、饥饿、死循环的区别 死锁:各进程互相等待对方手里的资源,导致各进程都阻塞,无法向前推进的现象。 饥饿:由于长期得不到想要的资源,某进程无法向前推进的现象。比如:在短进程优先(SPF)算法中,若有源源不断的短进程到来,则长进程将一直得不到处理机,从而发生长进程“饥饿”。 死循环:某进程执行过程中一直跳不出某个循环的现象。有时是因为程序逻辑 bug 导致的,有时是程序员故意设计的。 二.死锁产生的必要条件 产生死锁必须同时满足一下四个条件,只要其中任一条件不成立,死锁就不会发生。 1.互斥条件:只有对必须互斥使用的资源的争抢才会导致死锁(如哲学家的筷子、打印机设备)像内存、扬声器这样可以同时让多个进程使用的资源是不会导致死锁的(因为进程不用阻塞等待这种资源)。 2.不剥夺条件:进程所获得的资源在未使用完之前,不能由其他进程强行夺走,只能主动释放。 3.请求和保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源又被其他进程占有,此时请求进程被阻塞,但又对自己已有的资源保持不放。 4.循环等待条件:存在一种进程资源的循环等待链,链中的每一个进程已获得的资源同时被下一个进程所请求。 注意:发生死锁时一定有循环等待,但是发生循环等待时未必死锁(循环等待是死锁的必要不充分条件) 例如,哲学家问题中,若多出一个人,当这一人将筷子这一临界资源给3号哲学家时,就不会发生死锁。 所以,如果同类资源数大于1,则即使有循环等待,也未必发生死锁。但如果系统中每类资源都只有一个,那循环等待就是死锁的充分必要条件了。 三.什么时候会发生死锁 1.对系统资源的竞争。各进程对不可剥夺的资源(如打印机)的竞争可能引起死锁,对可剥夺的资源(CPU)的竞争是不会引起死锁的。 2.进程推进顺序非法。请求和释放资源的顺序不当,也同样会导致死锁。例如,并发执行的进程P1、P2分别申请并占有了资源 R1、R2之后进程P1又紧接着申请资源R2,而进程P2又申请资源R1,两者会因为申请的资源被对方占有而阻塞,从而发生死锁。 3.信号量的使用不当也会造成死锁。如生产者-消费者问题中,如果实现互斥的P操作在实现同步的P操作之前,就有可能导致死锁。(可以把互斥信号量、同步信号量也看做是一种抽象的系统资源) 总之,对不可剥夺资源的不合理分配,可能导致死锁。 对于生产者消费者问题不了解的可以先看一下我的这一篇:http://t.csdnimg.cn/cjZjT 对生产者消费者问题的阐述如下: 生产者、消费者问题 系统中有一组生产者进程和一组消费者进程,生产者进程每次生产一个产品放入缓冲区,消费者进程每次从缓冲区中取出一个产品并使用。(注:这里的“产品”理解为某种数据) 生产者、消费者共享一个初始为空、大小为n的缓冲区。 对于生产者: 缓冲区没满时,生产者才能继续生产,若缓冲区满时,生产者必须阻塞等待。 消费者从缓冲区取走数据后,若此时有生产者处于阻塞状态,那么消费者进程应该唤醒生产者进程(阻塞态--->就绪态) 注:生产者进程只是回到了就绪态,这并不意味着生产者进程需要立即往缓冲区写数据 对于消费者: 缓冲区空时,消费者必须等待,缓冲区没空时,消费者才能取走数据(消费) 当生产者写入数据,缓冲区不为空,就会唤醒消费者进程(阻塞态--->就绪态) 缓冲区: 缓冲区是临界资源,各进程必须互斥地访问。 假如两个进程并发地往缓冲区写入数据,两个进程挑选了同一块区域写入数据,那么后面进程写入的数据就会覆盖前面进程写入的数据。所以各进程必须互斥访问才不会导致数据覆盖等问题。 PV操作题目分析步骤: 例:系统中有一组生产者进程和一组消费者进程,生产者进程每次生产一个产品放入缓冲区,消费者进程每次从缓冲区中取出一个产品并使用。(注:这里的“产品”理解为某种数据) 生产者、消费者共享一个初始为空、大小为n的缓冲区。 1.找出题目中描述的各个进程,分析它们之间的同步、互斥关系。 同步:当缓冲区没满时,生产者才能生产,否则堵塞等待,当缓冲区没空时,消费者才能消费,否则堵塞等待。 互斥:对于临界资源,各进程必须互斥访问。 2.根据各进程的操作流程确定P、V操作的大致顺序 当缓冲区没空(即有产品)之后,可以执行V操作,在在消费者消费之前需要执行P操作。下面的案例同理。(前V后P) 3.设置信号量,并根据题目条件确定信号量初值。(互斥信号量初值一般为1,同步信号量的初始值要看对应资源的初始值是多少) semaphore mutex=1; //互斥信号量,实现对缓冲区的互斥访问 semaphore empty=n; //同步信号量,表示空闲缓冲区的数量 semaphore full=0; //同步信号量,表示产品的数量,也即非空缓冲区的数量

Linux实验记录:使用Apache服务部署静态网站

前言: 本文是一篇关于Linux系统初学者的实验记录。 参考书籍:《Linux就该这么学》 实验环境: VmwareWorkStation 17——虚拟机软件 RedHatEnterpriseLinux[RHEL]8——红帽操作系统 目录 前言: 备注: 正文: 实验1:安装Apache程序 Step1:把系统镜像挂载到/media/cdrom目录 Step2:使用Vim文本编辑器创建软件仓库的配置文件 Step3:安装Apache服务程序 Step4:启用httpd服务程序并将其加入到开机启动项 实验2:配置服务参数文件:修改保存网站数据的目录 Step1:建立网站数据的保存目录,并创建首页文件 Step2:打开httpd服务程序的主配置文件,并修改: Step3:重启httpd服务程序并验证效果 ​实验3:SELinux安全子系统 Step1:验证前文中权限不足是由于SELinux而导致的 Step2:semanage命令 Step3:向新的网站数据目录中新添加一条SELinux安全上下文 实验4:个人用户主页功能 Step1:编辑配置文件,开启个人用户主页功能 step2:在用户家目录中建立用于保存网站数据的目录及首页文件 Step3:查看SELinux域安全策略 实验5:在网站中添加密码功能 Step1:使用htpasswd命令生成密码数据库 Step2:继续编辑个人用户主页功能的配置文件 备注: Web网络服务,一般是指允许用户通过浏览器访问互联网中各种资源的服务。 Web网络服务是一种被动访问的服务程序,只有接收到互联网中其他主机发出的请求后才会相应,最终用于提供服务程序的Web服务器会通过HTTP或HTTPS把请求的内容传送給用户。 目前能提供Web网络服务的程序有:IIS、Nginx和Apache等 IIS(Internet Information Service,互联网信息服务)是Windows系统中默认的Web服务程序。 Nigix程序作为一款轻量级的网站服务软件,有好的稳定性和丰富的功能。 Apache程序是RHEL5、6、7、8系统中默认的Web服务程序,名字取自美国印第安人的土著语,寓意为“拥有高超的作战策略和无穷的耐性”。 正文: 实验1:安装Apache程序 Step1:把系统镜像挂载到/media/cdrom目录 Step2:使用Vim文本编辑器创建软件仓库的配置文件 Step3:安装Apache服务程序 Step4:启用httpd服务程序并将其加入到开机启动项 打开firefox,访问127.0.0.1(测试页面) 实验2:配置服务参数文件:修改保存网站数据的目录 在Linux系统中配置服务,其实就是修改服务的配置文件。 Linux系统中的配置文件: 作用文件名称服务目录/etc/httpd主配置文件/etc/httpd/conf/httpd.conf网站数据目录/var/www/html访问日志/var/log/httpd/access_log错误日志/var/log/httpd/error_log 主配置文件中保存的是最重要的服务参数 在主配置文件中,存在上中类型的信息:注释行信息、全局配置、区域配置 全局配置参数可以用于所有的子站点,区域配置参数则是单独针对每个独立的子站点进行设置的。 配置httpd服务程序时最常用的参数以及用途描述: 参数作用ServerRoot服务目录ServerAdmin管理员邮箱User运行服务的用户Group运行服务的用户组ServerName网站服务器的域名DocumentRoot网站数据目录Listen监听的IP地址与端口号DirectoryIndex默认的索引页页面ErrorLog错误日志文件CustomLog访问日志文件Timeout网页超时时间,默认300秒 由表可知:Document参数用于定义网站数据的保存路径,参数默认值/var/www/html 当前网站普遍的首页名称是index.html。 尝试修改网页内容,并在firefox中查看: Step1:建立网站数据的保存目录,并创建首页文件 Step2:打开httpd服务程序的主配置文件,并修改: Step3:重启httpd服务程序并验证效果 此时会提示权限不足,需要修改SELinux策略。 实验3:SELinux安全子系统 SELinux(Security-Enhanced Linux)是美国国家安全局在Linux开源社区的帮助下开发的一个强制访问控制(MAC,Mandatory Access Control)的安全子系统。 Linux系统使用SELinux技术的目的是为了让各个服务进程都受到约束,使其仅获取到本应获取的资源。

【SparkML系列3】特征提取器TF-IDF、Word2Vec和CountVectorizer

本节介绍了用于处理特征的算法,大致可以分为以下几组: 提取(Extraction):从“原始”数据中提取特征。转换(Transformation):缩放、转换或修改特征。选择(Selection):从更大的特征集中选择一个子集。局部敏感哈希(Locality Sensitive Hashing, LSH):这类算法结合了特征转换的方面与其他算法。 Feature Extractors(特征提取器) TF-IDF 词频-逆文档频率(Term frequency-inverse document frequency,简称TF-IDF)是一种在文本挖掘中广泛使用的特征向量化方法,用以反映一个词语对于语料库中文档的重要性。用t表示一个词语,用d表示一个文档,用D表示语料库。词频TF(t,d)是词语t在文档d中出现的次数,而文档频率DF(t,D)是包含词语t的文档数量。如果我们仅使用词频来衡量重要性,那么很容易过分强调那些出现非常频繁但对文档信息贡献较小的词语,例如“a”、“the”和“of”。如果一个词语在整个语料库中出现得非常频繁,这意味着它对特定文档没有携带特殊信息。逆文档频率是衡量一个词语提供了多少信息的数值度量: 其中|D|是语料库中文档的总数。由于使用了对数,如果一个词语出现在所有文档中,其逆文档频率(IDF)值将变为0。注意,为了避免对语料库外的词语进行除零操作,应用了平滑项。TF-IDF值简单地是词频(TF)和逆文档频率(IDF)的乘积: 在词频和文档频率的定义上有几种不同的变体。在MLlib中,我们将TF和IDF分开,以使它们更加灵活。 TF:HashingTF和CountVectorizer都可以用来生成词频向量。 HashingTF是一个Transformer,它接受一组词语并将这些集合转换成固定长度的特征向量。在文本处理中,“一组词语”可能是一个词袋。HashingTF利用哈希技巧。通过应用一个哈希函数,将一个原始特征映射到一个索引(词项)上。这里使用的哈希函数是MurmurHash 3。然后根据映射后的索引计算词频。这种方法避免了计算全局的词到索引映射表,这对于大型语料库来说可能代价很高,但它会遭受潜在的哈希冲突,不同的原始特征经过哈希可能会变成相同的词项。为了减少冲突的机会,我们可以增加目标特征维度,即哈希表的桶数。由于使用简单的模运算来确定向量索引,建议使用2的幂作为特征维度,否则特征将不会均匀地映射到向量索引上。默认的特征维度是2的18次方,即262,144。一个可选的二元切换参数控制词频计数。当设置为true时,所有非零频率计数都设置为1。这对于模拟二元而不是整数计数的离散概率模型特别有用。 CountVectorizer将文本文档转换为词项计数向量。有关更多详情,请参考CountVectorizer。 IDF:IDF是一个估计器,它在数据集上进行训练并产生一个IDFModel。IDFModel接受特征向量(通常由HashingTF或CountVectorizer创建)并对每个特征进行缩放。直观地说,它降低了在语料库中频繁出现的特征的权重。 注意:spark.ml不提供文本分割工具。我们推荐用户使用斯坦福NLP小组的工具和scalanlp/chalk。 import org.apache.spark.ml.feature.{HashingTF, IDF, Tokenizer} import org.apache.spark.sql.SparkSession /** * @description TfIdfExample * @date 2024/1/31 18:09 * @author by fangwen1 */ object TfIdfExample { def main(args: Array[String]): Unit = { val spark = SparkSession .builder .master("local[*]") .appName("TfIdfExample") .getOrCreate() // 创建测试数据集 val sentenceData = spark.createDataFrame(Seq( (0.0, "Hi I heard about Spark"), (0.0, "

由《幻兽帕鲁》私服漏洞引发的攻击面思考

《幻兽帕鲁》私服意外丢档 当了一天的帕鲁,回家开机抓帕鲁的时候发现服务器无法连接。运维工具看了下系统负载发现 CPU 已经跑满。 故障排查 登录服务器进行排查发现存在可疑的 docker 进程。 经过一番艰苦的溯源,终于在命令行历史中发现了端倪 攻击者为了实现挖坑的收益最大化,删除了服务器上的所有 docker,并启动了一个挖坑进程。恰巧帕鲁的私服也是通过 docker 的方式进行的部署,惨遭波及。 想到我辛苦一小时抓的海誓龙,多次丝血逃跑的艰辛,必须溯源下去。 通过后续进一步的排查,最终定位到了攻击者真实的入侵路径。 亡羊补牢 在一位资深“黑客”朋友的指导下,我在众多安全产品中选择了一款使用最便捷的 SAAS 工具进行服务器漏洞的监控。其打动我的优势如下: 1. SAAS 应用,微信登录,无需部署,开箱即用 2. 24 小时监控,无需专业知识 3. 支持公众号推送告警,对我这种不使用办公社交软件的用户极为友好 4. 每月仅需 5 元 顺便给大家推荐下这个工具:云图极速版 - 攻击面发现,攻击面管理工具

SSTI漏洞检测工具tplmap的安装与使用

SSTI工具安装与使用,操作环境kali 参考:[https://www.cnblogs.com/ktsm/p/15473100.html] 1、安装python2的pip工具 kali2020版及以上, 输入python2命令会执行python2, python3也存在。 但pip默认是pip3, 而我们需要的是pip2, 所以我们需要先安装pip2 git clone https://github.com/epinna/tplmap cd tplmap pip install -r requirements.txt 2、使用git克隆tplmap 进入家目录 #建立目录ins-pip2 cd mkdir ins-pip2 #下载pip2安装脚本 wget https://bootstrap.pypa.io/pip/2.6/get-pip.py #python2执行 需要sudo权限 sudo python2 get-pip.py #升级pip2 sudo pip2 install --upgrade pip #安装pip2扩展工具,不然后面安装还是报错 sudo pip2 install --upgrade setuptools 3、详细指令 --os-shell Run shell on the target --os-cmd Execute shell commands --bind-shell PORT Connect to a shell bind to a target port --reverse-shell HOST PORT Send a shell back to the attacker's port --upload LOCAL REMOTE Upload files to the server --download REMOTE LOCAL Download remote files 4、使用 当使用tplmap时,报出

两种相同的垂直工具栏标志以及为什么

可能你很少碰到这样的开发需求,所以本文属于”课外阅读”级别。 有两种方式启用垂直工具栏,一种是指定通用的 CCS_VERT 标志,另外一种,比较罕见:指定工具栏所特有的扩展属性 TBSTYLE_EX_VERTICAL。 问题来了,为什么会存在两个标志来做同一件事情? 因为我们搞砸了。 当初设计 TBSTYLE_EX_VERTICAL 的人没有意识到其实已经有一种通用而简单的方法了(就是上面所说的 CCS_VERT 标志),更糟糕的是,工具栏的某些属性由 CCS_VERT 控制,而另外一些则由 TBSTYLE_EX_VERTICAL 控制。 所以,如果你希望在 Windows XP 系统上启用一个垂直工具栏,则你可能需要同时设置这两个标志。 事情还没完。 因为这个错误已经铸成,我们不得自动化的同时启用这两个标志,也就是如果系统检测到开发者设置了 CCS_VERT,则会自动加上另外一个 TBSTYLE_EX_VERTICAL,反之亦然。 这个自动化机制可以确保开发者始终都会得到一个统一的工具栏呈现,而不会因为只设置了一个标志并忘记另外一个所带来的不一致行为。 但总的来说,确实是我们的设计失误,因为还有一些开发者就是希望故意只设置其中一个标志,从而得到他们希望的效果,在这种情况下,因为我们的自动化同步机制,他们没法得到他们想要的。 对此,我们很抱歉。 我可以立即联想到先发制人且尖酸刻薄的批评:”瞧,这就是为什么 Windows 垃圾的原因。” 总结 所谓人无完人,没有人是完美的,也没有代码是完美的。 我们的目标是:吸取教训,绝不再犯同样的错误。 最后 Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。 本文来自:《Why are there both TBSTYLE_EX_VERTICAL and CCS_VERT?》

13:会话跟踪技术Session的深度应用与实践-Java Web

目录 13.1 Session基本概念13.2 后端Java Servlet中的Session操作13.3 前端JavaScript与后端Session的交互13.4 Session与Cookie区别总结13.5 Session的应用场景总结 在Java Web开发中,Session作为服务器端的会话跟踪技术,为保持用户状态和管理应用程序逻辑提供了强大的支持。本文将全方位解析Session的工作原理、前后端实现方法,并对比其与其他会话跟踪技术(如Cookie)的区别,同时探讨多种应用场景,以助开发者更好地理解和运用Session机制。 13.1 Session基本概念 Session是Web服务器为了维持特定客户端用户的会话而创建的一种数据存储结构。每个用户在与服务器交互时都会获得一个唯一的Session ID,这个ID通常通过Cookie或者URL重写等方式传递给客户端。服务器端根据Session ID来关联和维护该用户的状态信息。 13.2 后端Java Servlet中的Session操作 在Java Servlet中,我们可以使用HttpSession接口来创建、读取和管理Session。 创建并获取Session import javax.servlet.http.HttpSession; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public void getSession(HttpServletRequest request, HttpServletResponse response) { HttpSession session = request.getSession(); // 获取或创建新的Session session.setAttribute("username", "JohnDoe"); // 设置Session属性 } 读取Session属性 public String getUsername(HttpServletRequest request) { HttpSession session = request.getSession(false); // 获取已存在的Session,不存在则返回null if (session != null) { return (String) session.getAttribute("username"); // 读取Session属性值 } return null; // 如果没有找到,则返回null } 销毁Session

10:基于Servlet模拟用户登录功能的实现与解析-Java Web

目录 10.1 登录表单设计与前端交互10.2 创建Servlet处理登录请求10.3 用户服务模拟实现10.4 安全性与优化考量10.5 区别总结10.6 应用场景总结 在Web开发中,用户登录功能是几乎所有系统的基础模块。本篇博客将通过编写一个基于Java Servlet的用户登录模拟案例,详细阐述如何从接收到前端请求、验证用户信息、到处理登录结果并返回响应的全过程。我们将深入探讨代码细节,并分析不同实现方案之间的优缺点,最后总结其在实际项目中的应用场景。 10.1 登录表单设计与前端交互 设计HTML表单以收集用户名和密码。使用JavaScript进行简单的表单验证与提交操作。 <!-- login.html --> <form id="loginForm" action="/login" method="post"> <input type="text" name="username" placeholder="Username" required> <input type="password" name="password" placeholder="Password" required> <button type="submit">Login</button> </form> 10.2 创建Servlet处理登录请求 定义Servlet类并配置web.xml或使用注解映射URL。在doPost方法中获取请求参数并进行用户验证。 // LoginServlet.java @WebServlet("/login") public class LoginServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = request.getParameter("password"); // 假设我们有一个UserService来处理用户验证 UserService userService = new UserService(); User user = userService.