当前位置: 首页 > news >正文

三、shell脚本--运算符与表达式:让脚本学会“思考”

一、算术运算符:加减乘除取模

在我们写shell脚本时,做点基本的数学运算还是经常需要的。常用的算术运算符跟我们平时学的一样:

  • + :
  • - :
  • * : (小提示:有时候在某些命令里可能需要写成 \*)
  • / : (在 Shell 里通常是取整数部分)
  • % : 取余数 (求模)

想在 Shell 里算个数,有下面这几种方法:

  • 方法一:用 expr 命令 (比较老资格的方法,语法稍微有点怪 👴)

    • 数字和运算符之间必须用空格隔开
    • 乘号 * 很多时候需要转义,写成 \*
    #!/bin/bash
    num1=10
    num2=3
    # 注意空格和乘号的转义
    sum_result=$(expr $num1 + $num2)
    product_result=$(expr $num1 \* $num2)
    echo "expr 计算: $num1 + $num2 = $sum_result"
    echo "expr 计算: $num1 * $num2 = $product_result"
    
  • 方法二:用 let 命令 (比 expr 省事儿一点 👍)

    • 可以直接在 let 后面写数学表达式,变量名不用加 $,运算符不用空格,乘号也不用转义
    • 它通常是用来直接改变一个变量的值
    #!/bin/bash
    count=5
    echo "初始计数: $count"
    # 用 let 直接操作变量
    let count=count+3
    echo "加 3 后的计数: $count"
    let count*=2 # 乘 2
    echo "再乘 2 后的计数: $count"
    
  • 方法三:用 $(( )) (强烈推荐!现代、最方便 ⭐)

    • 这是目前最主流最推荐的整数运算方式。
    • 把你的算术表达式整个放进双圆括号 $((...)) 里。
    • 括号里面的写法就跟写普通数学题差不多,变量名前的 $ 可加可不加(加上更清晰),运算符不需要特殊转义,空格也不强制要求(但可以有)。
    • 它会直接返回计算结果
    • 注意: Bash 的 $(( )) 默认做的是整数运算,结果没有小数部分。
    #!/bin/bash
    a=15
    b=4# 用 $(( )) 做各种运算
    sum=$((a + b))
    difference=$((a - b))
    product=$((a * b))
    quotient=$((a / b)) # 整数除法,结果是 3
    remainder=$((a % b)) # 取余数,结果是 3echo "$a + $b = $sum"
    echo "$a - $b = $difference"
    echo "$a * $b = $product"
    echo "$a / $b (整除) = $quotient"
    echo "$a % $b (取余) = $remainder"# 也可以直接用在 echo 或其他地方
    echo "$a 的平方是: $((a * a))"
    

    一句话建议: 做整数计算?用 $(( )) 就对了,省心又好用

二、关系运算符:比一比,谁大谁小谁相等

光会算还不够,脚本还得能比较。比如比较两个数谁大,或者两个字符串是不是一样。Shell 里比较数字和比较字符串(文本)用的符号不一样,这点要分清楚!

1.数字大小比较 🔢

如果你要比较的是数字,那么在 if 语句的条件判断部分(通常是 [ ... ][[ ... ]] 里面)要用下面这些:

  • -eq : 等于 (Equal)
  • -ne : 不等于 (Not Equal)
  • -gt : 大于 (Greater Than)
  • -lt : 小于 (Less Than)
  • -ge : 大于或等于 (Greater or Equal)
  • -le : 小于或等于 (Less or Equal)
#!/bin/bash
score=85
pass_mark=60echo "你的得分: $score"
echo "及格分数线: $pass_mark"# 用 [ ... ] 来比较数字
if [ $score -ge $pass_mark ]; then
echo "<font color='green'>恭喜你,通过了!</font> 👍"
else
echo "<font color='red'>呃,还得再加把劲儿。</font> 💪"
fival1=100
val2=100
if [ $val1 -eq $val2 ]; then
echo "这两个数值相等。"
fi

切记:单方括号 [ ... ] 里,运算符(像 -ge)和它两边的数字/变量之间必须要有空格隔开!

2.字符串内容比较 🔤

如果要比较的是文本内容,运算符就换一套了。它们也经常出现在 if 语句里,尤其是在双方括号 [[ ... ]] 中用起来更方便([[ ... ]] 对字符串处理更强大一些)。

  • === : 判断字符串内容是否完全相同 (在 [ ] 中建议用 =,在 [[ ]] 中两者都行,== 可能更符合其他语言习惯)
  • != : 判断字符串内容是否不同
  • < : 判断字符串按字典顺序是否小于 (在 [[ ... ]] 中使用)
  • > : 判断字符串按字典顺序是否大于 (在 [[ ... ]] 中使用)
  • -z 字符串变量 : 判断这个字符串是不是空的 (Zero length) 🤔
  • -n 字符串变量 : 判断这个字符串是不是非空的 (Non-zero length) ✅
#!/bin/bash
str_a="apple"
str_b="banana"
str_c="apple"
empty_str=""# 用 [[ ... ]] 来比较字符串
if [[ "$str_a" == "$str_c" ]]; then
echo "字符串 '$str_a' 和 '$str_c' 内容一样。"
fiif [[ "$str_a" != "$str_b" ]]; then
echo "字符串 '$str_a' 和 '$str_b' 内容不一样。"
fi# 字典顺序比较 (推荐在 [[ ]] 中用)
if [[ "$str_a" < "$str_b" ]]; then
echo "按字典顺序排,'$str_a' 在 '$str_b' 前面。" # 'a' 在 'b' 前面
fi# 检查字符串是不是空的
if [[ -z "$empty_str" ]]; then
echo "变量 empty_str 是空的。"
fi# 检查字符串是不是非空
if [[ -n "$str_a" ]]; then
echo "变量 str_a 不是空的。"
fi

几个关键点要记住:

  1. 比较字符串时,强烈推荐把变量用双引号 " 包起来 (像 "$variable")!这样就算变量是空的或者里面有空格,脚本也不会出错。
  2. 字符串比较用的 >< 是按字典顺序(通常是 ASCII 码顺序)比的,不是比数字大小!要比数字大小,请一定用 -gt, -lt 这些。
  3. 单方括号 [ ... ] 里,>< 有别的意思(是用来做重定向的),所以如果你想比较字符串的字典顺序,最好用双方括号 [[ ... ]]

三、逻辑运算符:组合拳 && || !

有时候一个条件不够用,我们需要判断好几个条件是不是同时满足,或者满足其中一个就行。这时候就轮到逻辑运算符出场了。

  • && (逻辑与 AND): 两边都要同时为真,结果才为真。像“芝麻开门”的口令,每个字都得对。
  • || (逻辑或 OR): 两边只要有一个为真,结果就为真。像有两个门,开哪个都行。
  • ! (逻辑非 NOT): 取反。把真的变假的,假的变真的。

它们最常出现在 if 语句的 [[ ... ]] 条件里,用来把前面说的关系运算(数字比较、字符串比较)组合起来。

#!/bin/bash
age=25
has_driving_license="yes" # 用非空字符串表示“有”echo "年龄: $age"
echo "是否有驾照: $has_driving_license"# 逻辑与 && : 必须年满 18 岁 并且 有驾照
if [[ $age -ge 18 && -n "$has_driving_license" ]]; then
echo "<font color='green'>满足开车条件!</font> 🚗"
fi# 逻辑或 || : 年龄小于 18 或者 没有驾照 (用 ! 取反来演示没有)
is_minor=$((age < 18)) # is_minor 会是 1 (true) 或 0 (false)
no_license=$([[ -z "$has_driving_license" ]]) # 检查是否为空
# 注意: Shell 中 0 代表 true (成功),非 0 代表 false (失败)
# 所以下面的判断条件稍微有点绕,我们换种更直观的写法# 更直观的 逻辑或 示例:
is_student="yes"
if [[ $age -lt 18 || "$is_student" == "yes" ]]; then
echo "<font color='orange'>是未成年人或是学生。</font>"
fi# 逻辑非 ! : 如果年龄 不是 25
if [[ ! $age -eq 25 ]]; then
echo "你的年龄不是 25 岁。"
else
echo "你的年龄正好是 25 岁。"
fi# 组合复杂条件 (在 [[ ]] 里,括号可以直接用,不用转义)
credits=120
has_graduated="true"
if [[ ($age -gt 22 && $credits -ge 120) || "$has_graduated" == "true" ]]; then
echo "已达到毕业标准或已毕业。"
fi

还有一种巧妙用法: &&|| 不光能用在 [[ ]] 里,还能直接连接两个命令,实现一种“短路”效果:

  • 命令1 && 命令2: 只有当 命令1 成功执行(退出码是 0)了,才会去执行 命令2。常用来保证一步成功了再做下一步。
  • 命令1 || 命令2: 只有当 命令1 失败了(退出码不是 0),才会去执行 命令2。常用来在出错时执行备用操作或报错。
# 例子:如果成功创建了新目录,就立马进去
mkdir my_cool_project && cd my_cool_project && echo "成功创建并进入项目目录!"# 例子:尝试 ping 一个可能不存在的主机,如果 ping 不通就提示一下
ping -c 1 a_non_existent_server || echo "<font color='red'>警告:无法连接到服务器!</font>"

四、练习题 🧠✍️

题目一:算术运算
❓ 用 Shell 脚本计算 100 除以 7余数。请使用推荐$(( )) 方法。

题目二:数值比较
❓ 写一个 if 条件判断,检查变量 file_count 的值是否大于等于 5

题目三:字符串比较
❓ 怎么判断一个名叫 user_input 的变量是不是空字符串?请写出使用 [[ ... ]] 的条件判断。

题目四:比较辨析
❓ 比较变量 num1=5num2=10,判断 num1 是否小于 num2,应该用 -lt 还是 <?为什么?

题目五:逻辑与
❓ 假设要判断变量 score 是否大于等于 60 并且 小于 90。请写出使用 &&[[ ... ]] 条件。

题目六:逻辑或与命令
❓ 如何用一行命令实现:尝试移动文件 old.logbackup/ 目录下,如果移动失败 (比如 backup/ 目录不存在),就打印一条消息 “移动失败,请检查目录”?


五、参考答案 ✅💡

答案一:

#!/bin/bash
dividend=100
divisor=7quotient=$((dividend / divisor))
remainder=$((dividend % divisor))echo "$dividend 除以 $divisor 的商是: $quotient" # 输出 14
echo "$dividend 除以 $divisor 的余数是: $remainder" # 输出 2

答案二:

file_count=8 # 假设变量已有值
if [ $file_count -ge 5 ]; then
echo "文件数量 ($file_count) 达到或超过 5 个。"
fi

或者使用双方括号(更推荐):

file_count=8
if [[ $file_count -ge 5 ]]; then
echo "文件数量 ($file_count) 达到或超过 5 个。"
fi

答案三:

user_input="" # 假设变量是空的
if [[ -z "$user_input" ]]; then
echo "用户输入是空的。"
fi

(别忘了用双引号把变量包起来是个好习惯!)

答案四:
应该使用 -lt (Less Than)。
原因: 因为 num1num2 存的是数字,我们要比较的是它们的数值大小,所以必须用数字比较运算符 (-eq, -ne, -gt, -lt, -ge, -le)。符号 < 是用来比较字符串字典顺序的(主要在 [[ ... ]] 里用),用它来比数字大小是不对的。

答案五:

score=75 # 假设变量已有值
if [[ $score -ge 60 && $score -lt 90 ]]; then
echo "分数 ($score) 在 60 到 90 之间 (含60, 不含90),良好。"
fi

答案六:
利用逻辑或 || 的短路特性:

mv old.log backup/ || echo "移动失败,请检查目录"

解释:如果 mv 命令成功执行(退出码为 0),|| 后面的 echo不会执行。只有当 mv 命令失败时(比如目录不存在,退出码非 0),|| 后面的 echo 命令才会执行。

相关文章:

三、shell脚本--运算符与表达式:让脚本学会“思考”

一、算术运算符&#xff1a;加减乘除取模 在我们写shell脚本时&#xff0c;做点基本的数学运算还是经常需要的。常用的算术运算符跟我们平时学的一样&#xff1a; : 加- : 减* : 乘 (小提示&#xff1a;有时候在某些命令里可能需要写成 \*)/ : 除 (在 Shell 里通常是取整数部分…...

c++ 指针参数传递的深层原理

指针参数传递的深层原理 理解为什么可以修改指针指向的内容但不能直接修改指针本身&#xff0c;需要深入理解指针在内存中的表示方式和函数参数传递机制。 1. 指针的内存表示 指针本质上是一个变量&#xff0c;它存储的是另一个变量的内存地址。在内存中&#xff1a; 假设有…...

【查看.ipynp 文件】

目录 如何打开 .ipynb 文件&#xff1f; 如果确实是 .ipynp 文件&#xff1a; .ipynp 并不是常见的 Jupyter Notebook 文件格式。通常&#xff0c;Jupyter Notebook 文件的扩展名是 .ipynb&#xff08;即 Interactive Python Notebook&#xff09;。如果你遇到的是 .ipynb 文…...

C++ 简单工厂模式详解

简单工厂模式&#xff08;Simple Factory Pattern&#xff09;是最简单的工厂模式&#xff0c;它不属于GoF 23种设计模式&#xff0c;但它是工厂方法模式和抽象工厂模式的基础。 概念解析 简单工厂模式的核心思想是&#xff1a; 将对象的创建逻辑集中在一个工厂类中 客户端不…...

ubuntu使用apt安装软件

1、使用apt list |grep jdk查看要安装的软件 此处以jdk为例 2、执行名称&#xff1a;安装指定版本的软件 sudo apt install openjdk-11-jdk...

TFT(薄膜晶体管)和LCD(液晶显示器)区别

TFT&#xff08;薄膜晶体管&#xff09;和LCD&#xff08;液晶显示器&#xff09;是显示技术中常见的术语&#xff0c;二者既有联系又有区别。以下是它们的核心区别和关系&#xff1a; 1. 基本概念 LCD&#xff08;液晶显示器&#xff09; LCD是一种利用液晶材料特性控制光线通…...

【文献阅读】中国湿地随着保护和修复的反弹

一、研究背景 滨海湿地是全球最具生态价值的生态系统之一&#xff0c;广泛分布在河口、潮间带、泻湖和盐沼等地带&#xff0c;在调节气候、水质净化、生物栖息以及防止海岸侵蚀等方面发挥着关键作用。然而&#xff0c;近年来滨海湿地正面临严峻威胁&#xff0c;全球估计约有50%…...

用Ensaio下载GIS数据

文章目录 简介重力场绘制 简介 Ensaio在葡萄牙语中是随笔的意思&#xff0c;是一个用于下载开源数据集的python库。其底层基于Pooch来下载和管理数据。 Ensaio可通过pip或者conda来安装 pip isntall ensaio conda install ensaio --channel conda-forge由于这个库功能较为单…...

【算法基础】递归算法 - JAVA

一、递归基础 1.1 什么是递归算法 递归算法是一种通过函数调用自身来解决问题的方法。简单来说&#xff0c;就是"自己调用自己"。递归将复杂问题分解为同类的更简单子问题&#xff0c;直到达到易于直接解决的基本情况。 1.2 递归的核心要素 递归算法由两个关键部…...

连续变量与离散变量的互信息法

1. 互信息法简介 互信息&#xff08;Mutual Information, MI&#xff09; 是一种衡量两个变量之间相互依赖程度的统计量&#xff0c;它来源于信息论。互信息可以用于评估特征与目标变量之间的相关性&#xff0c;无论这些变量是连续的还是离散的。互信息法是一种强大的特征选择…...

java_Lambda表达式

1、背景 lambda表达式是Java SE 8中一个重要的新特性。lambda表达式允许你通过表达式来代替功能接口。lambda表达式就和方法一样样&#xff0c;它提供了一个正常的参数列表和一个使用这些参数的主体&#xff08;body&#xff0c;可以是一个表达式和一个代码块&#xff09;。La…...

Python Cookbook-6.17 NuIl对象设计模式的实现

任务 你想减少代码中的条件声明&#xff0c;尤其是针对特殊情况的检查。 解决方案 一种常见的代表“这里什么也没有”的占位符是 None&#xff0c;但我们还可以定义一个类&#xff0c;其行为方式和这种占位符相似&#xff0c;而且效果更好: class Null(object):Null对象总是…...

Java接口全面教程:从入门到精通

目录 接口的基本概念 接口的特性 1. 访问修饰符 2. 接口中的常量 3. 接口中的方法 3.1 抽象方法&#xff08;传统用法&#xff09; 3.2 默认方法&#xff08;Java 8 引入&#xff09; 3.3 静态方法&#xff08;Java 8 引入&#xff09; 3.4 私有方法&#xff08;Java …...

Power Query精通指南3:数据库(查询折叠与数据隐私)、批量合并文件、自定义函数

文章目录 九、批量合并文件9.1 案例背景9.2 合并文件的标准流程9.3 示例&#xff1a;合并文件9.3.1 连接到文件夹9.3.1.1 连接到本地 / 网络文件夹9.3.1.2 连接到 SharePoint 文件夹9.3.1.3 连接到 OneDrive for Business9.3.1.4 连接到其他文件系统 9.3.2 筛选文件9.3.3 合并文…...

Python 学习

这里主要是为了记录我学习Python的过程&#xff0c;更多是使我规范书写Pyhton语言&#xff01; 1. 第一章 Python 定义&#xff1a;一种解释型的语言&#xff0c;区别于其他的高级语言&#xff0c;逐行翻译进行执行。 过程&#xff1a;首先编写编程语言&#xff0c;利用Pytho…...

生成式 AI 的优势

在科技飞速发展的今天,人工智能已经不再是一个遥不可及的概念,而是逐渐渗透到我们生活的方方面面。其中,生成式 AI 更是如同一颗璀璨的新星,在人工智能的浩瀚星空中闪耀着独特的光芒。它究竟有哪些令人瞩目的优势,又为何会成为我们这个时代无法忽视的存在呢? 生成式 AI …...

Hal库下备份寄存器

首先要确保有外部电源给VBAT供电 生成后应该会有这两个文件&#xff08;不知道为什么生成了好几次都没有&#xff0c;复制工程在试一次就有了&#xff09; 可以看到stm32f407有20个备份寄存器 读写函数 void HAL_RTCEx_BKUPWrite(RTC_HandleTypeDef *hrtc, uint32_t Backup…...

P1537 数字反转(升级版)详解

这个题目还是对于新手比较锻炼思维严谨性的&#xff0c;我认为是在我做过的一些题目中&#xff0c;此题算上等马 先看题目 我先说明我自己的思路&#xff0c;以及这个题目你需要特别注意的地方 1&#xff0c;数字反转&#xff0c;①可用<algorithm>库里面的reverse函数…...

operator 可以根据需要重载 == 运算符进行比较

要将 vector<AppInfo> 类型的 A 和 B 两个容器进行比较&#xff0c;并且当 B 中有 A 中没有的元素时&#xff0c;插入到数据库中&#xff0c;你可以通过以下步骤实现&#xff1a; 比较元素&#xff1a;遍历 vector<B>&#xff0c;检查每个元素是否在 vector<A&…...

网格不迷路:用 CSS 网格生成器打造完美布局

前言 你是否曾因写错 grid-template-areas 而捶键盘?是否在面对千层嵌套的复杂布局时,瞬间怀疑人生,甚至思考要不要转行去卖奶茶?别慌,CSS 网格生成器闪亮登场,像拼乐高一样,帮你轻松搭建网页结构,还能自动输出干净代码,堪称“前端界的乐高大师”。让我们放下枯燥的代…...

Go小技巧易错点100例(二十八)

本期分享&#xff1a; 1. runtime.Caller(1)获取调用者信息 2. for循环 select{}语法 正文&#xff1a; runtime.Caller(1)获取调用者信息 在 Go 语言中&#xff0c;runtime.Caller(1) 是 runtime 包提供的一个函数&#xff0c;用于获取当前 goroutine 的调用堆栈中的特定…...

Java变量简介

Java变量 -为什么需要变量? 一个程序就是一个世界 变量是程序的基本组成单位 不论是使用哪种高级程序语言编写程序,变量都是其程序的基本组成单位,比如: //变量有三个基本要素(类型+名称+值) class Test{public static void main(String [largs){int a=1;int b=3:b=89;Syst…...

Java快速上手之实验六

1. 编写ItemEventDemo.java&#xff0c;当选中或取消选中单选钮、复选钮和列表框时显示所选的结果。 2&#xff0e;编写GUIExample.java&#xff0c;当选中或取消选中单选钮、复选钮时在标签中显示相应结果。 import javax.swing.*; import java.awt.*; import java.awt.event.…...

【算法应用】基于灰狼算法优化深度信念网络回归预测(GWO-DBN)

目录 1.深度信念网络&#xff08;Deep Belief Networks, DBNs&#xff09;2.灰狼算法GWO原理3.结果展示4.参考文献5.代码获取6.读者交流 1.深度信念网络&#xff08;Deep Belief Networks, DBNs&#xff09; 深度信念网络&#xff08;Deep Belief Networks, DBNs&#xff09;是…...

基于Spring Boot实现STDIO通信的MCP Server与验证

STDIO 是一种基于标准输入输出(Standard Input/Output)的本地通信机制,旨在实现客户端与服务端之间的高效交互。 STDIO 是 MCP 协议支持的传输方式之一,通过操作系统的管道机制(stdin/stdout)进行数据传输,适用于客户端与服务端在同一台机器上的本地通信场景。 本篇基于…...

springboot基于推荐算法的景点推荐系统(源码+lw+部署文档+讲解),源码可白嫖!

摘要 本景点推荐系统采用B/S架构&#xff0c;数据库是MySQL&#xff0c;网站的搭建与开发采用了先进的Java进行编写&#xff0c;使用了协同过滤推荐算法和Spring Boot框架。该系统从两个对象&#xff1a;由管理员和用户来对系统进行设计构建。前台主要功能包括&#xff1a;用户…...

【LeetCode Hot100】栈篇

前言 本文用于整理LeetCode Hot100中题目解答&#xff0c;因题目比较简单且更多是为了面试快速写出正确思路&#xff0c;只做简单题意解读和一句话题解方便记忆。但代码会全部给出&#xff0c;方便大家整理代码思路。 20. 有效的括号 一句话题意 验证括号序列有效性。 一句话…...

IO模型和多路复用

一、IO模型的基础理解 什么是IO? IO全称是 Input/Output(输入/输出),在计算机科学里主要指程序与外部设备(硬盘、网络、用户终端等)进行数据交换的操作。首要特点是: IO通常很慢(从CPU和内存的视角看)经常需要等待外部设备响应1. 为什么要谈IO模型? 当一个程序需要…...

私人医生通过AI分析基因数据,是否有权提前告知癌症风险?

首席数据官高鹏律师团队编著 在精准医疗的浪潮中&#xff0c;私人医生借助AI技术解析基因数据、预判癌症风险&#xff0c;已成为高端医疗服务的“隐形标配”。然而&#xff0c;这一技术的光环之下&#xff0c;潜藏着法律与伦理的复杂博弈——医生是否有权基于AI的基因分析提前…...

day 11 超参数调整

一、内参与外参&#xff08;超参数&#xff09; 内参是模型为了适应训练数据而自动调整的&#xff0c;是模型内部与训练数据紧密相关的因素&#xff0c;不同的训练数据会导致模型学习到不同的参数值&#xff0c;这些参数在模型训练完成后就固定下来。 超参数是在模型训练前需…...

纯Java实现STDIO通信的MCP Server与客户端验证

在 MCP 协议中通过 STDIO(标准输入/输出)通信 是一种进程间通信(IPC)方式,服务器与客户端通过标准输入(stdin)和标准输出(stdout)交换数据。 关于STDIO 详细介绍以及如何基于Spring Boot项目实现 STDIO 的MCP服务器 以及如何调用和验证服务器可以参考: 基于Spring …...

Vue3学习笔记2——路由守卫

路由守卫 全局 router.beforeEach((to, from, next) > {})router.afterEach((to, from, next) > {}) 组件内守卫 beforeRouteEnter((to, from, next) > {})beforeRouteUpdate((to, from, next) > {})beforeRouteLeave((to, from, next) > {}) 路由独享 be…...

Three.js在vue中的使用(二)-加载、控制

在 Vue 中使用 Three.js 加载模型、控制视角、添加点击事件是构建 3D 场景的常见需求。下面是一个完整的示例&#xff0c;演示如何在 Vue 单文件组件中实现以下功能&#xff1a; 使用 GLTFLoader 加载 .glb/.gltf 模型添加 OrbitControls 控制视角&#xff08;旋转、缩放、平移…...

【堆】最大堆、最小堆以及GO语言的实现

堆是计算机科学中一种特别的完全二叉树结构&#xff0c;在优先队列、图算法和排序算法中有广泛应用。本文将从概念、原理和实现等方面详细介绍堆这一重要的数据结构。 1. 堆的基本概念 1.1 什么是堆&#xff1f; 堆&#xff08;Heap&#xff09;是一种特殊的完全二叉树&…...

动态规划之路劲问题3

解析题目&#xff1a; 跟之前路径题目大概一样&#xff0c;从左上角到右下角&#xff0c;每一步只能向下或者向右&#xff0c;而且每次走出来血量必须大于0&#xff08;注意这一点&#xff0c;否则容易导致每次出来可能小于0就可能错&#xff09; 算法分析&#xff1a; 状态…...

学习黑客网络安全法

在正式“开荒”各种黑客工具前&#xff0c;Day 4 的任务是给自己装上一副合规与伦理的“护身铠”。这一小时你将弄懂——做渗透想合法必须先拿授权、哪些法律条款碰不得、等保 2.0 与关基条例为何对企业像副“主线任务”&#xff1b;同时动手把这些要点制成一张“法律速查卡”&…...

节流 和 防抖的使用

节流&#xff08;Throttle&#xff09;是一种常用的性能优化技术&#xff0c;用于限制函数的执行频率&#xff0c;确保在一定时间内只执行一次。它常用于处理浏览器事件&#xff08;如滚动、窗口调整大小、鼠标移动等&#xff09;&#xff0c;以避免因事件触发过于频繁而导致的…...

关于项目中优化使用ConcurrentHashMap来存储锁对象

方案介绍 在开发用户创建私有空间功能时&#xff0c;我们的规则是一个用户最多只能创建一个私有空间。 在最初方案中&#xff0c;我是采用字符串常量池的方式存储锁对象useID。通过intern方法保证 同一用户ID的锁 唯一性。这一方案存在的问题是&#xff1a; 随着userId越来越…...

Java 网络安全新技术:构建面向未来的防御体系

一、Java 安全架构的演进与挑战 1.1 传统安全模型的局限性 Java 平台自 1995 年诞生以来&#xff0c;安全机制经历了从安全管理器&#xff08;Security Manager&#xff09;到 Java 平台模块系统&#xff08;JPMS&#xff09;的演进。早期的安全管理器通过沙箱模型限制不可信…...

【在Spring Boot中集成Redis】

在Spring Boot中集成Redis 依赖在application.yml中配置Redis服务地址创建Redis配置类缓存工具类使用 依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency&…...

昇腾的昇思MindSpore是什么?跟TensorFlow/PyTorch 等第三方框架有什么区别和联系?【浅谈版】

昇腾的昇思 MindSpore 是华为自主研发的全场景深度学习框架&#xff0c;旨在覆盖从科研到工业落地的全流程&#xff0c;支持云、边缘、手机等多种硬件场景的部署。它与 TensorFlow、PyTorch 等第三方框架既有相似性&#xff0c;也有明显差异。 一、昇思 MindSpore 的核心特点 全…...

MySQL进阶(三)

五、锁 1. 概述 锁是计算机协调多个进程或线程并发访问某一资源的机制&#xff08;避免争抢&#xff09;。 在数据库中&#xff0c;除传统的计算资源&#xff08;如 CPU、RAM、I/O 等&#xff09;的争用以外&#xff0c;数据也是一种供许多用户共享的资源。如何保证数据并发…...

Java面试趣事:从死循环到分段锁

互联网大厂Java开发岗终面现场 面试官&#xff08;推了推黑框眼镜&#xff09;&#xff1a;马小帅是吧&#xff1f;先说下HashMap扩容机制&#xff1f; 马小帅&#xff08;抓耳挠腮&#xff09;&#xff1a;这我知道&#xff01;默认初始容量16&#xff0c;默认负载因子0.75..…...

健康养生新主张

健康养生并非遥不可及的高深学问&#xff0c;摒弃中医理念&#xff0c;从生活细节入手&#xff0c;同样能实现身心的良好养护&#xff0c;开启活力满满的生活。​ 水是生命之源&#xff0c;科学饮水对养生意义重大。每天饮用 1500 - 2000 毫升的水&#xff0c;可维持身体正常的…...

合成复用原则(CRP)

非常好&#xff01;你已经学习了好几个设计原则&#xff0c;现在我们来讲解合成复用原则&#xff08;Composite Reuse Principle, CRP&#xff09;——它和继承是常被比较的一对“重用方式”。 &#x1f9e0; 一句话定义 合成复用原则&#xff08;CRP&#xff09;&#xff1a;尽…...

基于PyTorch的食物图像分类实战:从数据处理到模型训练

基于PyTorch的食物图像分类实战&#xff1a;从数据处理到模型训练 在深度学习领域&#xff0c;图像分类是一个经典且应用广泛的任务。无论是在电商平台的商品分类、医疗影像诊断&#xff0c;还是在农业作物识别等场景中&#xff0c;图像分类模型都发挥着重要作用。本文将以食物…...

在pycharm profession 2020.3将.py程序使用pyinstaller打包成exe

一、安装pyinstaller 在pycharm的项目的Terminal中运行pip3 install pyinstaller即可。 安装后在Terminal中输入pip3 list看一下是否成功 二、务必在在项目的Terminal中输入命令打包&#xff0c;命令如下&#xff1a; python3 -m PyInstaller --noconsole --onefile xxx.py …...

基于Springboot旅游网站系统【附源码】

基于Springboot旅游网站系统 效果如下&#xff1a; 系统登陆页面 系统主页面 景点信息推荐页面 路线详情页面 景点详情页面 确认下单页面 景点信息管理页面 旅游路线管理页面 研究背景 随着互联网技术普及与在线旅游消费习惯的深化&#xff0c;传统旅游服务模式面临效率低、…...

Linux操作系统从入门到实战(五)详细讲解Linux权限概念

Linux操作系统从入门到实战&#xff08;五&#xff09;详细讲解Linux权限概念 前言一、Linux中两种用户1.1 超级用户&#xff08;root&#xff09;1.2 普通用户1.3 切换用户命令 二、Linux权限管理2.1 文件访问者的分类&#xff1a;谁能访问文件&#xff1f;2.2 文件类型2.3 基…...

[方法论]软件工程中的设计模式:从理论到实践的深度解析

文章目录 软件工程中的设计模式&#xff1a;从理论到实践的深度解析引言&#xff1a;为什么需要设计模式&#xff1f;第一部分&#xff1a;设计模式的核心原则1. SOLID 原则&#xff08;面向对象设计的五大基石&#xff09;2. 其他关键思想 第二部分&#xff1a;创建型模式&…...