【算法篇】动态规划类(1)(笔记)
目录
一、理论基础
1. 大纲
2. 动态规划的解题步骤
二、LeetCode 题目
1. 斐波那契数
2. 爬楼梯
3. 使用最小花费爬楼梯
4. 不同路径
5. 不同路径 II
6. 整数拆分
7. 不同的二叉搜索树
一、理论基础
1. 大纲
动态规划,英文:Dynamic Programming,简称 DP,如果 某一问题有很 多重叠子问题,使用动态规划 是最有效的。
动态规划中 dp[j] 是由 dp[j-weight[i]] 推导出来的,然后取 max(dp[j], dp[j - weight[i]] + value[i])。
2. 动态规划的解题步骤
- 确定 dp 数组(dp table)以及下标的含义。
- 确定 递推公式。
- dp 数组 如何初始化。
- 确定 遍历顺序。
- 举例 推导 dp 数组。
二、LeetCode 题目
1. 斐波那契数
https://leetcode.cn/problems/fibonacci-number/submissions/569810951/https://leetcode.cn/problems/fibonacci-number/submissions/569810951/
斐波那契数,通常用 F(n) 表示,形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是: F(0) = 0,F(1) = 1 F(n) = F(n - 1) + F(n - 2),其中 n > 1 给你n ,请计算 F(n) 。
示例 1:
输入:n = 2
输出:1
解释:F(2) = F(1) + F(0) = 1 + 0 = 1示例 2:
输入:n = 3
输出:2
解释:F(3) = F(2) + F(1) = 1 + 1 = 2示例 3:
输入:n = 4
输出:3
解释:F(4) = F(3) + F(2) = 2 + 1 = 3
理解:
① dp[i] 的定义为:第 i 个数的 斐波那契数值是 dp[i]。
② 状态转移方程 dp[i] = dp[i - 1] + dp[i - 2]。
③ 初始化。
dp[0] = 0; dp[1] = 1;
// 写法一:
class Solution {
public:int fib(int n) {if (n < 2) return n;return fib(n - 1) + fib(n - 2);}
};// 写法二:
class Solution {
public:int fib(int n) {int f0 = 0, f1 = 1;int num;if (n == 1) return f1;if (n == 0) return f0;for (int i = 1; i < n; i++) {num = f0 + f1;f0 = f1;f1 = num;}return num;}
};
2. 爬楼梯
https://leetcode.cn/problems/climbing-stairs/description/https://leetcode.cn/problems/climbing-stairs/description/
假设你正在爬楼梯。需要
n
阶你才能到达楼顶。每次你可以爬1
或2
个台阶。你有多少种不同的方法可以爬到楼顶呢?
示例 1:
输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶示例 2:
输入:n = 3
输出:3
解释:有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶
理解:
① dp[i]: 爬到第i层楼梯,有dp[i]种方法。
② dp[i] = dp[i - 1] + dp[i - 2] :首先是 dp[i - 1],上 i-1 层楼梯,有 dp[i - 1] 种方法,那么再一步跳一个台阶不就是 dp[i] 了。还有就是 dp[i - 2],上 i-2 层楼梯,有 dp[i - 2] 种方法,那么再一步跳两个台阶不就是 dp[i] 了。
③ dp[0] = 1,相当于直接站在楼顶。
class Solution {
public:int climbStairs(int n) {if (n <= 2) return n;int dp[2] = {1, 2};for (int i = 2; i < n; i++) {int num = dp[0] + dp[1];dp[0] = dp[1];dp[1] = num;}return dp[1];}
};
3. 使用最小花费爬楼梯
https://leetcode.cn/problems/min-cost-climbing-stairs/description/https://leetcode.cn/problems/min-cost-climbing-stairs/description/
给你一个整数数组
cost
,其中cost[i]
是从楼梯第i
个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。你可以选择从下标为
0
或下标为1
的台阶开始爬楼梯。请你计算并返回达到楼梯顶部的最低花费。
示例 1:
输入:cost = [10,15,20]
输出:15
解释:你将从下标为 1 的台阶开始。
- 支付 15 ,向上爬两个台阶,到达楼梯顶部。
总花费为 15 。示例 2:
输入:cost = [1,100,1,1,1,100,1,1,100,1]
输出:6
解释:你将从下标为 0 的台阶开始。
- 支付 1 ,向上爬两个台阶,到达下标为 2 的台阶。
- 支付 1 ,向上爬两个台阶,到达下标为 4 的台阶。
- 支付 1 ,向上爬两个台阶,到达下标为 6 的台阶。
- 支付 1 ,向上爬一个台阶,到达下标为 7 的台阶。
- 支付 1 ,向上爬两个台阶,到达下标为 9 的台阶。
- 支付 1 ,向上爬一个台阶,到达楼梯顶部。
总花费为 6 。
理解:
① 到达第 i 台阶所花费的最少体力为 dp[i]。
② dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
可以有 两个途径得到 dp[i],一个是dp[i-1] 一个是 dp[i-2]。
dp[i - 1] 跳到 dp[i] 需要花费 dp[i - 1] + cost[i - 1]。
dp[i - 2] 跳到 dp[i] 需要花费 dp[i - 2] + cost[i - 2]。
③ dp[0] = 0,dp[1] = 0;
class Solution {
public:int minCostClimbingStairs(vector<int>& cost) {if (cost.size() == 1) return cost[0];if (cost.size() == 0) return 0;int dp[2] = {0};for (int i = 1; i < cost.size(); i++) {int costmin = min(dp[0] + cost[i - 1], dp[1] + cost[i]);dp[0] = dp[1];dp[1] = costmin;}return dp[1];}
};
4. 不同路径
https://leetcode.cn/problems/unique-paths/description/https://leetcode.cn/problems/unique-paths/description/
一个机器人位于一个
m x n
网格的左上角 (起始点在下图中标记为 “Start” )。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
问总共有多少条不同的路径?
示例 1:
输入:m = 3, n = 7
输出:28示例 2:
输入:m = 3, n = 2
输出:3
解释:
从左上角开始,总共有 3 条路径可以到达右下角。
1. 向右 -> 向下 -> 向下
2. 向下 -> 向下 -> 向右
3. 向下 -> 向右 -> 向下示例 3:
输入:m = 7, n = 3
输出:28示例 4:
输入:m = 3, n = 3
输出:6
理解:
① dp[i][j] :表示从(0 ,0)出发,到 (i, j) 有 dp[i][j] 条不同的路径。
② dp[i][j] = dp[i - 1][j] + dp[i][j - 1],因为 dp[i][j] 只有这两个方向过来。
③ dp[i][0] 一定都是 1,因为从 (0, 0) 的位置到 (i, 0) 的路径只有一条,那么 dp[0][j] 也同理。
// 方法一:(二维数组实现)
class Solution {
public:int uniquePaths(int m, int n) {vector<vector<int>> dp(m, vector<int>(n, 0));for (int i = 0; i < m; i++) dp[i][0] = 1;for (int j = 0; j < n; j++) dp[0][j] = 1;for (int i = 1; i < m; i++) {for (int j = 1; j < n; j++) {dp[i][j] = dp[i - 1][j] + dp[i][j - 1];}}return dp[m - 1][n - 1];}
};// 方法二:(一维数组实现)
class Solution {
public:int uniquePaths(int m, int n) {vector<int> dp(n);for (int i = 0; i < n; i++) dp[i] = 1;for (int j = 1; j < m; j++) {for (int i = 1; i < n; i++) {dp[i] += dp[i - 1];}}return dp[n - 1];}
};// 方法三:
class Solution {
public:int uniquePaths(int m, int n) {if (m == 0 || n == 0) return 1;vector<vector<int>> buff(m, vector<int>(n, 0));buff[0][0] = 1;for (int row = 0; row < m; row++) {for (int col = 0; col < n; col++) {if (row == 0 && col == 0) continue;else if (row == 0) buff[0][col] = buff[0][col - 1];else if (row > 0 && col == 0) buff[row][0] = buff[row - 1][0];else buff[row][col] = buff[row - 1][col] + buff[row][col - 1];// cout << buff[row][col] << " ";}// cout << endl;}return buff[m - 1][n - 1];}
};
5. 不同路径 II
https://leetcode.cn/problems/unique-paths-ii/description/https://leetcode.cn/problems/unique-paths-ii/description/
给定一个
m x n
的整数数组grid
。一个机器人初始位于 左上角(即grid[0][0]
)。机器人尝试移动到 右下角(即grid[m - 1][n - 1]
)。机器人每次只能向下或者向右移动一步。网格中的障碍物和空位置分别用
1
和0
来表示。机器人的移动路径中不能包含 任何 有障碍物的方格。返回机器人能够到达右下角的不同路径数量。
测试用例保证答案小于等于
2 * 109
。
示例 1:
输入:obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
输出:2
解释:3x3 网格的正中间有一个障碍物。
从左上角到右下角一共有 2 条不同的路径:1. 向右 -> 向右 -> 向下 -> 向下2. 向下 -> 向下 -> 向右 -> 向右
示例 2:
输入:obstacleGrid = [[0,1],[0,0]]
输出:1
理解:
① dp[i][j] :表示从(0 ,0)出发,到 (i, j) 有 dp[i][j] 条不同的路径。
② 从 (0, 0) 的位置到 (i, 0) 的路径只有一条,所以 dp[i][0] 一定为 1,dp[0][j] 也同理。但如果 (i, 0) 这条边有了障碍之后,障碍之后(包括障碍)都是走不到的位置了,所以障碍之后的 dp[i][0] 应该还是 初始值 0。
// 方法一:(二维数组保存)
class Solution {
public:int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {// 二维数组保存int m = obstacleGrid.size();int n = obstacleGrid[0].size();if (obstacleGrid[m - 1][n - 1] == 1 || obstacleGrid[0][0] == 1) return 0;vector<vector<int>> buff(m, vector<int>(n, 0));buff[0][0] = 1;for (int row = 0; row < m; row++) {for (int col = 0; col < n; col++) {if ((row == 0 && col == 0) || obstacleGrid[row][col] == 1) continue;else if (row == 0) buff[row][col] = buff[row][col - 1];else if (col == 0) buff[row][0] = buff[row - 1][0];else buff[row][col] = buff[row - 1][col] + buff[row][col - 1];}}return buff[m - 1][n - 1];}
};// 方法二:(一维数组保存)
class Solution {
public:int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {int m = obstacleGrid.size();int n = obstacleGrid[0].size();if (obstacleGrid[m - 1][n - 1] == 1 || obstacleGrid[0][0] == 1) //如果在起点或终点出现了障碍,直接返回0return 0;vector<vector<int>> dp(m, vector<int>(n, 0));for (int i = 0; i < m && obstacleGrid[i][0] == 0; i++) dp[i][0] = 1;for (int j = 0; j < n && obstacleGrid[0][j] == 0; j++) dp[0][j] = 1;for (int i = 1; i < m; i++) {for (int j = 1; j < n; j++) {if (obstacleGrid[i][j] == 1) continue;dp[i][j] = dp[i - 1][j] + dp[i][j - 1];}}return dp[m - 1][n - 1];}
};// 方法三:
class Solution {
public:int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {// 二维数组保存if (obstacleGrid[0][0] == 1) return 0;int m = obstacleGrid.size();int n = obstacleGrid[0].size();vector<vector<int>> buff(m, vector<int>(n, 0));buff[0][0] = 1;for (int row = 0; row < m; row++) {for (int col = 0; col < n; col++) {if ((row == 0 && col == 0) || obstacleGrid[row][col] == 1) continue;else if (row == 0) buff[row][col] = buff[row][col - 1];else if (col == 0) buff[row][0] = buff[row - 1][0];else buff[row][col] = buff[row - 1][col] + buff[row][col - 1];}}return buff[m - 1][n - 1];}
};
6. 整数拆分
https://leetcode.cn/problems/integer-break/description/https://leetcode.cn/problems/integer-break/description/
给定一个正整数
n
,将其拆分为k
个 正整数 的和(k >= 2
),并使这些整数的乘积最大化。返回 你可以获得的最大乘积 。
示例 1:
输入: n = 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1。示例 2:
输入: n = 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。
理解:
①dp[i]:分拆数字 i,可以得到的 最大乘积为 dp[i]。
②有两种渠道得到 dp[i]:一个是 j * (i - j) 直接相乘。一个是 j * dp[i - j],相当于是拆分 (i - j)。j 是从 1 开始遍历,拆分 j 的情况,在遍历 j 的过程中其实都计算过了。那么从 1 遍历 j,比较 (i - j) * j 和 dp[i - j] * j 取最大的。递推公式:dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));
③这里只初始化 dp[2] = 1,从 dp[i] 的定义来说,拆分数字 2,得到的最大乘积是 1。
class Solution {
public:int integerBreak(int n) {// dp 表示 对应为下标数字时 拆分的最大值,可以由之前下标数组最大值得出vector<int> dp(n + 1, 0);dp[2] = 1; // 数字代表拆分的数字for (int i = 3; i <= n; i++) {for (int j = 1; j <= i / 2; j++) {// 从 1 开始拆,有拆和不拆两种选择dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));}}return dp[n];}
};
7. 不同的二叉搜索树
https://leetcode.cn/problems/unique-binary-search-trees/description/https://leetcode.cn/problems/unique-binary-search-trees/description/
给你一个整数
n
,求恰由n
个节点组成且节点值从1
到n
互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。
示例 1:
输入:n = 3
输出:5示例 2:
输入:n = 1
输出:1
理解:
① dp[i] : 1 到 i 为节点组成的二叉搜索树的个数为 dp[i]。
② dp[i] += dp[j - 1] * dp[i - j]; ,j - 1 为 j 为头结点左子树节点数量,i - j 为以 j 为头结点右子树节点数量。
③ dp[以 j 为头结点左子树节点数量] * dp[以 j 为头结点右子树节点数量] 中以 j 为头结点左子树节点数量为 0,也需要 dp[以 j 为头结点左子树节点数量] = 1, 否则乘法的结果就都变成 0 了。所以初始化 dp[0] = 1。
class Solution {
public:int numTrees(int n) {if (n == 1) return 1;vector<int> dp(n + 1, 0);dp[0] = 1, dp[1] = 1;for (int i = 2; i <= n; i++) {for (int j = 0; j < i; j++) {dp[i] += dp[j] * dp[i - j - 1];}}return dp[n];}
};
相关文章:

【算法篇】动态规划类(1)(笔记)
目录 一、理论基础 1. 大纲 2. 动态规划的解题步骤 二、LeetCode 题目 1. 斐波那契数 2. 爬楼梯 3. 使用最小花费爬楼梯 4. 不同路径 5. 不同路径 II 6. 整数拆分 7. 不同的二叉搜索树 一、理论基础 1. 大纲 动态规划,英文:Dynamic Programm…...

mysql学习教程,从入门到精通,SQL 约束(Constraints)(41)
在数据库设计中,约束(Constraints)用于确保数据的准确性和完整性。它们通过限制可以插入到数据库表中的数据类型来防止无效数据。SQL 中有几种常见的约束类型,包括主键约束(Primary Key)、外键约束…...

使用CSS3与JavaScript实现炫酷的3D旋转魔方及九宫格交换动效
文章目录 前言一、项目需求背景二、CSS3 3D基础知识介绍2.1 什么是CSS3 3D?2.2 主要使用的CSS属性 三、使用HTML和CSS搭建魔方结构四、让魔方动起来:CSS3动画五、九宫格数字交换的JavaScript实现5.1 九宫格布局5.2 随机交换数字 六、随机交换与相邻格子的…...

springboot项目通过maven的profile功能实现通过不同文件夹的方式来组织不同环境配置文件
写在前面 本文看下springboot项目如何通过文件夹的方式来组织不同环境配置文件。 1:正文 一般的我们写springboot项目时配置文件是这个样子的: appliction.yaml --> 通过spring.profiles.activexxx来激活某个指定后缀的配置文件 application-evn1…...

GAN(Generative Adversarial Nets)
GAN(Generative Adversarial Nets) 引言 GAN由Ian J. Goodfellow等人提出,是Ian J. Goodfellow的代表作之一,他还出版了大家耳熟能详的花书(Deep Learning深度学习),GAN主要的思想是同时训练两个模型,生成…...

linux下使用mpi求自然数和
搭建MPI并行计算环境,编写 MPI程序,求和 1 23....1 0000。 要求: 1.使用100个进程; 2.进程0计算1 2...100, 进程1计算101 102... 200, ..... 进程99计算9901 9902... 10000; 3.调用计时函数,分别输出每个进程的计算时间; 4.需使用MPI集群通信函数和同…...

WebGl学习使用attribute变量绘制一个水平移动的点
在WebGL编程中,attribute变量是一种特殊类型的变量,用于从客户端传递数据到顶点着色器。这些数据通常包括顶点的位置、颜色、纹理坐标等,它们是与每个顶点直接相关的信息。attribute变量在顶点着色器中声明,并且对于每个顶点来说都…...

机器学习四大框架详解及实战应用:PyTorch、TensorFlow、Keras、Scikit-learn
目录 框架概述PyTorch:灵活性与研究首选TensorFlow:谷歌加持的强大生态系统Keras:简洁明了的高层 APIScikit-learn:传统机器学习的必备工具实战案例 图像分类实战自然语言处理实战回归问题实战 各框架的对比总结选择合适的框架 1…...

linux源码安装slurm以及mung和openssl
一、源码安装munge 1、编译安装munge (1)下载munge地址:https://github.com/dun/munge/releases (2)解压编译安装: 1 2 3 4 5 6 7 8 创建/data目录 复制文件munge-0.5.15.tar.xz 到/data目录下 tar -Jx…...

分享蓝牙耳机A2DP音频卡顿原因及解决思路
背景 最近一直在更新博客,我觉得写博客有三个好处,一是很多东西时间久了就会忘,记下来方便自己以后回忆和总结,二是记下来可以加深自己对知识的理解,三是可以知识分享,方便他人。 言归正传,今天…...

Mac 下编译 libaom 源码教程
AV1 AV1是一种开放、免版税的视频编码格式,由开放媒体联盟(AOMedia)开发,旨在提供高压缩效率和优秀的视频质量。AV1支持多种分辨率,包括SD、HD、4K和8K,并适用于视频点播(VOD)、直播…...

【成品设计】基于Arduino平台的物联网智能灯
《基于Arduino平台的物联网智能灯》 整体功能: 这个任务中要求实现一个物联网智能灯。实际测试环境中要求设备能够自己创建一个热点,连接这个热点后能自动弹出控制界面(强制门户)。 功能点 基础功能 (60分) 要求作品至少有2个灯…...

安装和配置k8s可视化UI界面dashboard-1.20.6
安装和配置k8s可视化UI界面dashboard-1.20.6 1.环境规划2.初始化服务器1)配置主机名2)设置IP为静态IP3)关闭selinux4)配置主机hosts文件5)配置服务器之间免密登录6)关闭交换分区swap,提升性能7&…...

VLAN:虚拟局域网
VLAN:虚拟局域网 交换机和路由器协同工作后,将原先的一个广播域,逻辑上,切分为多个广播域。 第一步:创建VLAN [SW1]dispaly vlan 查询vlan VID(VLAN ID):用来区分和标定不同的vlan 由12位二进制构成 范围: 0-4…...

利用可解释性技术增强制造质量预测模型
概述 论文地址:https://arxiv.org/abs/2403.18731 本研究提出了一种利用可解释性技术提高机器学习(ML)模型性能的方法。该方法已用于铣削质量预测,这一过程首先训练 ML 模型,然后使用可解释性技术识别不需要的特征并去…...

FlexMatch: Boosting Semi-Supervised Learning with Curriculum Pseudo Labeling
FlexMatch: Boosting Semi-Supervised Learning with Curriculum Pseudo Labeling 摘要:引言:背景3 flexMatch3.1 Curriculum Pseudo Labeling3.2 阈值预热3.3非线性映射函数实验4.1 主要结果4.2 ImageNet上的结果4.3收敛速度加速4.4 消融研究5 相关工作摘要: 最近提出的Fi…...

Spring Cloud 3.x 集成eureka快速入门Demo
1.什么是eureka? Eureka 由 Netflix 开发,是一种基于REST(Representational State Transfer)的服务,用于定位服务(服务注册与发现),以实现中间层服务的负载均衡和故障转移ÿ…...
线性代数 矩阵
一、矩阵基础 1、定义 一组数按照矩形排列而成的数表;形似行列式,区别点是 矩阵行列式符号()或[]| |形状方阵或非方阵方阵本质数表数属性A|A|是A诸多属性中的一种维度m *n (m 与n可以相等也可以不相等)n*n 同型矩阵 若A、B两个矩阵都是mn 矩阵&#x…...

【C语言】使用结构体实现位段
文章目录 一、什么是位段二、位段的内存分配1.位段内存分配规则练习1练习2 三、位段的跨平台问题四、位段的应用五、位段使用的注意事项 一、什么是位段 在上一节中我们讲解了结构体,而位段的声明和结构是类似的,它们有两个不同之处,如下&…...

univer实现excel协同
快速入门 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><script src&q…...

JavaScript进阶笔记--深入对象-内置构造函数及案例
深入对象 创建对象三种方式 利用对象字面量new Object({…})利用构造函数 // 1. 字面量创建对象const obj1 {name: pig,age: 18};console.log(obj1); // {name: "pig", age: 18}// 2. 构造函数创建对象function Pig(name, age) {this.name…...

网络爬虫自动化Selenium模拟用户操作
自动化测试和网络爬虫在现代软件开发中占据着重要的位置。它们通过自动化用户操作,减少了人工重复操作的时间成本。Selenium作为一个功能强大且应用广泛的自动化工具,不仅能在不同的浏览器中运行自动化测试,还能进行跨平台测试,并允许与多种编程语言集成。本教程将介绍如何…...

尚硅谷rabbitmq 2024 流式队列2024指定偏移量 第55节答疑
rabbitmq的stream: 4、对比 autoTrackingstrategy方式:始终监听Stream中的新消息(狗狗看家,忠于职守)指定偏移量方式:针对指定偏移量的消息消费之后就停止(狗狗叼飞盘,回来就完) 这两种分别怎么写?java 在 RabbitMQ 中,…...

NSSCTF-WEB-pklovecloud
目录 前言 正文 思路 尝试 结尾 前言 许久未见,甚是想念. 今天来解一道有意思的序列化题 正文 思路 <?php include flag.php; class pkshow {function echo_name(){return "Pk very safe^.^";} }class acp {protected $cinder;public $neutron;public $…...

深入Postman- 自动化篇
前言 在前两篇博文《Postman使用 - 基础篇》《玩转Postman:进阶篇》中,我们介绍了 Postman 作为一款专业接口测试工具在接口测试中的主要用法以及它强大的变量、脚本功能,给测试工作人员完成接口的手工测试带来了极大的便利。其实在自动化测试上,Postman 也能进行良好的支…...

react-JSX
JSX理念 jsx在编译的时候会被babel编译为react.createELement方法 在使用jsx的文件中,需要引入react。import React from "react" jsx会被编译为React.createElement,所有jsx的运行结果都是react element React Component 在react中,常使用…...

深度对比:IPguard与Ping32在企业网络管理中的应用
随着网络安全形势日益严峻,企业在选择网络管理工具时需慎之又慎。IPguard与Ping32是目前市场上两款颇具代表性的产品,它们在功能、性能以及应用场景上各有优势。本文将对这两款产品进行深度对比,以帮助企业找到最合适的解决方案。 IPguard以其…...

AI测试之 TestGPT
如今最火热的技术莫非OpenAI的ChatGPT莫属,AI技术也在很多方面得到广泛应用。今天我们要介绍的TestGPT就是一个软件测试领域中当红的应用。 TestGPT是什么? TestGPT是一家总部位于以色列特拉维夫的初创公司 CodiumAI Ltd.,发布的一款用于测…...

JavaEE-进程与线程
1.进程 1.1什么是进程 每个应⽤程序运⾏于现代操作系统之上时,操作系统会提供⼀种抽象,好像系统上只有这个程序在运 ⾏,所有的硬件资源都被这个程序在使⽤。这种假象是通过抽象了⼀个进程的概念来完成的,进程可 以说是计算机科学…...

JAVA软开-面试经典问题(6)-equals与hashcode方法
1.equals方法 1.Object类中的equals方法比较的是两个对象的地址(底层原理是 比较的,即比较的是对象的地址) return (this obj);2.基本数据类型的包装类和String类都重写了equals方法。 基本数据类型:比较的是数值的是否相等 …...