java安全入门
文章目录
- java基础知识
- this变量
- 方法可变参数
- 构造方法
- 继承的关键字
- protected
- super
- 阻止继承
- 方法重载
- 向上转型和向下转型
- 多态
- 抽象
- 接口
- static静态字段
- default方法
- 包
- final
- 内部类
- java序列化与反序列化
- 反射
- urldns链
- 动态代理
- 类加载器(ClassLoader)
- 双亲委派模型
- Spring Boot 2
- 1.Spring Boot 2
- 2. Maven
- 特点
- 依赖管理
- 在 Spring Boot 2 中的具体例子:
- 自动版本仲裁
- 自动配好Tomcat
- **3.Tomcat 是什么?**
- **Tomcat 的主要功能**
- **在 Spring Boot 中的作用**
- 4.自动配好SpringMVC
- **Spring MVC 和 Tomcat 的关系**
- 配置生成对应的类
- 容器
- **容器的组件添加功能如何工作?**
- **组件添加的常见方式**
- **使用注解(最常见)**
- 0字节截断
跟随Y4的路线学习
https://github.com/Y4tacker/JavaSec
java基础知识
中途看到一个很好的网站
https://liaoxuefeng.com/books/java/quick-start/index.html
this变量
this 是一个变量,指向当前正在执行代码的那个对象。
class Person {String name;void setName(String name) {this.name = name; // this.name 是成员变量,name 是参数}
}
方法可变参数
可变参数用类型...
定义,可变参数相当于数组类型:
class Group {private String[] names;public void setNames(String... names) {this.names = names;}
}Group g = new Group();
g.setNames("Xiao Ming", "Xiao Hong", "Xiao Jun"); // 传入3个String
g.setNames("Xiao Ming", "Xiao Hong"); // 传入2个String
构造方法
如果既要能使用带参数的构造方法,又想保留不带参数的构造方法,那么只能把两个构造方法都定义出来:
public Person() {}public Person(String name, int age) {this.name = name;this.age = age;
}
将属性定义为private,外部无法直接访问,通过方法才可以访问,而idea有自动生成get方法和set方法的快捷键,将鼠标移动到类里,按下alt+insert。蛋疼的是新键盘没有insert…于是改成contrl+shift+G了
继承的关键字
protected
一个protected
字段和方法可以被其子类,以及子类的子类所访问
super
class Person {protected String name;protected int age;public Person(String name, int age) {this.name = name;this.age = age;}
}class Student extends Person {protected int score;public Student(String name, int age, int score) {this.score = score;}
}
运行上面的代码,会得到一个编译错误,大意是在Student
的构造方法中,无法调用Person
的构造方法。
这是因为在Java中,任何class
的构造方法,第一行语句必须是调用父类的构造方法。如果没有明确地调用父类的构造方法,编译器会帮我们自动加一句super();
,所以,Student
类的构造方法实际上是这样:
class Student extends Person {protected int score;public Student(String name, int age, int score) {super(); // 自动调用父类的构造方法this.score = score;}
}
但是,Person
类并没有无参数的构造方法,因此,编译失败。
解决方法是调用Person
类存在的某个构造方法。例如:
class Student extends Person {protected int score;public Student(String name, int age, int score) {super(name, age); // 调用父类的构造方法Person(String, int)this.score = score;}
}
阻止继承
从Java 15开始,允许使用sealed
修饰class,并通过permits
明确写出能够从该class继承的子类名称。
例如,定义一个Shape
类:
public sealed class Shape permits Rect, Circle, Triangle {...
}
方法重载
直接写方法就行,要求参数个数或位置不能完全一致
向上转型和向下转型
向上转型是可以的,即子类可以转为父类,但向下转型是不允许的,在类型转换时,父类->子类无法凭空变出多的那部分功能。
Person p = new Student();
可以理解为将新建的Student实例转化为person类,可以对person类进行相关的操作
为了避免向下转型出错,Java提供了instanceof
操作符,可以先判断一个实例究竟是不是某种类型:
Person p = new Person();
System.out.println(p instanceof Person); // true
System.out.println(p instanceof Student); // false
instanceof判断一个实例是否是指定类或指定类的子类,从Java 14开始,判断instanceof
后,可以直接转型为指定变量,避免再次强制转型。
在逻辑关系不适合使用继承时可以使用组合,类可以拥有其他类的实例,嵌套之后可以拿到其他类的方法和属性
class Student extends Person {protected Book book;protected int score;
}
多态
Override(重写)和Overload(重载)是两个与方法相关的概念
在 Java 中,方法签名由 方法名 和 参数列表(包括参数的类型、数量和顺序)组成。
Override 发生在子类中,当子类重新定义(重写)父类中已有的方法时,称为重写。重写的目的是让子类提供自己的方法实现,覆盖父类的实现。条件:
-
方法签名(方法名 + 参数列表)必须与父类中的方法完全相同。
-
返回类型必须相同(或子类方法返回类型是父类方法返回类型的子类,称为协变返回类型)。
-
访问修饰符不能比父类更严格(例如,父类是 public,子类不能是 protected 或 private)。
-
子类方法抛出的异常不能比父类方法抛出的异常范围更广。
-
通常使用 @Override 注解来明确表示这是一个重写方法,防止错误。
Overload 发生在同一个类中,当定义多个方法名相同但参数列表不同的方法时,称为方法重载。重载方法是独立的新方法,互不干扰。
条件:
- 方法名必须相同。
- 参数列表必须不同(参数数量或参数类型不同)。
- 返回类型、访问修饰符、异常声明可以不同,但这些不影响重载的判断。
多态的特性就是,运行期才能动态决定调用的子类方法。对某个类型调用某个方法,执行的实际方法可能是某个子类的覆写方法。
抽象
使用abstract
修饰的类就是抽象类。抽象类无法实例化
接口
如果抽象类所有方法都是抽象方法,就可以把该类改写为接口
interface Person {void run();String getName();
}
接口定义的所有方法默认都是public abstract
的,所以这两个修饰符写不写效果都一样。接口不能定义实例字段
static静态字段
特性 | 实例字段 | 静态字段 |
---|---|---|
修饰符 | 无static | 使用static |
所属 | 属于对象 | 属于类 |
内存分配 | 每个对象一份,存储在堆中 | 类加载时分配,存储在方法区 |
访问方式 | 通过对象实例(如obj.field) | 通过类名或对象(如Class.field) |
生命周期 | 与对象一致 | 与类的生命周期一致 |
static修饰的属性可以直接通过类名访问,修改会影响到所有用到该属性的实例,因为所有实例都会共享该字段
default方法
定义:在接口中使用default关键字修饰的方法,提供了方法的具体实现,而非抽象方法。
向接口添加default方法不会破坏现有实现类的代码,因为它们自动继承默认实现。可以用 @Override重写
包
包没有父子关系。java.util和java.util.zip是不同的包,两者没有任何继承关系。
查找class的顺序,先查当前package,再查import的包,最后查java.lang包
final
final修饰class可以阻止被继承
final修饰method可以阻止被子类覆写
final修饰局部变量可以阻止被重新赋值
package abc;public class Hello {protected void hi(final int t) {t = 1; // error!}
}
内部类
定义在一个类内部的类,要实例化一个内部类,首先需要实例化它的外部类
Outer.Inner inner = outer.new Inner();
内部类除了可以引用外部类实例,还可以修改外部类的private字段
匿名类(Anonymous Class)是:Java 中一种没有显式名称的类,通常用于一次性使用的场景
定义的时候就{}加入类体,new后一般跟父类名或接口名
interface MyInterface {void doSomething();
}public class Test {public static void main(String[] args) {// 匿名类实现 MyInterfaceMyInterface obj = new MyInterface() {@Overridepublic void doSomething() {System.out.println("Doing something");}};obj.doSomething();}
}
静态内部类:static
修饰的内部类和Inner Class有很大的不同,它不再依附于Outer
的实例,而是一个完全独立的类,因此无法引用Outer.this
,但它可以访问Outer
的private
静态字段和静态方法。如果把StaticNested
移到Outer
之外,就失去了访问private
的权限。
java序列化与反序列化
序列化的类必须实现Serializable接口,实例可以序列化,类不可以,所以类中的static修饰的成员变量也不可以,transient标记的变量同样不可以反序列化
可以重写writeObject和readObject方法来自定义序列化和反序列化
安全问题的产生:只要反序列化数据,重写的readObject方法肯定就会自动执行
- 入口类的readObject方法里本身就存在危险方法
- 入口类参数中含有其他可控类,该类有危险方法
- 入口类参数中包含可控类,该类继续调用其他类
反射
可以通过反射的机制修改某些成员的属性
获取对象的类
public class ReflectionTest {public static void main(String[] args) {Person p=new Person("abc",20);Class c=p.getClass();//反射就是操作Class}
}
从原型Class实例化对象(无参构造和有参构造)
//无参构造方法
Class c=p.getClass();
c.newInstance();
//有参构造方法
Constructor tmp=c.getConstructor(String.class,int.class);
Person person2=(Person) tmp.newInstance("cc",10);
获取类里面属性
c.getField(p.name);
c.getFields();
c.getDeclaredFields();//获取到所有修饰符修饰的属性
修改private成员属性
Field age=c.getDeclaredField("age");
age.setAccessible(true);
age.set(person2,21);
System.out.println(person2);
访问类里面方法
Method[] m=c.getDeclaredMethods();
for(Method m1:m){System.out.println(m1);
}
调用类里面方法
Method m=c.getMethod("act1");
m.invoke(person2);//如果函数需要接收参数
Method m=c.getMethod("act1",String.class);
m.invoke(person2,"aaa");//私有方法访问与私有属性一样
urldns链
没错,来到了入门必见的一条链子
这条链子虽然简单,但是对我这样的小白来说,一下子有点想不明白hashmap的反序列化为什么会跟url类产生关系,ai的过程中突然顿悟了,hashmap在反序列化时是不是会调用hashcode()方法计算键的哈希值(后面会跟这条链子),而如果这个键是url类呢?url类有自己重写的hashcode方法,所以到这一步它会调用自己的hashcode方法,它自己的方法中会对域名发起一次解析请求,从而留下记录。
先跟一下hashmap的实现
先进readObject方法
再进最下面的hash方法
发现调用了hashcode方法计算key,也就是计算url,那么到这里就可以知道如果传入的类是url类,那么就会在反序列化时调用url类自己的hashcode方法了,那么它自己的hashcode方法又是什么样的呢。
进入url类,找到hashcode方法
发现当hashcode==-1时(应该是一个默认值),会调用handle类的hashcode方法,跟进handle类
继续跟进
发现在URLStreamHandler类的hashcode方法中,调用了getHostAddress方法,所以会对当前url进行一次解析
再来一个简单的序列化反序列化验证一手
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Scanner;public class Hello {public static void main(String[] args) throws Exception {HashMap<URL,Integer> h=new HashMap<URL,Integer>();URL url=new URL("http://zf8tay.dnslog.cn");h.put(url,20);// 序列化到文件FileOutputStream fos = new FileOutputStream("exploit.ser");ObjectOutputStream oos = new ObjectOutputStream(fos);oos.writeObject(h);oos.close();// 反序列化(假设目标系统执行)FileInputStream fis = new FileInputStream("exploit.ser");ObjectInputStream ois = new ObjectInputStream(fis);ois.readObject(); // 反序列化时触发 URL 的 hashCode()ois.close();}}
这个时候发现有两条记录,这是为什么呢?
跟进put方法,发现同样会调用hash方法,从而调用url类的hashcode方法,所以在序列化之前就会发起解析请求,想要阻止也很简单,在put前通过反射修改hashcode的值不是-1,put后再改回来即可
动态代理
代理就是加入一个代理类,即可以用原来类的方法,又可以自己加入方法,避免了直接对原生类的修改。
静态代理就是每一次调用方法都把底层逻辑写上,而如果很多方法的调用是相似的,就可以使用动态代理简化过程。不过要注意动态代理只能用于接口类
先写一个接口和接口的实现
interface Myservice{void sayhello(String name);
}
class Myserviceimp implements Myservice{@Overridepublic void sayhello(String name){System.out.println("hello,"+name);}
}
动态代理的InvocationHandler,invoke方法就像readObject方法一样,会在动态代理时自动执行
class Myhandle implements InvocationHandler{private Object target;public Myhandle(){}public Myhandle(Object o){this.target=o;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable{Object res=method.invoke(target,args);return res;}
}
主函数测试
public class DynamicProxyTest {public static void main(String[] args) {
// 创建真实对象MyService realService = new MyServiceImpl();// 创建动态代理MyService proxyService = (MyService) Proxy.newProxyInstance(MyService.class.getClassLoader(),new Class<?>[]{MyService.class},new MyInvocationHandler(realService));// 调用代理对象的方法proxyService.sayHello("Alice");}
}
类加载器(ClassLoader)
首先得知道什么是类加载器
Java的类加载器(ClassLoader)就像一个“搬运工”,负责把编译好的.class文件(字节码)加载到JVM(Java虚拟机)中,让程序能用。简单来说,它的工作是找到类文件、读进来、然后交给JVM处理。
它先去找到类文件,然后把类文件转换为字节流,然后JVM把这些字节流转换为可执行的类对象。java有几种类加载器
-
Bootstrap ClassLoader:最顶层,加载Java核心库(比如java.lang.String)。
-
Extension ClassLoader:加载扩展库。
-
Application ClassLoader:加载你自己写的程序的类。
在类初始化时会执行静态代码块,类实例化时会执行构造代码块和无参构造函数
动态加载类方法Class.forname可以自行选择是否初始化
双亲委派模型
听着高大上,其实就是加载类时,先试着让上级(父加载器)加载,干不了自己再干,比如Object类,所有的类都会向上让Bootstrap ClassLoader来加载这个类,所以无论在哪里调用这个类都是一样的,避免了冲突与混乱。
- 动态性:可以动态加载类,比如从网络下载个类直接用。利用URLClassLoader类
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;public class loader {public static void main(String[] args) throws MalformedURLException, ClassNotFoundException, InstantiationException, IllegalAccessException {URLClassLoader u=new URLClassLoader(new URL[]{new URL("file://F:\\web\\idea&vs脚本\\")});Class<?> c=u.loadClass("test");c.newInstance();}
}
同时,我们在test.java类的static区里可以加入方法,验证类在初始化时会自动执行静态代码块
public class test {static {System.out.println("已执行静态代码块");}
}
注意test.java要先编译为test.class文件
Spring Boot 2
1.Spring Boot 2
Spring Boot 2 是基于 Spring 框架 的一个开源 Java 开发框架,旨在简化企业级应用的开发。它通过提供“开箱即用”的配置、自动配置和嵌入式服务器,减少了开发者手动配置的工作量。Spring Boot 2 是 Spring Boot 的第二个主要版本(发布于 2018 年)
2. Maven
Maven 是一个广泛使用的 构建自动化工具,主要用于 Java 项目管理。它通过一个中央配置文件(pom.xml,Project Object Model)来管理项目的依赖、构建、测试和部署流程。Maven 简化了依赖管理和构建过程,避免了手动下载 JAR 文件的麻烦。
此后可以通过maven下载依赖和进行相关测试等操作,后续把项目打成jar包,直接在目标服务器执行即可。
myapp/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/example/Application.java
│ │ ├── resources/
│ │ │ └── application.properties
│ ├── test/
│ │ └── java/
├── pom.xml
├── target/ # 编译和打包输出
特点
依赖管理
父项目是一个用来管理和组织其他项目的“模板”或“蓝图”项目,通常以一个 Maven 或 Gradle 配置文件(比如 pom.xml)的形式存在。在 Spring Boot 中,父项目主要用来统一管理依赖版本、配置和构建规则,让子项目(实际的开发项目)可以直接“继承”这些设置,简化开发。
通俗点说,父项目就像一个“家里的管家”,它帮你把常用的工具、规则和资源(比如依赖库的版本、编译方式等)都整理好,写在一本“家规”里。你的具体项目(子项目)只要认这个“管家”为“家长”,就能直接用它准备好的东西,不用自己从头配置。
在 Spring Boot 2 中的具体例子:
Spring Boot 提供了一个官方的父项目,叫 spring-boot-starter-parent。它的 pom.xml 文件里定义了:
- 一堆常用依赖(比如 Spring 框架、测试库、日志库等)的推荐版本。
- 项目构建的默认配置(比如 Java 版本、Maven 插件等)。
- 一些通用的属性(比如编码格式)。
你在子项目的 pom.xml 里通过以下方式“继承”这个父项目:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.18</version> <!-- 假设用这个版本 --> </parent>
自动版本仲裁
“自动版本仲裁”指的是:当你使用 Spring Boot 的父项目(比如 spring-boot-starter-parent)或依赖管理工具(比如 spring-boot-dependencies)时,Spring Boot 会帮你“自动挑选”一些常用依赖的版本号。你在子项目的 pom.xml 文件里添加这些依赖时,不需要手动写版本号,因为父项目已经预先定义好了这些依赖的推荐版本。
那些不在 Spring Boot 父项目或 spring-boot-dependencies 预定义列表中的依赖。因为 Spring Boot 不知道这些依赖的推荐版本,所以你需要手动指定版本号。
自动配好Tomcat
3.Tomcat 是什么?
Apache Tomcat 是一个开源的 Web 服务器和 Servlet 容器,主要用于运行 Java 开发的 Web 应用。它由 Apache 软件基金会维护,是 Java 生态中最常用的服务器之一。
通俗解释:Tomcat 就像一个“餐厅服务员”,专门负责接收客户的请求(比如用户在浏览器访问你的网站),然后把请求交给你的 Java 程序(比如 Spring Boot 应用)处理,再把处理结果(网页、数据)送回给客户。
Tomcat 的主要功能
- 处理 HTTP 请求:接收用户通过浏览器发送的请求(比如 GET、POST),并返回响应(网页、JSON 数据等)。
- 运行 Servlet 和 JSP:支持 Java 的 Servlet(处理动态请求的 Java 程序)和 JSP(Java 服务器页面)技术,让开发者可以构建动态网站。
- 嵌入式或独立运行
- 独立运行:可以单独安装 Tomcat 作为一个服务器,把你的应用(WAR 文件)部署上去。
- 嵌入式运行:Spring Boot 把 Tomcat 打包到应用里,运行项目时 Tomcat 直接启动,省去部署步骤。
在 Spring Boot 中的作用
-
Spring Boot 默认把 Tomcat 作为内置 Web 服务器,包含在 spring-boot-starter-web 依赖中。
-
你写好 Spring Boot 应用(比如 REST API 或网页),运行 main 方法,Tomcat 就会启动,监听 HTTP 请求(默认端口 8080)。
-
你可以用浏览器或工具(比如 Postman)访问 http://localhost:8080,Tomcat 会把请求交给你的代码处理。
4.自动配好SpringMVC
Spring MVC 是 Spring 框架的一个模块,全称是 Spring Model-View-Controller,用于构建基于 Java 的 Web 应用程序。它是一个基于 MVC 设计模式的框架,帮助开发者以清晰的方式组织和开发 Web 项目。
MVC 模式:
- Model(模型):表示数据和业务逻辑,比如数据库中的用户信息或计算结果。
- View(视图):用户看到的内容,比如网页、JSON 响应。
- Controller(控制器):接收用户请求,协调 Model 和 View,决定“做什么”和“返回什么”。
Spring MVC 帮你把这三部分组织好,让开发 Web 应用更简单。
Spring MVC 和 Tomcat 的关系
-
Tomcat:是 Web 服务器,负责接收 HTTP 请求和发送响应,像“快递员”。
-
Spring MVC:是 Web 框架,运行在 Tomcat 里,负责处理请求的逻辑,像“餐厅服务团队”。
-
Spring Boot 把两者结合,Tomcat 作为嵌入式服务器,Spring MVC 作为请求处理核心,开发者只管写业务代码。
配置生成对应的类
默认配置:Spring Boot 像个贴心的管家,给你准备了一堆默认设置(比如 Tomcat 端口、文件上传大小),存在各种 Properties 类里(比如 MultipartProperties)。
自定义配置:你觉得默认值不合适,就在 application.properties 里写自己的值(比如改文件上传大小为 10MB)。
绑定到类:Spring Boot 看到你的配置文件,把值“贴”到对应的 Properties 类上(比如 MultipartProperties 的 maxFileSize 变成 10MB)。
创建对象:Spring Boot 把这个配置好的 Properties 类变成一个对象(Bean),放进 Spring 的“工具箱”(IOC 容器),程序随时可以拿来用。
容器
在 Spring Boot(或更广义的 Spring 框架)中,容器指的是 Spring 的 IOC 容器(Inversion of Control Container,控制反转容器),也叫 ApplicationContext。它是一个核心机制,负责管理应用程序中的对象(称为 Bean),包括创建、配置、组装和生命周期管理。
容器就像一个“智能管家”或“工具箱”,专门负责存放和管理你的程序里用到的各种“工具”(对象/Bean)。这些工具可能是你的业务逻辑类、配置类(如 MultipartProperties)、数据库连接等。容器不仅保管这些工具,还会自动帮你把它们组装好、配置好,并在需要时拿出来用。
Spring Boot 基于 Spring 框架,使用的容器是 ApplicationContext(具体实现如 AnnotationConfigApplicationContext)。
当你启动 Spring Boot 应用(运行 main 方法),Spring Boot 会自动创建一个容器。
容器会扫描你的代码(比如标有 @Component、@Service、@Controller 的类)和配置(比如 application.properties),把需要的对象创建并放进去。
容器的组件添加功能如何工作?
Spring 容器通过以下步骤将组件(Bean)添加到自身:
-
扫描代码
- 容器启动时,会扫描项目中的类,寻找标有特定注解的类(比如 @Component、@Controller、@Service、@Repository)或通过配置指定的类。
- Spring Boot 默认扫描主类(带 @SpringBootApplication 的类)所在包及其子包。
-
识别组件
- 容器识别哪些类需要变成 Bean。通常通过注解(如 @Component)或 XML/Java 配置指定。
- 比如,标有 @Controller 的类会被识别为 Web 控制器,标有 @Service 的类会被识别为业务逻辑组件。
-
创建 Bean
- 容器为每个识别到的组件创建对象(Bean),并根据需要配置它的属性(比如通过配置文件或依赖注入)。
- 比如,MultipartProperties 类会被创建为一个 Bean,配置文件中的 spring.servlet.multipart.max-file-size 会绑定到它的字段。
-
依赖注入
- 如果一个 Bean 需要依赖其他 Bean(比如 Controller 需要 Service),容器会自动把依赖的 Bean 注入。
- 比如,用 @Autowired 注解标记的字段,容器会找到对应的 Bean 填充。
-
存储到容器
- 创建好的 Bean 会被存到容器中,容器给每个 Bean 分配一个名字(通常是类名首字母小写),程序可以通过名字或类型获取 Bean。
-
管理生命周期
:
- 容器不仅负责添加组件,还管理 Bean 的生命周期(创建、初始化、使用、销毁)。
组件添加的常见方式
Spring 提供了多种方式让类被容器识别并添加为 Bean。以下是主要的添加方式,配以通俗解释:
使用注解(最常见)
Spring 提供了一系列注解,标记在类上后,容器会自动识别并创建 Bean。
- 常用注解
- @Component:通用组件,表示这个类需要被容器管理。
- @Controller / @RestController:用于 Web 控制器,处理 HTTP 请求。
- @Service:用于业务逻辑层。
- @Repository:用于数据访问层(比如数据库操作)。
- @Configuration:用于定义配置类,里面可以声明更多的 Bean。
0字节截断
在JDK7u40后这个得已修复,简单来说这个00截断其实就是因为Java对文件系统部分的实现是用C语言做的处理,C语言中对字符串来说都认为遇到0字节\0
就是字符串末尾,因此造成了这个问题。
\0 是 C 语言中表示 空字符(null character)的写法,对应 ASCII 码值为 0 的字符。在 Java 中,它等价于 Unicode 字符 \u0000。
相关文章:
java安全入门
文章目录 java基础知识this变量方法可变参数构造方法继承的关键字protected super阻止继承方法重载向上转型和向下转型多态抽象接口static静态字段default方法 包final内部类 java序列化与反序列化反射urldns链动态代理类加载器(ClassLoader)双亲委派模型…...
【开源深度解析】从零打造AI暗棋对战系统:Python实现中国象棋暗棋全攻略
🎲【开源深度解析】从零打造AI暗棋对战系统:Python实现中国象棋暗棋全攻略 🌈 个人主页:创客白泽 - CSDN博客 🔥 系列专栏:🐍《Python开源项目实战》 💡 热爱不止于代码,…...
UE5 Daz头发转Blender曲线再导出ABC成为Groom
先安装Daz to Blender Import插件 【神器】 --DAZ一键导入blender插件的详细安装和使用,自带骨骼绑定和控制器,多姿势动画,Importer桥接插件_哔哩哔哩_bilibili 然后安装DAZHairConverter插件 一分钟将DAZ头发转化成Blender粒子毛发_哔哩哔…...
【Java学习】反射
目录 反射类 一、泛型参数 二、反射类类型 三、实例化 1.实例化材料 2.结构信息可使用化 四、使用 1.Class —类完整结构信息 1.1Class<类>实例化 1.2Class<类>实例获取 1.2.1Class类静态获取: 1.2.2信息类静态获取 1.2.3信息类非静态获取 …...
SQLite数据类型
目录 1 SQLite的类型概述 1.1 存储类(Storage Classes) 1.2 类型亲和性(Type Affinity) 2 类型亲和性分配规则 3 数据类型详细说明 3.1 INTEGER类型 3.2 REAL类型 3.3 TEXT类型 3.4 BLOB类型 3.5 NULL类型 3.6 NUMERI…...
Django异步任务处理方式总结
在 Django 中实现异步任务处理是优化性能和用户体验的关键。以下是几种常见的异步任务处理方式及详细说明: 1. Celery(最主流方案) 适用场景:需要可靠、分布式、复杂任务队列的项目(如定时任务、重试机制、多节点部署…...
AI技术下研发体系重构
导语: 人工智能技术已发展70余年,经历了从逻辑符号主义向数据驱动范式的转变,目前正处于向多模态、通用化以及伦理化方向演化的阶段。在接下来的五年内,人工智能技术的商业化应用预计将迎来关键性的转变。大模型技术的突破、多模…...
UE5 使用插槽和物理约束对角色新增的饰品添加物理效果
这是一条项链,分为链部分和吊坠部分 新增物理碰撞资产,链部分在前面(作为固定),吊坠部分在后面(作为物理模拟) 链部分的Physics设置 连接部分的设置 吊坠部分 添加物理约束,在Constraint里面添加角色名和饰品名 在约束里面可以对特定骨骼约束,这里需要把链部分约束...
邂逅蓝耘元生代:ComfyUI 工作流与服务器虚拟化的诗意交织
往期推荐: 探秘蓝耘元生代:ComfyUI 工作流创建与网络安全的奇妙羁绊-CSDN博客 工作流 x 深度学习:揭秘蓝耘元生代如何用 ComfyUI 玩转 AI 开发-CSDN博客 探索元生代:ComfyUI 工作流与计算机视觉的奇妙邂逅-CSDN博客 解锁元生代&a…...
【Elasticsearch】在kibana中能获取已创建的api keys吗?
在 Kibana 中,目前没有直接的界面功能可以列出或查看已创建的 API 密钥(API keys)。API 密钥的管理和查看主要通过 Elasticsearch 的 REST API 来完成,而不是通过 Kibana 的管理界面。 在 Kibana 中使用 Dev Tools 查看 API 密钥…...
[论文阅读]Deep Cross Network for Ad Click Predictions
摘要 特征工程是许多预测模型成功的关键。然而,这个过程是困难的,甚至需要手动特征工程或穷举搜索。DNN能够自动学习特征交互;然而,它们隐式地生成所有的交互,并且不一定有效地学习所有类型的交叉特征。在本文中&…...
薪技术|0到1学会性能测试第45课-apache调优技术
前面的推文我们掌握了apache监控技术,今天我们继续来看下apache调优技术,究竟是怎么做性能调优???后续文章都会系统分享干货,带大家从0到1学会性能测试。 Apache调优技术 Apache最近的版本是2.2版,Apache2.2是一个多用途的web服务器,其设计在灵活性、可移植性和性能中…...
Linux之基础开发工具二(makefile,git,gdb)
目录 一、自动化构建-make/makefile 1.1、背景 1.2、基本使用 1.3、推导过程 1.4、语法拓展 二、进度条小程序 2.1、回车与换行 2.2、行缓冲区 2.3、练手-倒计时程序 2.4、进度条程序 三、版本控制器-Git 3.1、版本控制器 3.2、gitee的使用 3.2.1、如何创建仓库 …...
cesium之自定义地图与地图叠加
在appvue中,cesium支持更换不同的地图资源,代码如下 <template><div id"cesiumContainer" ref"cesiumContainer"></div> </template><script setup> import * as Cesium from cesium; import "./Widgets/widgets.css&…...
链表结构深度解析:从单向无头到双向循环的实现全指南
上篇博客实现动态顺序表时,我们会发现它存在许多弊端,如: • 中间/头部的插⼊删除,时间复杂度为O(N) • 增容需要申请新空间,拷⻉数据,释放旧空间。会有不⼩的消耗。 • 增容⼀般是呈2倍的增⻓,…...
Apache Velocity代码生成简要介绍
Apache Velocity 概述 Apache Velocity 是一个基于 Java 的模板引擎,它允许将 Java 代码与 HTML、XML 或其他文本格式分离,实现视图与数据的解耦。在 Web 开发中,Velocity 常用于生成动态网页内容;在其他场景下,也可用…...
阿里云前端Nginx部署完,用ip地址访问却总访问不到,为什么?检查安全组是否设置u为Http(80)!
根据你的描述,Ping测试显示数据包无丢失但无法通过公网IP访问服务,说明网络基础层(ICMP协议)是通畅的,但更高层(如TCP/UDP协议或服务配置)存在问题。以下是系统性排查与解决方案: 一…...
【Hive入门】Hive行级安全:基于Apache Ranger的细粒度访问控制深度解析
引言 在大数据时代,数据安全与隐私保护已成为企业不可忽视的核心需求。传统表级权限控制已无法满足"同一张表不同用户看到不同数据"的业务场景,行级安全(Row-Level Security)成为数据仓库系统的必备能力。 1 行级安全概述 1.1 什么是行级安全…...
Marin说PCB之1000-BASE-T1的PCB设计总结--04
另外一路的1000-BASE-T1 Circuit:千兆以太网的仿真电路原理图的连接搭建方式如下: (共模电感的连接需要特别注意一下PIN序别搞错了) 这一路1000-BASE-T1 Circuit是做了兼容设计的: 其中电容C2099和C2100是百兆以太网的…...
两数之和(暴力+哈希查找)
目录 一.题目 二.解题过程 题目解析 方法一(暴力求解) 思路 代码 提交结果 方法二(哈希查找) 思路 代码 提交结果 作者的个人gitee 作者的算法讲解主页▶️ 每日一言:“愿你纵踩淤泥,也要…...
Qt项目——天气预报
目录 前言结果预览工程文件窗体无状态栏窗口跟随移动HTTP基本概念JSON数据QT解析JSON数据结语 前言 通过对之前Qt的学习其实我们就已经有一点经验了,做天气预报只需要了解以下内容: stylesheet界面美化 Json数据解析 HTTP通信 自定义控件绘制温度 结果预…...
智能推理DeepSeek-R1+Word深度整合业级智能办公构建
前引: 当我们将DeepSeek-R1深度集成到Word时,实际上是在构建智能办公的"数字神经系统"。这个系统不仅理解文字内容,更能感知用户意图,在恰当的时刻提供精准的智能辅助。随着RAG(检索增强生成)技术…...
【C++ Qt】常用输入类下:Combo Box/Spin Box/DataTimeEdit/Dial/Slide
每日激励:“不设限和自我肯定的心态:I can do all things。 — Stephen Curry” 绪论: 在Qt开发框架中,UI组件是构建用户交互界面的基石。本章将详细探讨Qt中常用的UI组件,包括下拉框(QComboBoxÿ…...
基于Piecewise Jerk Speed Optimizer的速度规划算法(附ROS C++/Python仿真)
目录 1 时空解耦运动规划2 PJSO速度规划原理2.1 优化变量2.2 代价函数2.3 约束条件2.4 二次规划形式 3 算法仿真3.1 ROS C仿真3.2 Python仿真 1 时空解耦运动规划 在自主移动系统的运动规划体系中,时空解耦的递进式架构因其高效性与工程可实现性被广泛采用。这一架…...
K8s 常用命令、对象名称缩写汇总
K8s 常用命令、对象名称缩写汇总 前言 在之前的文章中已经陆续介绍过 Kubernetes 的部分命令,本文将专题介绍 Kubernetes 的常用命令,处理日常工作基本够用了。 集群相关 1、查看集群信息 kubectl cluster-info # 输出信息Kubernetes master is run…...
C++编程语言:从高效系统开发到现代编程范式的演进之路
目录 前言一、c简介1.1 起源1.2 c的特点 二、开发环境搭建 2.1. 安装 Qt 开发工具2.2 修改编码环境 2.3创建第一个 Qt 项目2.4 c的编译过程2.5 代码示例 2.6 qt疑难杂症 2.6.1 遇到无法删除代码,一点击光标就变成小黑块2.6.2 遇到运行不弹出终端 编辑 2.6.3 遇到…...
OpenCV进阶操作:角点检测
文章目录 一、角点检测1、定义2、检测流程1)输入图像2)图像预处理3)特征提取4)角点检测5)角点定位和标记6)角点筛选或后处理(可选)7)输出结果 二、Harris 角点检测&#…...
广州华锐视点邀您参与2025广交会VRAR展【5月10-12日】
2025 广交会数字显示与元宇宙生态博览会暨第 9 届世界 VR&AR 展将在广州盛大举行 。时间:2025 年 5 月 10 日至 12 日,广州华锐视点作为一家深耕 VR、AR、AI、元宇宙内容制作领域的企业,也将携旗下众多创新产品和解决方案闪耀登场&#x…...
mac m2 安装 hbase
默认安装好了 homebrew。 1. 终端先更新下 homebrew brew upgrade再安装 hbase brew install hbase 安装完会有如下图的内容 2. 按照提示启动 hbase brew services start hbase返回启动成功 3. 访问 http://localhost:16010 检验一下 启动成功 4. 在启动 hbase shell之…...
k8s node 报IPVS no destination available
在 Kubernetes 集群中,IPVS no destination available 错误通常表示 kube-proxy(IPVS 模式)无法为 Service 找到可用的后端 Pod。这会导致流量无法正确转发,影响服务可用性。以下是详细的排查和解决方法: 一、错误原因…...
MySQL 中 EXISTS (SELECT 1 FROM ...) 的用法详解
EXISTS (SELECT 1 FROM ...) 是 MySQL 中用于存在性检查的核心语法,其核心逻辑是判断子查询是否返回至少一行数据。以下从作用原理、使用场景、性能优化等方面展开解析,并结合具体示例说明。 1. 基本语法与作用原理 语法结构: SELECT 列名 F…...
荣耀A8互动娱乐组件部署实录(第3部分:控制端结构与房间通信协议)
作者:曾在 WebSocket 超时里泡了七天七夜的苦命人 一、控制端总体架构概述 荣耀A8控制端主要承担的是“运营支点”功能,也就是开发与运营之间的桥梁。它既不直接参与玩家行为,又控制着玩家的行为逻辑和游戏规则触发机制。控制端的主要职责包…...
前端-HTML+CSS+JavaScript+Vue+Ajax概述
HTML(超文本标记语言)常见标签 <html><head> <title>这是标题的内容,显示在浏览器的头部</title></head><body><!-- 这里面的内容在浏览器显示给用户看 --><!-- h1 -> h6 : 标题从大到小 …...
20250506格式化NanoPi NEO开发板使用Ubuntu core16.04系统的TF启动卡
https://www.sdcard.org/downloads/formatter/eula_windows/SDCardFormatterv5_WinEN.zip 20250506使用SDCardFormatter工具格式化NanoPi NEO开发板使用Ubuntu core16.04系统的TF启动卡 2025/5/6 20:04 缘起:使用友善之臂的NanoPi NEO开发板,制作了Ubunt…...
信息时代的政治重构:网络空间与主权的未来
一、网络空间:暴力垄断的终结 无边界主权的崛起 网络空间作为“第五阶段”的暴力竞争场域,打破传统领土垄断。政府无法像控制物理世界那样垄断网络暴力,类似公海的法律真空状态。 边区类比:中世纪的安道尔(法西共管避…...
Kotlin重构Android项目实践
以下是使用 Kotlin 重构 Android 项目的 5 个常见场景实践,通过对比 Java 实现方式,展示 Kotlin 的简洁性和现代特性: 场景 1:数据类替代 Java POJO Java 传统实现: public class User {private String name;private…...
Vue + Element UI 表单弹窗输入法卡顿问题解决方案
Vue Element UI 表单弹窗输入法卡顿问题解决方案 前言 在使用 Vue 和 Element UI 开发后台管理系统时,经常会遇到 el-dialog 弹出表单对话框的场景。然而,很多开发者可能会遇到一个棘手的问题:当调用 resetFields() 方法重置表单时&#x…...
ubantu安装CUDA
想要通过llama.cpp的方式跑deepseek R1模型。在按照https://huggingface.co/unsloth/DeepSeek-R1-GGUF教程去配环境时报错了。具体如下: (base) oemcore:~/Desktop/deepseek_llama.cpp$ sudo cmake llama.cpp -B llama.cpp/build -DBUILD_SHARED_LIBSOFF -DGGM…...
Python生活手册-Numpy多维数组构建:从快递分拣到智能家居的数据变形术
一、快递分拣系统(基础构建) 1. 电子面单生成(列表转数组) import numpy as np手工录入的快递单号 纸质单号 [["SF123", "JD456", "EMS789"],["YT012", "ZT345", "YZ6…...
数据库的范围查询
范围查询 B树迭代器 迭代器接口 B树的基本操作包括用于范围查询的查找和迭代。B树的位置由状态化的迭代器 BIter 表示。 // 查找小于或等于输入键的最近位置 func (tree *BTree) SeekLE(key []byte) *BIter// 获取当前键值对 func (iter *BIter) Deref() ([]byte, []byte)/…...
JS DAY4 日期对象与节点
一日期对象 日期对象:用来表示时间的对象 作用:可以得到当前系统时间 1.实例化 在代码中发现了 new 关键字时,一般将这个操作称为实例化 创建一个时间对象并获取时间 时间必须实例化 获得当前时间 const date new Date() 获得指定时间 const date new Date(…...
【Leetcode 每日一题 - 补卡】1007. 行相等的最少多米诺旋转
问题背景 在一排多米诺骨牌中, t o p s [ i ] tops[i] tops[i] 和 b o t t o m s [ i ] bottoms[i] bottoms[i] 分别代表第 i i i 个多米诺骨牌的上半部分和下半部分。(一个多米诺是两个从 1 1 1 到 6 6 6 的数字同列平铺形成的 —— 该平铺的每一半…...
Android设备运行yolov8
放假这几天搞了一个基于uniapprk3588实现了一版yolo检测 这个是基于前端调用后端api来实现,感觉还可以,但是需要有网络才能进行图像检测,网络不稳定就会出现等待时间会比较久的问题,然后有做了一个在做了一个Android版本的图像检…...
Debezium MySqlValueConverters详解
Debezium MySqlValueConverters详解 1. 类的作用与功能 1.1 核心作用 MySqlValueConverters是Debezium中负责MySQL数据类型转换的核心类,主要功能包括: 数据类型映射:将MySQL的数据类型映射到Kafka Connect的Schema类型值转换:将MySQL的原始值转换为Kafka Connect可用的…...
Redis从入门到实战——实战篇(下)
四、达人探店 1. 发布探店笔记 探店笔记类似于点评网站的评价,往往是图文结合。对应的表有两个: tb_blog:探店笔记表,包含笔记中的标题、文字、图片等tb_blog_comments:其他用户对探店笔记的评价 步骤①࿱…...
算法中的数学:质数(素数)
1.质数 1.1定义 一个大于1的自然数,除了1和它自身外,不能被其他自然数整除,那么他就是质数,否则他就是合数。 注意:1既不是质数也不是合数 唯一的偶质数是2,其余所有质数都是奇质数 1.2质数判定求法 试除法…...
linux、window安装部署nacos
本文以nacos 2.2.0为例 文章目录 1.下载安装包2.按需修改配置配置单机模式配置内存 -Xms -Xmx -Xmn配置数据库为MySQL 3. 访问http://ip:8848/nacos4.常见问题找不到javac命令 1.下载安装包 打开官网,下载2.2.0版本 2.按需修改配置 配置单机模式 默认集群模式&…...
C++ 外观模式详解
外观模式(Facade Pattern)是一种结构型设计模式,它为复杂的子系统提供一个简化的接口。 概念解析 外观模式的核心思想是: 简化接口:为复杂的子系统提供一个更简单、更统一的接口 降低耦合:减少客户端与子…...
42. 接雨水(相向双指针/前后缀分解),一篇文章讲透彻
给定一个数组,代表柱子的高度 求出下雨之后,能接的水有多少单位。我们将每一个柱子想象成一个水桶,看他能接多少水 以这个水桶为例,他所能接的水取决于左边的柱子的最大高度和右边柱子的最大高度,因为只有柱子高的时候…...
vue实现AI问答Markdown打字机效果
上线效果 功能清单 AI问答,文字输出跟随打字机效果格式化回答内容(markdown格式)停止回答,复制回答内容回答时自动向下滚动全屏切换历史问答查看 主要技术 vue 2.7.1markdown-it 14.1.0microsoft/fetch-event-source 2.0.1high…...