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

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

目录

接口的基本概念

接口的特性

1. 访问修饰符

2. 接口中的常量

3. 接口中的方法

3.1 抽象方法(传统用法)

3.2 默认方法(Java 8 引入)

3.3 静态方法(Java 8 引入)

3.4 私有方法(Java 9 引入)

接口的实现

接口继承

函数式接口与 Lambda 表达式

一、函数式接口

二、Lambda 表达式

三、Lambda 简化格式

四、Lambda 表达式的限制

五、简单示例

接口的演进历史

接口 vs 抽象类

接口的常见应用

1. 策略模式

2. 回调机制

接口设计最佳实践

接口在实际开发中的注意事项

总结


接口的基本概念

接口是一种特殊的抽象类型,它只定义规范而不提供实现。通过关键字 interface 声明:

// 最简单的接口定义
public interface MyInterface {// 接口内容
}

接口本质上是一种 "契约",定义了实现该接口的类必须提供的行为,但不规定这些行为如何实现。它解决了 Java 单继承限制的问题,使一个类可以 "实现" 多个接口,从而获得类似多重继承的能力。

接口的特性

1. 访问修饰符

问题:接口的访问修饰符是不是只能是 public

解答:接口本身可以是 public 或默认 (包级) 访问级别,但接口中声明的方法隐式地是 public 的。

// 正确 - public接口
public interface PublicInterface {void method();  // 隐式public abstract
}// 正确 - 默认访问级别接口(包级)
interface PackageLevelInterface {void method();  // 隐式public abstract
}

关于接口方法修饰符的说明:

在接口中定义方法时,可以有以下写法:

// 以下三种写法在接口中是等价的
void method1();                  // 隐式public abstract
public void method2();           // 显式public,隐式abstract
abstract void method3();         // 显式abstract,隐式public
public abstract void method4();  // 完全显式

这四种写法都是正确的,因为接口中的方法默认就是 public abstract 的。通常为了简洁,我们会使用第一种写法,省略修饰符。

注意: 接口中的方法不能使用 protected 修饰符,这在所有 Java 版本中都是不允许的。Java 9 只引入了 private 方法支持,但没有引入 protected 方法支持。

2. 接口中的常量

接口中声明的变量默认是 public static final 的常量:

public interface GameConstants {// 常量声明(隐式public static final)int MAX_PLAYERS = 4;String GAME_NAME = "我的世界";
}

这意味着:

  • public:可以被任何类访问
  • static:属于接口本身,而非实现类的实例
  • final:一旦赋值,不能被修改

使用示例:

// 直接通过接口名访问常量
System.out.println("最大玩家数: " + GameConstants.MAX_PLAYERS);
System.out.println("游戏名称: " + GameConstants.GAME_NAME);

为什么接口中的变量要是 final

  • 确保接口定义的标准值不被实现类修改
  • 提供统一的常量引用点
  • 保持接口作为 "契约" 的纯粹性

3. 接口中的方法

3.1 抽象方法(传统用法)

接口中最基本的方法类型是抽象方法:

public interface Animal {// 抽象方法(隐式public abstract)void eat();void sleep();
}

抽象方法特点:

  • 没有方法体,只有声明
  • 实现类必须提供具体实现
  • 隐式 public abstract

实现示例:

public class Cat implements Animal {// 必须实现所有抽象方法@Overridepublic void eat() {System.out.println("猫在吃鱼");}@Overridepublic void sleep() {System.out.println("猫在睡觉");}
}
3.2 默认方法(Java 8 引入)

什么是默认方法?
默认方法是 Java 8 引入的一种特性,允许接口中包含有具体实现的方法。这些方法使用 default 关键字标记,并提供一个默认实现。

public interface Pet {// 抽象方法 - 必须由实现类提供实现void feed();// 默认方法 - 已经有实现,实现类可以直接使用default void play() {System.out.println("宠物在玩耍");}
}

默认方法解决了一个重要问题:如何在不破坏现有代码的情况下向接口添加新方法。

通俗理解:
想象接口是一份工作合同,里面规定了员工必须完成的任务

  • 抽象方法就是 "你必须完成这项工作"
  • 默认方法就是 "如果你不知道怎么做,可以按照这个方法做"

默认方法如何使用?

// 实现类可以直接使用默认方法
public class Dog implements Pet {@Overridepublic void feed() {System.out.println("给狗喂食");}// 不必重写默认方法,但也可以选择重写@Overridepublic void play() {System.out.println("狗在玩飞盘");}
}// 使用时
Pet myPet = new Dog();
myPet.feed();  // 输出"给狗喂食"
myPet.play();  // 如果没重写,输出"宠物在玩耍";如果重写了,输出"狗在玩飞盘"

默认方法的执行优先级
当有多个接口都定义了相同的默认方法时:

interface Father {default void greeting() {System.out.println("父亲的问候");}
}interface Mother {default void greeting() {System.out.println("母亲的问候");}
}// 实现多个接口时,如果默认方法冲突,必须手动解决冲突
class Child implements Father, Mother {@Overridepublic void greeting() {// 指定使用父亲接口的默认方法Father.super.greeting();// 或者使用母亲接口的默认方法// Mother.super.greeting();// 或者完全自定义// System.out.println("孩子的问候");}
}

什么是菱形继承问题?
菱形继承问题可以通过一个简单的例子来理解:

    祖父母/    \父亲   母亲\    /孩子

在这个结构中,如果 "祖父母" 定义了一个方法,而 "父亲" 和 "母亲" 都提供了不同的实现,那么 "孩子" 应该继承哪个版本的方法呢?这就是菱形继承问题。

Java 通过接口的默认方法优先级规则解决了这个问题:

  • 类的方法优先于接口的默认方法
  • 子接口的默认方法优先于父接口的默认方法
  • 如果还有冲突,必须显式指定使用哪个接口的方法
3.3 静态方法(Java 8 引入)

什么是接口静态方法?
接口静态方法就是属于接口本身的方法,不需要通过实现类调用。

public interface Calculator {// 静态方法 - 直接通过接口名调用static int add(int a, int b) {return a + b;}static int subtract(int a, int b) {return a - b;}
}

静态方法的使用很简单:

// 直接通过接口名调用
int result = Calculator.add(5, 3);  // result = 8

静态方法的作用:

  • 提供与接口相关的工具方法
  • 不需要创建对象就能使用
  • 组织相关功能在一起
3.4 私有方法(Java 9 引入)

什么是接口私有方法?为什么需要它?

初学者常有疑问:接口的方法不是要被实现吗?私有方法不能被实现类访问,那有什么用?

答案是:私有方法不是给实现类用的,而是给接口自己的默认方法和静态方法用的。

下面是一个简单的例子,展示私有方法如何帮助减少代码重复:

public interface SimpleLogger {// 默认方法1default void logInfo(String message) {// 使用私有方法处理共同逻辑log("INFO", message);}// 默认方法2default void logError(String message) {// 复用相同的日志逻辑log("ERROR", message);}// 私有辅助方法 - 只在接口内部使用private void log(String level, String message) {System.out.println(level + ": " + message);}
}

通俗理解:

  • 私有方法就像接口的 "内部工具"
  • 它们只供接口自己的默认方法和静态方法使用
  • 实现类根本看不到这些私有方法,也不需要关心它们

有两种类型的私有方法:

  • 私有实例方法:只能被接口的默认方法调用
  • 私有静态方法:可以被接口的默认方法和静态方法调用
public interface FileProcessor {// 默认方法调用私有实例方法default byte[] readFile(String path) {validatePath(path);  // 调用私有实例方法return new byte[0]; // 简化示例}// 静态方法调用私有静态方法static String getFileExtension(String filename) {return extractExtension(filename);  // 调用私有静态方法}// 私有实例方法private void validatePath(String path) {if (path == null) {throw new IllegalArgumentException("Path cannot be null");}}// 私有静态方法private static String extractExtension(String filename) {int dotPos = filename.lastIndexOf('.');return dotPos > 0 ? filename.substring(dotPos + 1) : "";}
}

接口的实现

类通过 implements 关键字实现一个或多个接口:

// 实现单个接口
public class Rectangle implements Drawable {@Overridepublic void draw() {System.out.println("绘制长方形");}
}// 实现多个接口
public class Smartphone implements Phone, Camera, WebBrowser {@Overridepublic void makeCall(String number) {System.out.println("正在拨打: " + number);}@Overridepublic void takePhoto() {System.out.println("正在拍照");}@Overridepublic void browseWeb(String url) {System.out.println("正在浏览: " + url);}
}

实现类必须遵循以下规则:

  • 必须实现接口的所有抽象方法
  • 可以选择性地覆盖接口的默认方法
  • 不能覆盖接口的静态方法
  • 必须将抽象方法实现为 public

接口继承

接口可以通过 extends 关键字继承一个或多个其他接口:

// 基础接口
interface Animal {void eat();
}// 扩展接口
interface FlyingAnimal extends Animal {void fly();
}// 实现扩展接口的类必须实现所有方法
class Bird implements FlyingAnimal {@Overridepublic void eat() {System.out.println("鸟在吃虫子");}@Overridepublic void fly() {System.out.println("鸟在天空飞翔");}
}

接口继承的特点:

  • 子接口继承父接口的所有方法和常量
  • 子接口可以添加新的方法和常量
  • 子接口可以覆盖父接口的默认方法
  • 子接口不能移除父接口的方法

函数式接口与 Lambda 表达式

一、函数式接口

函数式接口是 仅包含一个抽象方法 的接口,它是 Lambda 表达式的 “宿主”,通过 Lambda 可简洁实现接口中的抽象方法。

  • 注解规范:推荐用 @FunctionalInterface 注解标记(非强制),用于在编译期检查接口是否符合函数式接口规范(确保只有一个抽象方法)。

    java

    @FunctionalInterface  
    interface MyComparator {  int compare(int a, int b); // 唯一抽象方法  
    }  
    
二、Lambda 表达式
  • 概念:Java 8 引入的特性,允许将 “行为”(一段代码)作为参数传递,直接表示函数式接口的实现,避免编写冗长的匿名内部类。
  • 核心作用:大幅简化代码,提升可读性,拥抱函数式编程风格,让代码更简洁、灵活。
三、Lambda 简化格式
  1. 参数类型省略
    小括号中的参数数据类型可省略。
    // 完整形式:(int a, int b) -> a - b  
    MyComparator comp = (a, b) -> a - b;  
    
  2. 单参数时省略小括号
    若参数只有一个,小括号可省略。
    interface Square {  int calculate(int num);  
    }  
    Square s = num -> num * num; // 单参数,省略小括号  
    
  3. 单行方法体省略大括号
    若方法体只有一行,可省略 return、分号和大括号。
    MyComparator comp = (a, b) -> a - b; // 隐含 return,省略大括号  
    
四、Lambda 表达式的限制
  1. 仅适配函数式接口:必须对应一个抽象方法的函数式接口,否则编译报错。
  2. 变量作用域限制:Lambda 内不能定义与外部同名的新变量,但可访问 final 或 “等效 final”(未被修改)的局部变量。
  3. 类型依赖上下文:Lambda 表达式的类型由所在的函数式接口决定,不能独立存在。
五、简单示例
import java.util.Arrays;  @FunctionalInterface  
interface MyComparator {  int compare(int a, int b);  
}  public class LambdaDemo {  public static void main(String[] args) {  // 使用 Lambda 实现函数式接口  MyComparator comp = (a, b) -> a - b;  int result = comp.compare(10, 5);  System.out.println("比较结果:" + result); // 输出:5  // 简单数组排序示例  Integer[] nums = {5, 3, 8};  Arrays.sort(nums, (x, y) -> x - y); // 升序排列  System.out.println("排序后数组:" + Arrays.toString(nums)); // 输出:[3, 5, 8]  }  
}  

通过上述规则,Lambda 表达式在函数式接口的支撑下,以极简方式实现行为定义,成为 Java 函数式编程的核心工具,让代码在简洁中迸发强大的表现力。

接口的演进历史

Java 版本新增特性详细说明
Java 1.0基本接口功能只支持常量和抽象方法
Java 8 (2014)默认方法、静态方法允许接口包含方法实现,支持 API 演化
Java 9 (2017)私有方法 (实例和静态)增强接口内部代码复用能力

接口 vs 抽象类

特性接口抽象类
多重继承支持(一个类可以实现多个接口)不支持(一个类只能继承一个抽象类)
构造器不允许允许(但不能直接实例化)
方法实现仅默认 / 静态 / 私有方法可有实现可以有抽象和非抽象方法
成员变量仅常量 (public static final)任何类型的字段
访问修饰符方法默认 public可以使用任何访问修饰符
状态不能包含状态(除了常量)可以包含状态(实例变量)
目的定义类型和行为契约提供共同基类和部分实现

接口的常见应用

1. 策略模式

通过接口定义不同的算法:

// 策略接口
interface SortStrategy {void sort(int[] array);
}// 具体策略实现
class QuickSort implements SortStrategy {@Overridepublic void sort(int[] array) {System.out.println("使用快速排序");// 排序实现...}
}class BubbleSort implements SortStrategy {@Overridepublic void sort(int[] array) {System.out.println("使用冒泡排序");// 排序实现...}
}// 使用
class ArrayProcessor {private SortStrategy strategy;public void setStrategy(SortStrategy strategy) {this.strategy = strategy;}public void sortArray(int[] array) {strategy.sort(array);}
}

2. 回调机制

使用接口实现回调:

// 回调接口
interface ClickListener {void onClick(String buttonName);
}// 使用回调
class Button {private String name;private ClickListener listener;public Button(String name) {this.name = name;}public void setListener(ClickListener listener) {this.listener = listener;}public void click() {// 触发回调if (listener != null) {listener.onClick(name);}}
}// 使用Lambda实现回调
Button submitButton = new Button("Submit");
submitButton.setListener(buttonName -> System.out.println(buttonName + " 被点击了"));
submitButton.click();  // 输出:Submit 被点击了

接口设计最佳实践

  1. 保持接口小而精确:一个接口应该只关注一个功能点
  2. 明确接口的责任:接口名应该能清楚表达其用途
// 好的接口命名
interface Printable { void print(); }
interface Comparable<T> { int compareTo(T other); }
  1. 使用默认方法扩展:添加新功能时考虑使用默认方法
interface List<E> {// 原有方法void add(E element);// 通过默认方法扩展功能default void addAll(E... elements) {for (E e : elements) {add(e);}}
}
  1. 避免过度使用接口:不要为每个类都创建接口,只在真正需要抽象时使用

接口在实际开发中的注意事项

  1. 接口变更:尽量避免在已发布的接口中添加非默认方法
  2. 文档完善:为接口方法提供清晰的文档,说明预期行为
/*** 表示可以发送消息的功能。*/
interface MessageSender {/*** 发送文本消息到指定接收者。* * @param recipient 消息接收者ID* @param content 消息内容,不能为null* @return 是否发送成功* @throws MessageException 如果发送过程中出错*/boolean send(String recipient, String content) throws MessageException;
}
  1. 合理使用默认实现:默认方法应提供合理的通用实现,不应依赖具体实现细节

总结

Java 接口是一种强大的抽象机制,随着 Java 语言的发展不断增强其功能:

  1. 基础特性
    • 定义抽象方法(必须由实现类实现)
    • 声明常量(隐式 public static final
    • 实现多重继承机制
  2. Java 8 增强
    • 默认方法(带实现的接口方法)
    • 静态方法(属于接口本身的方法)
    • 函数式接口(支持 Lambda 表达式)
  3. Java 9 增强
    • 私有方法(增强接口内部代码复用)

关键优势

  • 定义类型而非实现
  • 支持多重继承
  • 促进松散耦合
  • 简化系统演化

理解接口的这些特性和最佳实践,将帮助你写出更灵活、更易维护的 Java 代码。无论是初学者还是有经验的开发者,掌握接口都是提高 Java 编程能力的关键步骤。


参考资料:

  • Oracle Java 接口文档
  • Java 9 接口增强
  • Effective Java (Joshua Bloch)

相关文章:

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;创建型模式&…...

测试基础笔记第十八天

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、web自动化1.xpath定位1.属性定位2.属性与逻辑结合3.属性和层级结合 2.常见元素定位方法&#xff08;面试题&#xff09;3.常见元素定位失败原因4.cookie1.验证码…...

深度学习系统学习系列【2】之人工神经网络(ANN)

文章目录 说明人工神经网络概述基本单位&#xff08;神经元模型&#xff09;神经元基本模型线性模型与激活函数多层神经网络人工神经网络的注意内容 人工神经网络的阶段划分训练阶段输入、输出数据量化的设计权值向量W和偏置b的设计 预测阶段 人工神经网络核心算法梯度下降算法…...

《解锁Windows下GCC升级密码,开启高效编程新旅程》

《解锁Windows下GCC升级密码,开启高效编程新旅程》 为什么要升级 Windows 下的 GCC 版本? 在软件开发的动态领域中,GCC 作为一款卓越的编译器,在 Windows 环境下的升级有着重要意义,其影响深远且广泛。 从性能优化的角度来看,新版 GCC 往往在编译速度上有显著提升。随着…...

**Java面试大冒险:谢飞机的幽默与技术碰撞记**

互联网大厂Java求职者面试&#xff1a;一场严肃与搞笑交织的技术盛宴 场景&#xff1a; 互联网大厂面试间 人物&#xff1a; 面试官&#xff1a; 一位严肃的资深架构师&#xff0c;对技术要求严格。谢飞机&#xff1a; 一位搞笑的程序员&#xff0c;技术实力参差不齐。 第一…...

软件检测价格受多种因素影响,你了解多少?

软件检测价格受到多种因素的影响&#xff0c;这对企业来说至关重要&#xff0c;对开发者来说也至关重要&#xff0c;了解软件检测价格能够让企业和开发者更好地进行预算&#xff0c;能够让企业和开发者更好地进行决策。以下为你深入分析相关内容。 检测范围影响软件检测范围的…...

学习黑客风险Risk

一眼纵览 今天 Day 5 我们用 60 分钟打通「风险管理快闪副本」——先用漫画式视角速读两个国际标准&#xff08;NIST & ISO/IEC 27005&#xff09;&#xff0c;再把抽象概念变身为炫彩 Risk Heat Map&#xff0c;最后亲手填一张迷你 风险登记簿。学完你将能&#xff1a; 讲…...

scikit-learn在监督学习算法的应用

shiyonguyu大家好&#xff0c;我是我不是小upper&#xff01;最近行业大环境不是很好&#xff0c;有人苦恼别人都开始着手项目实战了&#xff0c;自己却还卡在 scikit-learn 的代码语法上&#xff0c;连简单的示例运行起来都磕磕绊绊。确实&#xff0c;对很多机器学习初学者来说…...

BG开发者日志505:项目总体情况

1、从2024年12月中旬启动&#xff0c;到4月底gameplay部分开发完毕&#xff0c;已经四个半月过去了。 其中大部分内容是3、4两个月中完成的&#xff0c;量产阶段。 预计6月初参加新品节&#xff0c;6月中旬发售&#xff08;比原计划7月中旬提前一个月&#xff09;。 --------…...

MySQL 空值处理函数对比:IFNULL、COALESCE 和 NULLIF

IFNULL、COALESCE 和 NULLIF这三个函数都是 MySQL 中处理 NULL 值的函数&#xff0c;但它们的功能和使用场景有所不同&#xff1a; 1. IFNULL(expr, fallback) 功能&#xff1a;两值处理&#xff0c;专为替换 NULL 设计 如果 expr 不是 NULL&#xff0c;返回 expr如果 expr …...

【2025年】MySQL面试题总结

文章目录 1. MySQL 支持哪些存储引擎&#xff1f;默认使⽤哪个&#xff1f;2. MyISAM 和 InnoDB 有什么区别&#xff1f;3. 事务的四大特性?4. 并发事务带来了哪些问题?5. 不可重复读和幻读有什么区别&#xff1f;6. MySQL 事务隔离级别&#xff1f;默认是什么级别&#xff1…...

Python 数据智能实战 (10):智能商品推荐 - LLM “猜你喜欢”

写在前面 —— 从协同过滤到语义理解:融合 LLM,打造更懂用户心意的个性化推荐 在之前的篇章里,我们已经见证了 LLM 在用户分群、购物篮分析、流失预测、内容生成等多个电商环节的赋能潜力。今天,我们将聚焦于电商平台的“心脏”之一,也是用户体验和商业转化的核心驱动力…...

2025年 蓝桥杯省赛 Python A 组题目

文章目录 A.偏蓝B.IPv6C.2025图形D.最大数字E.倒水F.拼好数G.登山H.原料采购 近期复盘一下 省赛的题目&#xff0c;正所谓知不足方能进步可以在洛谷找到比赛的题目&#xff0c;不过得注意由于python版本的问题&#xff0c;有些代码想要在洛谷上ac的话&#xff0c;需要对应调整代…...