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

常用数据结构之String字符串

字符串

在Java编程语言中,字符可以使用基本数据类型char来保存,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串。

操作字符串常用的有三种类:String、StringBuilder、StringBuffer

接下来看看这三类常见用法

String

String value = new String("测试下");
System.out.println(value);

特点:

不可变

String value_a = "测试下原来值";value_a = "改变了";System.out.println(value_a);

实际打印

改变了

看起来好像改变了,那string为啥还具有不可变的特点呢

那咱来看看以上程序执行过程中value_a的指向

可以看到原来value_a指向“测试下原来值”字符串,后来有指向了“改变了”

为啥String不可变,咱进入String源码看看咋实现的

public final class Stringimplements java.io.Serializable, Comparable<String>, CharSequence {/** The value is used for character storage. */private final char value[];/** Cache the hash code for the string */private int hash; // Default to 0/** use serialVersionUID from JDK 1.0.2 for interoperability */private static final long serialVersionUID = -6849794470754667710L;/*** Class String is special cased within the Serialization Stream Protocol.** A String instance is written into an ObjectOutputStream according to* <a href="{@docRoot}/../platform/serialization/spec/output.html">* Object Serialization Specification, Section 6.2, "Stream Elements"</a>*/private static final ObjectStreamField[] serialPersistentFields =new ObjectStreamField[0];/*** Initializes a newly created {@code String} object so that it represents* an empty character sequence.  Note that use of this constructor is* unnecessary since Strings are immutable.*/public String() {this.value = "".value;}/*** Initializes a newly created {@code String} object so that it represents* the same sequence of characters as the argument; in other words, the* newly created string is a copy of the argument string. Unless an* explicit copy of {@code original} is needed, use of this constructor is* unnecessary since Strings are immutable.** @param  original*         A {@code String}*/public String(String original) {this.value = original.value;this.hash = original.hash;}/*** Allocates a new {@code String} so that it represents the sequence of* characters currently contained in the character array argument. The* contents of the character array are copied; subsequent modification of* the character array does not affect the newly created string.** @param  value*         The initial value of the string*/public String(char value[]) {this.value = Arrays.copyOf(value, value.length);}/*** Allocates a new {@code String} that contains characters from a subarray* of the character array argument. The {@code offset} argument is the* index of the first character of the subarray and the {@code count}* argument specifies the length of the subarray. The contents of the* subarray are copied; subsequent modification of the character array does* not affect the newly created string.** @param  value*         Array that is the source of characters** @param  offset*         The initial offset** @param  count*         The length** @throws  IndexOutOfBoundsException*          If the {@code offset} and {@code count} arguments index*          characters outside the bounds of the {@code value} array*/public String(char value[], int offset, int count) {if (offset < 0) {throw new StringIndexOutOfBoundsException(offset);}if (count <= 0) {if (count < 0) {throw new StringIndexOutOfBoundsException(count);}if (offset <= value.length) {this.value = "".value;return;}}// Note: offset or count might be near -1>>>1.if (offset > value.length - count) {throw new StringIndexOutOfBoundsException(offset + count);}this.value = Arrays.copyOfRange(value, offset, offset+count);}/*** Allocates a new {@code String} that contains characters from a subarray* of the <a href="Character.html#unicode">Unicode code point</a> array* argument.  The {@code offset} argument is the index of the first code* point of the subarray and the {@code count} argument specifies the* length of the subarray.  The contents of the subarray are converted to* {@code char}s; subsequent modification of the {@code int} array does not* affect the newly created string.** @param  codePoints*         Array that is the source of Unicode code points** @param  offset*         The initial offset** @param  count*         The length** @throws  IllegalArgumentException*          If any invalid Unicode code point is found in {@code*          codePoints}** @throws  IndexOutOfBoundsException*          If the {@code offset} and {@code count} arguments index*          characters outside the bounds of the {@code codePoints} array** @since  1.5*/public String(int[] codePoints, int offset, int count) {if (offset < 0) {throw new StringIndexOutOfBoundsException(offset);}if (count <= 0) {if (count < 0) {throw new StringIndexOutOfBoundsException(count);}if (offset <= codePoints.length) {this.value = "".value;return;}}// Note: offset or count might be near -1>>>1.if (offset > codePoints.length - count) {throw new StringIndexOutOfBoundsException(offset + count);}final int end = offset + count;// Pass 1: Compute precise size of char[]int n = count;for (int i = offset; i < end; i++) {int c = codePoints[i];if (Character.isBmpCodePoint(c))continue;else if (Character.isValidCodePoint(c))n++;else throw new IllegalArgumentException(Integer.toString(c));}// Pass 2: Allocate and fill in char[]final char[] v = new char[n];for (int i = offset, j = 0; i < end; i++, j++) {int c = codePoints[i];if (Character.isBmpCodePoint(c))v[j] = (char)c;elseCharacter.toSurrogates(c, v, j++);}this.value = v;}
}

可以看到String类有个final修饰符,final修饰符,用来修饰类、方法和变量,final 修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的

相当于string类型指向的具体内容不会变,例如刚才的例子,

value_a = "测试下原来值"; 这个数值不会变,原本有这个字符串有char value[]来进行保存本质不会被修改
value_a = "改变了"; 后续改变value_a的数值,会把原本value_a的引用指向新的字符串"改变了",而不是改变原来有char value[]保存的"测试下原来值",但由于无引用指向原来的字符串"测试下原来值",会被垃圾回收掉

结论:String不可变指的是String的内容不会变,但是可以改变String引用指向新的字符串

接下来看个🌰

String pre = "Hello,World";String new_value = "Hello,World";String object_value = new String("Hello,World");System.out.println(object_value.hashCode());System.out.println(pre.hashCode());System.out.println(new_value.hashCode());System.out.print("通过==判断pre是否与new_value相等->");System.out.println(pre==new_value);System.out.print("通过==判断pre是否与object_value相等->");System.out.println(pre==object_value);System.out.println("----------------");System.out.print("通过.equals判断pre是否与new_value相等->");System.out.println(pre.equals(new_value));System.out.print("通过.equals判断pre是否与object_value相等->");System.out.println(pre.equals(object_value));

以上程序分别会打印true还是false呢

可以看到通过字面创建的"Hello,World",不管新建多少次,==判断和equals判断都相等

通过对象创建的"Hello,World"和字面量新建的字符串通过==判断也相等,但是通过equals判断对象创建和字面量创建返回的false

首先来看看equals和==的区别

equals与==区别

==:判断两个对象的地址是否相等

equals:Object超级父类有个equals方法

    public boolean equals(Object obj) {return (this == obj);}

Object是直接判断两者地址是否相同,与==作用相同

而且所有的对象都会继承Object类

可以看看官方的解释

package java.lang;/*** Class {@code Object} is the root of the class hierarchy.* Every class has {@code Object} as a superclass. All objects,* including arrays, implement the methods of this class.*类对象是类层次结构的根。每个类都有Object作为超类。所有对象,包括数组,都实现了此类的方法。* @author  unascribed* @see     java.lang.Class* @since   JDK1.0*/
public class Object

所以String也继承了Object类,具有equals方法

来看看String的equals的方法咋实现的呢

public boolean equals(Object anObject) {if (this == anObject) {return true;//假设两个对象地址相同==,则返回true 相当于两者相同}if (anObject instanceof String) {String anotherString = (String)anObject;int n = value.length;if (n == anotherString.value.length) {char v1[] = value;char v2[] = anotherString.value;int i = 0;while (n-- != 0) {//循环遍历String的value数组if (v1[i] != v2[i])return false;//其中有任何一个不同,认定两者不同i++;}return true; //所有字符都相同的情况下,相当于两者相同}}return false; //把不是String类与String对比 相当于两者不同}

可以看出来String的equals方法

1,假设两个对象地址相同==,则返回true 相当于两者相同

2,判断对象是否属于string

3,循环遍历String的value数组,其中有任何一个不同,认定两者不同

4,所有字符都相同的情况下,相当于两者相同

5,不是String类与String对比 相当于两者不同

而Object是直接判断两者地址是否相同

所以再看看之前举的🌰

String pre = "Hello,World";String new_value = "Hello,World";String object_value = new String("Hello,World");System.out.println(object_value.hashCode());System.out.println(pre.hashCode());System.out.println(new_value.hashCode());System.out.print("通过==判断pre是否与new_value相等->");System.out.println(pre==new_value);System.out.print("通过==判断pre是否与object_value相等->");System.out.println(pre==object_value);System.out.println("----------------");System.out.print("通过.equals判断pre是否与new_value相等->");System.out.println(pre.equals(new_value));System.out.print("通过.equals判断pre是否与object_value相等->");System.out.println(pre.equals(object_value));

pre和new_value都是通过字面量的形式创建的字符串,"Hello,World"字符串会保存到常量池当中,新建了pre引用变量和new_value引用变量指向的同一个"Hello,World"对象,所以两者本质属于同个对象,所以==和equals都相同

object_value在堆中新建了对象,object_value引用变量指向堆中的"Hello,World"对象

所以pre==object_value会返回false,两者属于两个对象

pre.equals(new_value)返回true,由于String对equals重写了,只需两者都是String对象,且value数组的值都相同则返回true

hashcode

再看看为啥这三者的hashcode都相同呢

直接看源码

public int hashCode() {int h = hash;if (h == 0 && value.length > 0) {char val[] = value;for (int i = 0; i < value.length; i++) {h = 31 * h + val[i];}hash = h;}return h;}

获取哈希码,也称为散列码

hashCode()方法‌:用于返回对象的哈希码,这是一个整数值。哈希码用于确定对象在哈希表中的索引位置。理想情况下,不同的对象应该产生不同的哈希码,但这不是强制的。哈希码的计算通常基于对象的属性,不同的对象可能产生相同的哈希码,这就是所谓的哈希冲突。

上述hashcode实现简化成:

value[n],字符数组有n个字符 计算规则顺序 定义h[n]为当前遍历计算出来的值

n=0   h[0]=value[0]

n=1:  h[1]=h[0]*31+value[1]

n=2: h[2] = h[1]*31+value[2]=(value[0]*31+value1)*31+value[2]

选择 31原因:

优化计算‌:31可以被编译器优化为31 * i = (i << 5) - i,这种形式利用了位运算和减法,比直接的乘法运算效率更高‌

减少冲突‌:31是一个质数,使用质数作为乘法因子可以降低哈希冲突的概率。质数的乘法性质使得每个字符的哈希值与31相乘时,都能保持相对独立的哈希值,从而减少冲突的可能性‌

31用2进制来表达为 11111 ,31*i等价于(i<<5)-i,即先将i左移5位(相当于乘以32),然后再减去i

注意点:

1,两者equals相同,则两者的hashcode返回整数值相同

2,若两者hashcode相同,equals不一定相同

3,不同的对象hashcode,为了使得减少哈希表的冲突,尽量保持不同

可以看到pre、new_value、object_value三者的value数组保存的数值相同都是"Hello,World"

所以通过hash算法算出来的索引为止即hash值相同

接下来再看个🌰

String a = "Hello";String b = "Hello";String c = new String("Hello");String e = a+b;String t = a+b+c;String l = a+"World";String l1 = "Hello"+World"

以上程序共新建了多少对象呢

a="Hello",一个对象

b由于"Hello"在字符串常量池中存在,

c 在堆中新建1个新的字符串常量对象"Hello",栈内存储c变量引用指向它

e 通过+来拼接字符串实际通过StringBuilder来构建的所有会新建个对象StringBuilder,

t a="Hello"在常量池中有,无需新建,b="Hello"在常量池中有,无需新建,c为堆对象引用,已新建过了,但是新的字符串"HelloHelloHello"会放入堆中新建个对象

l "World"和"Hello"会在编译期间拼接,新建"HelloWorld"对象,注意这里不会新建"World"对象进入常量池

l1 编译期间拼接成"HelloWorld" 新建1个对象 注意这里与l不同 l通过StringBuilder拼接的 两个对象部署同个对象

所以总共新建了6个对象

总结

字面量新建

String a = "Hello"; // 在字符串常量池中存入"Hello" 新建1个对象 a引用变量指向它
String b = "Hello";// 在字符串常量找到了"Hello" 无需新建对象 b引用变量指向它
String c = "World";// 在字符串常量池中找不到"World" 常量池中存入"World" 新建1个对象 c引用变量指向它

对象新建

String a = "Hello"; // 在字符串常量池中存入"Hello" 新建1个对象 a引用变量指向它
String b = "Hello";// 在字符串常量找到了"Hello" 无需新建对象 b引用变量指向它
String c = "World";// 在字符串常量池中找不到"World" 常量池中存入"World" 新建1个对象 c引用变量指向它
String t = new String("Hello");//"Hello"在字符串常量池中存在,无需在常量池在存入"Hello",在堆中新建对象指向它
String t1 = new String("HelloWorld");//"HelloWorld"在字符串常量池中不存在,在常量池在存入"HelloWorld",内存堆中新建对象指向它

+拼接

String a = "Hello"; // 在字符串常量池中存入"Hello" 新建1个对象 a引用变量指向它
String b = "Hello";// 在字符串常量找到了"Hello" 无需新建对象 b引用变量指向它
String c = "World";// 在字符串常量池中找不到"World" 常量池中存入"World" 新建1个对象 c引用变量指向它
String t = new String("Hello");//"Hello"在字符串常量池中存在,无需在常量池在存入"Hello",在堆中新建对象指向它
String t1 = new String("HelloWorld");//"HelloWorld"在字符串常量池中不存在,在常量池在存入"HelloWorld",内存堆中新建对象指向它
String b1 = "Hello"+"World";//"HelloWorld"在常量池中已有,所以无需新建对象
String new_value = "Hello"+"Java";//"HelloJava"在常量池中不存在,常量池新建"HelloJava"
String value_new = a+b;//通过StringBuilder拼接会新建个对象

拼接"Hello"常量:直接拼接,会在编译期间进入常量池

但不是所有的常量都会进行折叠,只有编译器在程序编译期就可以确定值的常量才可以

  • 基本数据类型( bytebooleanshortcharintfloatlongdouble)以及字符串常量。
  • final 修饰的基本数据类型和字符串变量
  • 字符串通过 “+”拼接得到的字符串、基本数据类型之间算数运算(加减乘除)、基本数据类型的位运算(<<、>>、>>> )

引用的值在程序编译期是无法确定的,编译器无法对其进行优化

拼接常量引用变量:字符对象的拼接实际上底层是使用的StringBuilder的append方法,先将字符串对象转换成StringBuilder然后调用append方法之后再调用toString(),此时生成的是另一个String对象,String对象存储在堆中,不会存入常量池

注意:‌String().intern()方法在Java中的作用是将字符串对象添加到字符串常量池中,如果常量池中已经存在相同的字符串,则返回该字符串的引用;如果不存在,则创建一个新的字符串对象并添加到常量池中‌‌

对象引用和“+”的字符串拼接方式,实际上是通过 StringBuilder 调用 append() 方法实现的,拼接完成之后调用 toString() 得到一个 String 对象 。

注意被final修饰的常量的引用拼接可以直接在编译期间再进入常量池

但修饰1个当时无法确定的数值,即在运行时才可以确定的值,则海还是会通过StringBuilder来拼接

开发中应该减少多个字符串拼接操作

所以出现了StringBuilder和StringBuffer

StringBuilder

由于string为不可变的,后续又设计了stringbuilder类

‌StringBuilder是Java中的一个可变字符串操作类,主要用于在需要频繁修改字符串内容的场景下使用,以提高性能。

StringBuilder的优势和适用场景

  1. 性能优势‌:StringBuilder是可变的,对字符串的修改直接作用于当前对象,无需创建新对象,因此在需要频繁拼接或修改字符串时,性能更高‌1。
  2. 适用场景‌:适合在单线程环境下使用,特别是在本地应用程序或单线程任务中需要频繁修改字符串时,StringBuilder的性能优于StringBuilder

源码

public final class StringBuilderextends AbstractStringBuilderimplements java.io.Serializable, CharSequence
{/** use serialVersionUID for interoperability */static final long serialVersionUID = 4383685877147921099L;/*** Constructs a string builder with no characters in it and an* initial capacity of 16 characters.*/public StringBuilder() {super(16);}/*** Constructs a string builder with no characters in it and an* initial capacity specified by the {@code capacity} argument.** @param      capacity  the initial capacity.* @throws     NegativeArraySizeException  if the {@code capacity}*               argument is less than {@code 0}.*/public StringBuilder(int capacity) {super(capacity);}/*** Constructs a string builder initialized to the contents of the* specified string. The initial capacity of the string builder is* {@code 16} plus the length of the string argument.** @param   str   the initial contents of the buffer.*/public StringBuilder(String str) {super(str.length() + 16);append(str);}/*** Constructs a string builder that contains the same characters* as the specified {@code CharSequence}. The initial capacity of* the string builder is {@code 16} plus the length of the* {@code CharSequence} argument.** @param      seq   the sequence to copy.*/public StringBuilder(CharSequence seq) {this(seq.length() + 16);append(seq);}@Overridepublic StringBuilder append(Object obj) {return append(String.valueOf(obj));}@Overridepublic StringBuilder append(String str) {super.append(str);return this;}/*** Appends the specified {@code StringBuffer} to this sequence.* <p>* The characters of the {@code StringBuffer} argument are appended,* in order, to this sequence, increasing the* length of this sequence by the length of the argument.* If {@code sb} is {@code null}, then the four characters* {@code "null"} are appended to this sequence.* <p>* Let <i>n</i> be the length of this character sequence just prior to* execution of the {@code append} method. Then the character at index* <i>k</i> in the new character sequence is equal to the character at* index <i>k</i> in the old character sequence, if <i>k</i> is less than* <i>n</i>; otherwise, it is equal to the character at index <i>k-n</i>* in the argument {@code sb}.** @param   sb   the {@code StringBuffer} to append.* @return  a reference to this object.*/public StringBuilder append(StringBuffer sb) {super.append(sb);return this;}@Overridepublic StringBuilder append(CharSequence s) {super.append(s);return this;}
}

可以看出来构造函数有4个

StringBuilder():字符初始容量为16的StringBuilder

StringBuilder(int capacity):字符初始容量为指定数量的StringBuilder

StringBuilder(CharSequence seq):包含与指定的CharSequence相同的字符序列

StringBuilder(String str):包含与指定的String相同的字符序列

常用方法:

append():

public AbstractStringBuilder append(String str) {if (str == null)return appendNull();int len = str.length();ensureCapacityInternal(count + len);str.getChars(0, len, value, count);count += len;return this;}

可以看出来返回的对象是this,不会增加新的对象,对比String内存占用少了很多

insert():

public AbstractStringBuilder insert(int offset, char[] str) {if ((offset < 0) || (offset > length()))throw new StringIndexOutOfBoundsException(offset);int len = str.length;ensureCapacityInternal(count + len);System.arraycopy(value, offset, value, offset + len, count - offset);System.arraycopy(str, 0, value, offset, len);count += len;return this;}

可以看出来返回的对象是this,不会增加新的对象,对比String内存占用少了很多

toString():

@Overridepublic String toString() {// Create a copy, don't share the arrayreturn new String(value, 0, count);}

StringBuilder类不是线程安全的,有多个线程同时对同一个StringBuilder对象进行操作,可能会出现并发问题。

StringBuffer

线程安全的,主要原因在于其内部方法关键字进行同步‌。这意味着多个线程可以安全地同时访问和修改同一个StringBuffer对象,而不会导致数据不一致或其他线程相关的问题‌

@Overridepublic synchronized StringBuffer append(String str) {toStringCache = null;super.append(str);return this;}

synchronized即同步锁,当前线程执行情况下,其它线程会同步等待直至当前线程释放锁

    

相关文章:

常用数据结构之String字符串

字符串 在Java编程语言中&#xff0c;字符可以使用基本数据类型char来保存&#xff0c;在 Java 中字符串属于对象&#xff0c;Java 提供了 String 类来创建和操作字符串。 操作字符串常用的有三种类&#xff1a;String、StringBuilder、StringBuffer 接下来看看这三类常见用…...

Android开发获取缓存,删除缓存

Android开发获取缓存&#xff0c;删除缓存 app设置中往往有清理缓存的功能。会显示当前缓存时多少&#xff0c;然后可以点击清理缓存 直接上代码&#xff1a; object CacheHelper {/*** 获取缓存大小* param context* return* throws Exception*/JvmStaticfun getTotalCache…...

网络安全 | 保护智能家居和企业IoT设备的安全策略

网络安全 | 保护智能家居和企业IoT设备的安全策略 一、前言二、智能家居和企业 IoT 设备面临的安全威胁2.1 设备自身安全缺陷2.2 网络通信安全隐患2.3 数据隐私风险2.4 恶意软件和攻击手段 三、保护智能家居和企业 IoT 设备的安全策略3.1 设备安全设计与制造环节的考量3.2 网络…...

掌握API和控制点(从Java到JNI接口)_38 JNI从C调用Java函数 01

1. Why? 将控制点下移到下C/C层 对古典视角的反思 App接近User&#xff0c;所以App在整体架构里&#xff0c;是主导者&#xff0c;拥有控制权。所以&#xff0c; App是架构的控制点所在。Java函数调用C/C层函数&#xff0c;是合理的。 但是EIT造形告诉我们&#xff1a; App…...

vue组件间的数据传递:自定义输入组件(v-model/defineModel)

文章目录 引言I Vue 3.4 开始,推荐使用 defineModel() 宏子组件使用defineModel父组件用 v-model 绑定值底层机制II Vue 3.4之前:自定义输入组件(组件中实现 v-model )前置知识父组件监听自定义事件进行 v-model 的数据绑定子组件通过监听input事件触发自定义的 `update:mo…...

记录一下 在Mac下用pyinstallter 打包 Django项目

安装: pip install pyinstaller 在urls.py from SheepMasterOneToOne import settings from django.conf.urls.static import staticurlpatterns [path("admin/", admin.site.urls),path(generate_report/export/, ReportAdmin(models.Report, admin.site).generat…...

大模型相关概念

文章目录 部署相关数据并行模型并行张量并行管道并行&#xff08;流水线并行&#xff09; 混合并行&#xff08;数据并行模型并行&#xff09;显存优化技术InfiniBand去中心化的All-Reduce操作软件 大模型命名**1. 模型架构相关****2. 模型用途相关****3. 训练方法相关****4. 多…...

【实用教程】在 Android Studio 中连接 MuMu 模拟器

MuMu 模拟器是一个非常流行的安卓模拟器&#xff0c;特别适合开发人员进行应用测试&#xff0c;我使用它的根本原因在于Android Studio自带的AVM实现是太难用了&#xff0c;但是Mumu模拟器启动以后不会自动被Android Studio识别到&#xff0c;但是其他模拟器都是能够正常被Andr…...

Linux 安装 Ollama

1、下载地址 Download Ollama on Linux 2、有网络直接执行 curl -fsSL https://ollama.com/install.sh | sh 命令 3、下载慢的解决方法 1、curl -fsSL https://ollama.com/install.sh -o ollama_install.sh 2、sed -i s|https://ollama.com/download/ollama-linux|https://…...

双亲委派(JVM)

1.双亲委派 在 Java 中&#xff0c;双薪委派通常是指双亲委派模型&#xff0c;它是 Java 类加载器的一种工作模式&#xff0c;用于确保类加载的安全性和一致性。以下是其相关介绍&#xff1a; 定义与作用 定义&#xff1a;双亲委派模型要求除了顶层的启动类加载器外&#xf…...

青少年编程与数学 02-009 Django 5 Web 编程 01课题、概要

青少年编程与数学 02-009 Django 5 Web 编程 01课题、概要 一、Django 5Django 5 的主要特性包括&#xff1a; 二、MVT模式三、官方网站四、内置功能数据库 ORM&#xff08;对象关系映射&#xff09;用户认证和授权表单处理模板引擎URL 路由缓存框架国际化和本地化安全性功能管…...

为AI聊天工具添加一个知识系统 之90 详细设计之31 Derivation 之5-- 神经元变元用它衍生神经网络

本文要点 要点 Derivation 神经元变元衍生模型&#xff08; 衍生 神经网络&#xff09; 整体上说&#xff0c;它&#xff08; Derivation&#xff09;自己充当 整体无意识原型anestor的代言--作为所有神经网络的 共生环境。Derivation 初始断言了 基于最古老的 自然和逻辑树…...

Centos挂载镜像制作本地yum源,并补装图形界面

内网环境centos7.9安装图形页面内网环境制作本地yum源 上传镜像到服务器目录 创建目录并挂载镜像 #创建目录 cd /mnt/ mkdir iso#挂载 mount -o loop ./CentOS-7-x86_64-DVD-2009.iso ./iso #前面镜像所在目录&#xff0c;后面所挂载得目录#检查 [rootlocalhost mnt]# df -h…...

【Python实战练习】Python类中的方法:形式与作用详解

文章目录 Python类中的方法:形式与作用详解1. 实例方法 (Instance Method)定义与使用作用2. 类方法 (Class Method)定义与使用作用3. 静态方法 (Static Method)定义与使用作用4. 特殊方法 (Magic/Dunder Methods)常见的特殊方法定义与使用作用5. 抽象方法 (Abstract Method)定…...

Idea 2024.3 使用CodeGPT插件整合Deepseek

哈喽&#xff0c;大家好&#xff0c;我是浮云&#xff0c;最近国产大模型Deepseek异常火爆&#xff0c;作为程序员我也试着玩了一下&#xff0c;首先作为简单的使用&#xff0c;大家进入官网&#xff0c;点击开始对话即可进行简单的聊天使用&#xff0c;点击获取手机app即可安装…...

神经网络常见激活函数 1-sigmoid函数

sigmoid 1 函数求导 sigmoid函数 σ ( x ) 1 1 e ( − x ) \sigma(x) \frac{1}{1e^{(-x)}} σ(x)1e(−x)1​ sigmoid函数求导 d d x σ ( x ) d d x ( 1 1 e − x ) e − x ( 1 e − x ) 2 ( 1 e − x ) − 1 ( 1 e − x ) 2 1 1 e − x − 1 ( 1 e − x ) 2 …...

Vue(6)

一.路由板块封装 &#xff08;1&#xff09;路由的封装抽离 目标&#xff1a;将路由板块抽离出来 好处&#xff1a;拆分板块&#xff0c;利于维护 // 路由的使用步骤 5 2 // 5个基础步骤 // 1. 下载 v3.6.5 // 2. 引入 // 3. 安装注册 Vue.use(Vue插件) // 4. 创建路由对象…...

深入理解进程优先级

目录 引言 一、进程优先级基础 1.1 什么是进程优先级&#xff1f; 1.2 优先级与系统性能 二、查看进程信息 2.1 使用ps -l命令 2.2 PRI与NI的数学关系 三、深入理解Nice值 3.1 Nice值的特点 3.2 调整优先级实践 四、进程特性全景图 五、优化实践建议 结语 引言 在操…...

机器学习 - 需要了解的条件概率、高斯分布、似然函数

似然函数是连接数据与参数的桥梁&#xff0c;通过“数据反推参数”的逆向思维&#xff0c;成为统计推断的核心工具。理解它的关键在于区分“参数固定时数据的概率”与“数据固定时参数的合理性”&#xff0c;这种视角转换是掌握现代统计学和机器学习的基础。 一、在学习似然函…...

程序诗篇里的灵动笔触:指针绘就数据的梦幻蓝图<7>

大家好啊&#xff0c;我是小象٩(๑ω๑)۶ 我的博客&#xff1a;Xiao Xiangζั͡ޓއއ 很高兴见到大家&#xff0c;希望能够和大家一起交流学习&#xff0c;共同进步。 今天我们一起来学习转移表&#xff0c;回调函数&#xff0c;qsort… 目录 一、转移表1.1 定义与原理1.3…...

4、C#基于.net framework的应用开发实战编程 - 测试(四、一) - 编程手把手系列文章...

四、 测试&#xff1b; 四&#xff0e;一、调试&#xff1b; 开发完应用&#xff0c;就需要对应用进行测试&#xff0c;第一部就从调试开始&#xff0c;特别是一些重要的功能点&#xff0c;还有如果运行时有问题&#xff0c;也需要对应用进行调试&#xff0c;以找出问题。 1、 …...

逻辑回归:Sigmoid函数在分类问题中的应用

欢迎来到我的主页&#xff1a;【Echo-Nie】 本篇文章收录于专栏【机器学习】 1 什么是Sigmoid函数&#xff1f; Sigmoid函数&#xff08;Logistic函数&#xff09;是机器学习中最经典的激活函数之一&#xff0c;是一个在生物学中常见的S型函数&#xff0c;也称为S型生长曲线。…...

使用 SDKMAN! 在 Mac(包括 ARM 架构的 M1/M2 芯片)上安装 Java 8

文章目录 1. 安装 SDKMAN!2. 查找可用的 Java 8 版本3. 安装 Java 84. 验证安装5. 切换 Java 版本&#xff08;可选&#xff09;6. 解决 ARM 架构兼容性问题总结 可以使用 SDKMAN! 在 Mac&#xff08;包括 ARM 架构的 M1/M2 芯片&#xff09;上安装 Java 8。SDKMAN! 是一个强大…...

AUTOSAR汽车电子嵌入式编程精讲300篇-基于FPGA的CAN FD汽车总线数据交互系统设计

目录 前言 汽车总线以及发展趋势 汽车总线技术 汽车总线发展趋势 CAN FD总线国内外研究现状 2 系统方案及CAN FD协议分析 2.1系统控制方案设计 2.2 CAN FD总线帧结构分析 2.2.1数据帧分析 2.2.2远程帧分析 2.2.3过载帧分析 2.2.4错误帧分析 2.2.5帧间隔分析 2.3位…...

滴水逆向_程序实现弹窗修改OEP

作业&#xff1a; 几个很重要的注意事项。 1 我们模拟的是内核如何将一个文件硬盘中拉伸到内存中&#xff0c;但是我们做的仅仅是 模拟拉伸过程。也就是说其中的属性字段是无差别的拷贝的。 但是加载exe的时候 &#xff0c;imagebase 是随机分配的。 我们打开内存中的exe&…...

HTTP报文格式

HTTP请求报文格式 1. 结构&#xff1a; [请求行] [请求头] [空行] [请求体] &#xff08;可选&#xff09;请求行&#xff1a;方法 URI HTTP版本 常见方法&#xff1a;GET&#xff08;获取资源&#xff09;、POST&#xff08;提交数据&#xff09;、PUT&#xff08;替…...

pytest.fixture

pytest.fixture 是 pytest 测试框架中的一个非常强大的功能,它允许你在测试函数运行前后执行一些设置或清理代码。以下是关于 pytest.fixture 的详细介绍: 一、定义与用途 pytest.fixture 是一个装饰器,用于标记一个函数为 fixture。Fixture 函数中的代码可以在测试函数运…...

位运算算法篇:进入位运算的世界

位运算算法篇&#xff1a;进入位运算的世界 本篇文章是我们位运算算法篇的第一章&#xff0c;那么在我们是算法世界中&#xff0c;有那么多重要以及有趣的算法&#xff0c;比如深度优先搜索算法以及BFS以及动态规划算法等等&#xff0c;那么我们位运算在这些算法面前相比&#…...

Heterogeneous Graph Attention Network(HAN)

HAN WWW19 分类&#xff1a;异构图神经网络 元路径 (图片地址&#xff1a;异构图注意力网络(3) HAN_哔哩哔哩_bilibili) ​​ 如图所示&#xff0c;假如异构图如上所示。那么&#xff0c;按照MAM和MDM就可以生成不同的子图。这样&#xff0c;就可以生成MAM与MDM的一阶邻居…...

重学SpringBoot3-Spring WebFlux之SSE服务器发送事件

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞??收藏评论 Spring WebFlux之SSE服务器发送事件 1. 什么是 SSE&#xff1f;2. Spring Boot 3 响应式编程与 SSE 为什么选择响应式编程实现 SSE&#xff1f; 3. 实现 SSE 的基本步骤 3.1 创建 Spr…...

Java中实现定时锁屏的功能(可以指定时间执行)

Java中实现定时锁屏的功能&#xff08;可以指定时间执行&#xff09; 要在Java中实现定时锁屏的功能&#xff0c;可以使用java.util.Timer或java.util.concurrent.ScheduledExecutorService来调度任务&#xff0c;并通过调用操作系统的命令来执行锁屏。下面我将给出一个基本的…...

工作案例 - python绘制excell表中RSRP列的CDF图

什么是CDF图 CDF&#xff08;Cumulative Distribution Function&#xff09;就是累积分布函数&#xff0c;是概率密度函数的积分。CDF函数是一个在0到1之间的函数&#xff0c;描述了随机变量小于或等于一个特定值的概率。在可视化方面&#xff0c;CDF图表明了一个随机变量X小于…...

推理大模型DeepSeek迅速觉醒

随着人工智能技术的快速发展&#xff0c;DeepSeek作为一种创新的技术工具&#xff0c;正在重塑行业格局。本文将深入分析如何把握这一波由DeepSeek带来的流量红利&#xff0c;揭示其在市场洞察、技术创新和用户需求中的潜在机会&#xff0c;并提供实用策略帮助个人或企业快速融…...

Ubuntu22.04部署deepseek大模型

Ollama 官方版 Ollama 官方版: https://ollama.com/ 若你的显卡是在Linux上面 可以使用如下命令安装 curl -fsSL https://ollama.com/install.sh | shollama命令查看 rootheyu-virtual-machine:~# ollama -h Large language model runnerUsage:ollama [flags]ollama [comman…...

redis的数据结构介绍(string

redis是键值数据库&#xff0c;key一般是string类型&#xff0c;value的类型很多 string&#xff0c;hash&#xff0c;list&#xff0c;set&#xff0c;sortedset&#xff0c;geo&#xff0c;bitmap&#xff0c;hyperlog redis常用通用命令&#xff1a; keys&#xff1a; …...

QUIC 与 UDP 关系

QUIC协议是建立在UDP之上的,这意味着QUIC的数据包实际上是通过UDP传输的。QUIC的设计使其能够利用UDP的特性,同时在其上实现更复杂的功能。以下是QUIC如何体现出其基于UDP的特性,以及QUIC头部字段的详细介绍。 QUIC与UDP的关系 UDP封装:QUIC数据包被封装在UDP数据包中进行…...

webview_flutter的使用

目录 步骤示例代码 步骤 1.配置依赖。根目录下运行如下命令&#xff1a; flutter pub add webview_flutter 2.所需页面导入&#xff1a; import ‘package:webview_flutter/webview_flutter.dart’; 3.初始化WebViewController overridevoid initState() {super.initState();…...

Centos执行yum命令报错

错误描述 错误&#xff1a;为仓库 ‘appstream’ 下载元数据失败 : Cannot prepare internal mirrorlist: Curl error (6): Couldn’t resolve host name for http://mirrorlist.centos.org/?release8&archx86_64&repoAppStream&infrastock [Could not resolve h…...

aio-pika 快速上手(Python 异步 RabbitMQ 客户端)

目录 简介官方文档如何使用 简介 aio-pika 是一个 Python 异步 RabbitMQ 客户端。5.0.0 以前 aio-pika 基于 pika 进行封装&#xff0c;5.0.0 及以后使用 aiormq 进行封装。 https://github.com/mosquito/aio-pikahttps://pypi.org/project/aio-pika/ pip install aio-pika官…...

AI安全最佳实践:AI应用开发安全评估矩阵(上)

生成式AI开发安全范围矩阵简介 生成式AI目前可以说是当下最热门的技术&#xff0c;吸引各大全球企业的关注&#xff0c;并在全球各行各业中带来浪潮般的编个。随时AI能力的飞跃&#xff0c;大语言模型LLM参数达到千亿级别&#xff0c;它和Transformer神经网络共同驱动了我们工…...

疯狂前端面试题(二)

一、Webpack的理解 Webpack 是一个现代 JavaScript 应用程序的静态模块打包工具。Webpack 能够将各种资源&#xff08;JavaScript、CSS、图片、字体等&#xff09;视为模块&#xff0c;并通过依赖关系图将这些模块打包成一个或多个最终的输出文件&#xff08;通常是一个或几个…...

深入探究 C++17 std::is_invocable

文章目录 一、引言二、std::is_invocable 概述代码示例输出结果 三、std::is_invocable 的工作原理简化实现示例 四、std::is_invocable 的相关变体1. std::is_invocable_r2. std::is_nothrow_invocable 和 std::is_nothrow_invocable_r 五、使用场景1. 模板元编程2. 泛型算法 …...

【R语言】卡方检验

一、定义 卡方检验是用来检验样本观测次数与理论或总体次数之间差异性的推断性统计方法&#xff0c;其原理是比较观测值与理论值之间的差异。两者之间的差异越小&#xff0c;检验的结果越不容易达到显著水平&#xff1b;反之&#xff0c;检验结果越可能达到显著水平。 二、用…...

DeepSeek LLM 论文解读:相信长期主义开源理念可扩展大语言模型(DeepSeek 吹响通用人工智能的号角)

论文链接&#xff1a;DeepSeek LLM: Scaling Open-Source Language Models with Longtermism&#xff08;相信长期主义开源理念可扩展大语言模型&#xff09; 目录 摘要一、数据处理&#xff08;一&#xff09;数据清洗与丰富&#xff08;二&#xff09;分词器与词汇设置 二、模…...

指针基础知识2

1. 指针运算 1.1 指针 - 整数 以数组举例&#xff1a;因为数组在内存中是连续存放的&#xff0c;只要知道第⼀个元素的地址&#xff0c;顺藤摸瓜就能找到后面的所有元素。这时就会用到指针加减整数。 1.2指针-指针 指针 - 指针可以得到两个指针之间的数据个数。但是&#xf…...

nginx的4层和7层配置证书

4层证书代理 # 定义上游服务器组 stream {upstream tcp-25510 {hash $remote_addr consistent;server ip:5510;}# 配置监听 25510 端口的服务器块server {listen 25510 ssl; # 监听 25510 端口并启用 SSL# 指定 SSL 证书和私钥ssl_certificate /etc/nginx/key/bundle.crt;ssl…...

【大数据技术】搭建完全分布式高可用大数据集群(Flume)

搭建完全分布式高可用大数据集群(Flume) apache-flume-1.11.0-bin.tar.gz注:请在阅读本篇文章前,将以上资源下载下来。 写在前面 本文主要介绍搭建完全分布式高可用集群 Flume 的详细步骤。 注意: 统一约定将软件安装包存放于虚拟机的/software目录下,软件安装至/opt目…...

C++ 顺序表

顺序表的操作有以下&#xff1a; 1 顺序表的元素插入 给定一个索引和元素&#xff0c;这个位置往后的元素位置都要往后移动一次&#xff0c;元素插入的步骤有以下几步 &#xff08;1&#xff09;判断插入的位置是否合法&#xff0c;如果不合法则抛出异常 &#xff08;2&…...

Python----Python高级(网络编程:网络基础:发展历程,IP地址,MAC地址,域名,端口,子网掩码,网关,URL,DHCP,交换机)

一、网络 早期的计算机程序都是在本机上运行的&#xff0c;数据存储和处理都在同一台机器上完成。随着技术的发展&#xff0c;人 们开始有了让计算机之间相互通信的需求。例如安装在个人计算机上的计算器或记事本应用&#xff0c;其运行环 境仅限于个人计算机内部。这种设置虽然…...

Spring Boot 的问题:“由于无须配置,报错时很难定位”,该怎么解决?

Spring Boot 的 "由于无须配置&#xff0c;报错时很难定位" 主要指的是&#xff1a; 传统 Spring 框架 需要大量 XML 或 Java 配置&#xff0c;开发者对应用的组件、Bean 加载情况有清晰的控制&#xff0c;出错时可以从配置入手排查。Spring Boot 采用自动配置&…...