Java中的String数据类型,String类(字符串)详解

news2024/11/28 0:36:52

目录

  • 第一章、String概述
    • 1)String是什么
    • 2)String长什么样
    • 3)String的构造方法(声明方式)
  • 第二章、String类的详解
    • 1)String底层是什么
    • 2)字符串存储的内存原理/字符串常量池(String Constant Pool)
    • 3)字符串之间的比较问题
      • ①字符串之间的直接比较
      • ②字符串拼接完毕后做==比较的问题
    • 4)字符串与其他类型的转换
      • ①String字符串与基本数据类型的转换
      • ②String字符串与包装类型的转换
    • 5)String类常用方法
  • 第三章、字符串缓冲区StringBuffer和StringBuilder
    • 1)字符串缓冲区概述
    • 2)StringBuffer和StringBuilder声明方式
    • 3)StringBuffer/StringBuilder和String类型之间的转换
      • 4)二者的常用方法

第一章、String概述

1)String是什么

①String表示字符串类型,是引用数据类型不是基本数据类型,String是类且是最终类,不能有子类。
②字符串虽然是引用类型属于对象,但是它不是存储在堆空间中,而是存储在方法区中的字符串常量池中。只要我们书写了双引号,数据都会立刻在字符串常量池中保存。
在这里插入图片描述

2)String长什么样

使用双引号包裹起来的都是String。
①一个字母被双引号包裹起来的:

A

②多个字母被双引号包裹起来的:

“hello daShaGua!

③中文被双引号包裹起来的:

“你好小可爱”

3)String的构造方法(声明方式)

字符串常用的构造方法:6种

构造方法作用
String()初始化一个新创建的 String 对象,使其表示一个空字符序列。
String(String original)初始化一个新创建的 String 对象,使其表示一个与参数相同的字符序列;换句话说,新创建的字符串是该参数字符串的副本。
String(byte[] bytes)通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String。
String(byte[] bytes, int offset, int length)通过使用平台的默认字符集解码指定的 byte 子数组,构造一个新的 String。
String(char[] value)分配一个新的 String,使其表示字符数组参数中当前包含的字符序列。
String(char[] value, int offset, int count)分配一个新的 String,它包含取自字符数组参数一个子数组的字符。
Column 1Column 2
centered 文本居中right-aligned 文本居右
	public static void test1(){
	//String()|  初始化一个新创建的 String 对象,使其表示一个空字符序列。
		String s1 = "";					//空字符串
		String s2 = new String();		//空字符串
		
	//String(String original)| 初始化一个新创建的 String 对象,使其表示一个与参数相同的字符序列;
		String s3 = new String("");		//空字符串
		String s4 = new String("qwer");
		
	//String(byte[] bytes)  |通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String。	
		byte[] bs = {65,66,97,98};
		//类型转换:byte[] --> String
		String str = new String(bs);
		System.out.println(str);	//"ABab"
		
	//String(byte[] bytes, int offset, int length)   
	//通过使用平台的默认字符集解码指定的 byte 子数组,构造一个新的 String。	
		byte[] bs3 = {65,66,67,68,97,98,99,100};
		//类型转换:byte[] --> String
		String str3 = new String(bs3, 2, 5);
		System.out.println(str3);	//"CDab"

	//String(char[] value)  | 初始化一个新创建的 String 对象,使其表示字符数组参数中当前包含的字符序列。
		char[] cs = {'j','a','v','a'};
		//类型转换:char[] --> String
		String str = new String(cs);
		System.out.println(str);		//"java"
		
	//String(char[] value, int offset, int count)  | 包含取自字符数组参数一个子数组的字符。	
		String str1 = new String(cs,0,2);
		System.out.println(str1);		//"ja"
		
	}

第二章、String类的详解

1)String底层是什么

查看源码可以发现,String的底层是数组。
jdk1.8及以前String使用的是char数组
在这里插入图片描述

jdk1.9及以后使用的是byte数组
在这里插入图片描述
因为字符串底层是数组,所以可以遍历字符串

		//第一种方式
		//char charAt(int index):返回指定索引处的 char 值。 
		String str = "java";
		
		for(int i = 0;i <= str.length() - 1;i++){
			char c = str.charAt(i);
			System.out.print(c);
		}
//---------------------------分割------------------------------------------
		//第二种方式
		 //	char[] toCharArray():将此字符串转换为一个新的字符数组。 
		char[] cs = str.toCharArray();
		for(int i = 0;i <= cs.length - 1;i++){
			System.out.print(cs[i]);
		}

2)字符串存储的内存原理/字符串常量池(String Constant Pool)

①字符串被保存在字符串常量池中,在JDK1.8 字符串常量池在堆中, 运行时常量池在方法区。
②在java中String类型的值是不可改变的,指的是想要改变字符串值时会复用字符串常量池中的地址值。
例如:我们有一个字符串变量s = “a”,然后我们再对s赋值为”b”,我们并没有改变字符串s的值,只是在常量池中新建了一个字符串”b”,然后让s的地址值从指向”a”变成了指向”b”。

String s = "a";
s = "b";//并没有改变S的值,只是在常量池中新建了一个字符串”b”,然后让s从指向”a”变成了指向”b”

③直接赋值会复用字符串常量池中的地址值,new出来的不会复用,而是开辟一个新的空间

//直接赋值会复用字符串常量池中的地址
//它们的地址是一样的,这个就是 String 的复用性。"abc"在常量池中的,并且 s1 和 s2 都指向同一个地方。
		String s1 = "abc";
		String s2 = "abc";
		System.out.println(s1 == s2);		//true 比较的是地址值,s1和s2在常量池理指向了同一个地址值
		
		System.out.println(s1.equals(s2));	//true 底层重写了toString所以调用equals方法时比较的是内容
//new出来的不会复用,而是开辟一个新的空间		
		String s3 = new String("abc");
		
		System.out.println(s1 == s3);			//false new出来的不会复用,而是开辟一个新的空间
		System.out.println(s1.equals(s3));		//true 底层重写了toString所以调用equals方法时比较的是内容

ps:这里放一个老师的考题


			//【问题】:执行完毕下列5行代码,内存中一共有几个对象?
			//答:4个对象
		
		String s1 = "hello";					//1个对象		在常量池中
		String s2 = "hello";					//不会产生对象
		String s3 = new String("hello");		//1个对象		在堆中
		String s4 = new String("helloworld");	//2个对象		一个在堆中,另一个在常量池中
		String s5 = "helloworld";				//不会产生对象
		//所以一共是四个对象

3)字符串之间的比较问题

①字符串之间的直接比较

1、==比较的是地址值
2、equals比较的是字符串内容

//直接赋值会复用字符串常量池中的地址
//它们的地址是一样的,这个就是 String 的复用性。"abc"在常量池中的,并且 s1 和 s2 都指向同一个地方。
		String s1 = "abc";
		String s2 = "abc";
		System.out.println(s1 == s2);		//true 比较的是地址值,s1和s2在常量池理指向了同一个地址值
		
		System.out.println(s1.equals(s2));	//true 底层重写了toString所以调用equals方法时比较的是内容
//new出来的不会复用,而是开辟一个新的空间		
		String s3 = new String("abc");
		
		System.out.println(s1 == s3);			//false new出来的不会复用,而是开辟一个新的空间
		System.out.println(s1.equals(s3));		//true 底层重写了toString所以调用equals方法时比较的是内容

②字符串拼接完毕后做==比较的问题

1、字符串内容做==比较,比较的是地址值,
2、常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量,只要其中有一个是变量,结果就在堆中
3、只有常量池中数据内容进行,比较结果才会为true,有堆参与结果一定为false
4、如果拼接的结果调用intern()方法,返回值就在常量池中

		String s1 = "hello";			//s1变量记录的是"hello"常量数据在常量池中的地址
		String s2 = "world";			//s2变量记录的是"world"常量数据在常量池中的地址
		String s3 = "helloworld";		//s3变量记录的是"helloworld"常量数据在常量池中的地址
		
		System.out.println("hello" + s2 == s3);			//常量 + 变量 	结果在堆中     堆 == 常量池		false
		System.out.println(s1 + "world" == s3);			//变量 + 常量 	结果在堆中	   堆 == 常量池		false
		System.out.println(s1 + s2 == s3);				//变量 + 变量 	结果在堆中	   堆 == 常量池		false
		System.out.println("hello" + "world" == s3);	//常量 + 常量 	结果在常量池中 常量池 == 常量池	true
		
		System.out.println("================================");
		
		System.out.println("hello" + s2 == "hello" + s2);				//堆 == 堆			false
		System.out.println(s1 + "world" == s1 + "world");				//堆 == 堆			false
		System.out.println(s1 + s2 == s1 + s2);							//堆 == 堆			false
		System.out.println("hello" + "world" == "hello" + "world");		//常量池 == 常量池		true
		
		System.out.println("*********************************");
		
		/*
		 * 	String intern():返回字符串对象的规范化表示形式。 
		 * 	分析:
		 * 		jvm会去常量池中查找是否存在该字符串常量对象:
		 * 		如果存在,则直接返回该常量对象在常量池中的地址信息
		 * 		如果不存在,则先在常量池中创建该常量对象,再返回其在常量池中的地址信息
		 */
		System.out.println(("hello" + s2).intern() == ("hello" + s2).intern());					//常量池 == 常量池		true
		System.out.println((s1 + "world").intern() == (s1 + "world").intern());					//常量池 == 常量池		true
		System.out.println((s1 + s2).intern() == (s1 + s2).intern());							//常量池 == 常量池		true
		System.out.println(("hello" + "world").intern() == ("hello" + "world").intern());		//常量池 == 常量池		true

4)字符串与其他类型的转换

①String字符串与基本数据类型的转换

1、字符串转为基本类型

String s1 = "123";
		int i = Integer.parseInt(s1);
		//类型转换:字符串转为基本类型
		String s2 = "3.14";
		double d = Double.parseDouble(s2);

2、基本类型转为字符串

int num = 123;
		//类型转换:基本类型 -> String
		String s1 = num + "";
		String s2 = Integer.toString(num);
		String s3 = String.valueOf(num);

②String字符串与包装类型的转换

1、包装类型转为字符串

Integer iObj = Integer.valueOf(123);
		//类型转换:包装类型 -> 字符串类型
		String str = iObj.toString();
		System.out.println(str);						//"123"
		System.out.println(str instanceof String);		//true

2、字符串转为包装类型

//类型转换:String -> 包装类型
			Integer iObj1 = new Integer("123");
			Double dObj = Double.valueOf("3.14");

5)String类常用方法

String类常用方法:将字符串内容转换为全大写/小写

	public static void test5(){
		/*
		 * 	将字符串内容转换为全大写/小写
			 * 	String toLowerCase():使用默认语言环境的规则将此 String 中的所有字符都转换为小写。 
			 *  String toUpperCase():使用默认语言环境的规则将此 String 中的所有字符都转换为大写。 
		 */
		String content = "Today is Friday pm";
		String newContent = content.toLowerCase();
		System.out.println(newContent);// 打印结果 today is friday pm

	

		
		newContent = content.toUpperCase();
		System.out.println(newContent);// 打印结果 TODAY IS FRIDAY PM
		System.out.println(content);// 打印结果 Today is Friday pm
	}

String类常用方法:查找字符在字符串中的位置

	public static void test4(){
		/*
		 * 	得到传入的字符串在原串中首次/最后一次出现的位置:
			 * 	int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引。 
	 			int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始。 
				int lastIndexOf(String str):返回指定子字符串在此字符串中最右边出现处的索引。 
	 			int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。 
	 			
	 		注意:
	 			从头到尾都比对不上,就返回-1
		 */
		String content = "山不在在高,有仙则名。水不在在深,有龙则灵。斯是陋室,惟吾德馨。";
		int index = content.indexOf("在");//从第0个索引开始找,在第2个索引找到  第一个在
		System.out.println(index);	//2
		
		index = content.indexOf("在", 5); //从第5个索引开始找,在第13个索引找到  第一个在
		System.out.println(index);	//13
		
		index = content.lastIndexOf("则");//从第0个索引开始找,在第19个索引找到  最后一个则
		System.out.println(index);	//19
		
		index = content.lastIndexOf("则",18);//从第18个索引开始向前找,在第8个索引找到  最后一个则
		System.out.println(index);	//8
		
		index = content.indexOf("在在");//从第0个索引开始找,在第2个索引找到  第一个  在在
		System.out.println(index);	//2
		
		index = content.indexOf("在再");//从第0个索引开始找,没找到  在再   返回-1
		System.out.println(index);		//-1
	}
	

String类常用方法:根据参数截取字符串,获得新字符串


		/*	截取字符串:
			String substring(int beginIndex):
	 		String substring(int beginIndex, int endIndex):
	 		方法的参数存在起始索引和结束索引,绝大多数情况下,都满足含头不含尾的特点
		 */
		String content = "唧唧复唧唧,木兰当户织。不闻机杼声,惟闻女叹息。";
		
		String newContent = content.substring(4);
		System.out.println(content);//打印结果 唧唧复唧唧,木兰当户织。不闻机杼声,惟闻女叹息。
		System.out.println(newContent);//打印结果 唧,木兰当户织。不闻机杼声,惟闻女叹息。

		newContent = content.substring(3, 5);
		System.out.println(newContent);//打印结果 唧唧

String类常用方法:切割字符串,返回数组

		//根据正则规则切割字符串:String[] split(String regex):根据给定正则表达式的匹配拆分此字符串。 
		//如果匹配不上,则不做任何的切割行为,将原串作为一个整体存入到数组容器中
		 
		String content = "java is a good lang,java is a nice lang";
		String regex = ",";
		String[] strs = content.split(regex);
		System.out.println(Arrays.toString(strs) + "-->" + strs.length);
		//打印结果[java is a good lang , java is a nice lang]-->3
	
		
		String[] strs2 = content.split("@");
		System.out.println(Arrays.toString(strs2) + "-->" + strs2.length);
		//打印结果[java is a good lang , java is a nice lang]-->1

String类常用方法:拼接字符串的两种方式

	//第一种
	//拼接字符串:String concat(String str):将指定字符串连接到此字符串的结尾。 
	
		String s1 = "遥想公瑾当年,";
		String s2 = "小乔初嫁了。";
		String result = s1.concat(s2);
		System.out.println(result);
	//第二种	
		System.out.println("谈笑间," + "樯橹灰飞烟灭");
	

第三章、字符串缓冲区StringBuffer和StringBuilder

1)字符串缓冲区概述

①String是不能更改的,而StringBuffer与StringBuilder则是可变的字符序列。可以看成是高级的String。二者的内部方法是一致的。
②缓冲区就是一个临时空间,它里面可以临时存储数据。缓冲区本身就是一个容器,把需要修改的字符串先存储到字符串缓冲区容器中,在容器中修改完成后存储在字符串常量池中。
③任意类型都可以存储到字符串缓冲区。注意:是将任意数据都转成字符串进行存储;容器对象提供很多对容器中的数据操作的功能,比如添加,删除,修改,查询;
④StringBuffer不提供线程同步,StringBuilder是线程同步的,StringBuilder效率不如StringBuffer,但是StringBuilder 的方法不是线程安全的(不能同步访问)。由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下会使用 StringBuilder 类。

2)StringBuffer和StringBuilder声明方式

// 默认含有16个字符的容量
StringBuffer sb1 = new StringBuffer();
//含12个字符容量的字符串缓冲区
StringBuffer sb2 = new StringBuffer(12);
// 含16+4的字符串缓冲区,"b cd"为4个字符容量
StringBuffer sb3 = new StringBuffer("b cd");

//StringBuilder 同理,就不一一举例了
StringBuilder sb = new StringBuilder("");

3)StringBuffer/StringBuilder和String类型之间的转换

//String类型--》StringBuilder
StringBuilder builder = new StringBuilder("abc");
StringBuilder builder2 = new StringBuilder("abcde");

StringBuilder类型--》String
String str = builder.toString();
String str2= new String(builder2);

4)二者的常用方法

①添加

 //空参构造
        StringBuilder sb = new StringBuilder();
         // 增操作:append和insert
        //尾部追加数据append
        sb.append("abc").append(123).append(3.14).append(true);
        System.out.println(sb);     //缓冲区对象内部数据为 ==> "abc1233.14true"

 //带参构造
        StringBuilder sb2 = new StringBuilder("helloworld");
        System.out.println(sb2);//打印结果 helloworld


        //在中间某位置插入数据 insert
        sb2.insert(5, "java");
        System.out.println(sb2); //打印结果 hellojavaworld

②删除

		StringBuilder sb = new StringBuilder("helloabc0world");
          //  删操作:delete    deleteCharAt
          
        //删除中间的"abc"数据
        sb.delete(5, 8);
        System.out.println(sb);//打印结果 hello0world
        
        //删除中间的'0'数据
		sb.deleteCharAt(5);
        System.out.println(sb);//打印结果 helloworld

③修改

  /*
      改操作:reverse
       		 setCharAt
             setLength  */
             
        String content = "上海自来水来自海上1";
        //类型转换:String -> StringBuilder
        StringBuilder sb = new StringBuilder(content);
        //将sb中的字符串内容进行反转
        sb.reverse();
//-------------------------------分割--------------------------------
        StringBuilder sb2 = new StringBuilder("helloworldjavascript");
		
        //将sb2对象的容量设置为10个长度==》setLength方法
        sb2.setLength(10);
        System.out.println(sb2);        //打印结果 "helloworld"

        //将字符串内容w 改为W==》setCharAt方法
        sb2.setCharAt(5, 'W');
        System.out.println(sb2);//打印结果 helloWorld

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/577070.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言-【指针二】-【指针运算/指针和数组】

好久不见吖&#xff0c;好啦&#xff0c;言归正传&#xff0c;这篇文章接着上篇文章的尾巴接着介绍指针相关知识哦&#xff01; 一.指针运算 &#xff08;1&#xff09;指针-整数 &#xff08;2&#xff09;指针-指针 &#xff08;3&#xff09;指针的关系运算 接下来&…

Apache Kafka - 高性能原因探究

文章目录 概述图解 概述 Kafka 的高性能主要依赖于以下几个关键因素: 分布式架构:Kafka 采用分布式集群架构,可以水平扩展到上万个节点,支持每秒处理百万级消息。持久化存储:Kafka 使用文件系统持久化存储消息,避免了数据库成为性能瓶颈,大大提高了吞吐量。顺序读写:Kafka 的…

计算机视觉:卷积核的运行过程

本文重点 我们前面从直观角度理解了卷积神经网络的卷积在特征提取的作用,本节课程我们从数学角度来看一下,卷积是如何计算的? 计算步骤 1. 将卷积核与输入图像的某一部分进行逐元素相乘。 2. 将相乘后的结果求和,得到卷积核在该部分的输出值。 3. 重复以上步骤,将卷积核…

达梦8逻辑备份导出导入dexp/dimp

逻辑导出&#xff08;dexp&#xff09;和逻辑导入&#xff08;dimp&#xff09;是 DM 数据库的两个命令行工具&#xff0c;分别用来实现对 DM 数据库的逻辑备份和逻辑还原。逻辑备份和逻辑还原都是在联机方式下完成&#xff0c;联机方式是指数据库服务器正常运行过程中进行的备…

数据结构作业4-图

图数据结构的小练习&#xff1a; 文章目录 数据结构作业4-图3 对图1所示的带权无向图。&#xff08;40分&#xff09;解&#xff1a; 4 对于图1所示的带权无向图。&#xff08;20分&#xff09;解&#xff1a; 5 已知带权有向图如下图所示&#xff0c;请利用Dijkstra算法从顶点…

基于操作系统的基础IO

1.c语言中的文件输入输出 在观看本章节的时候&#xff0c;大家可以去看看之前c语言的文件输入输出的有关博客。 好那么废话不多说之间进入本章正题: 我们都知道c程序默认会打开三个输入输出流&#xff1a; stdin&#xff1a;相当于键盘 stdout&#xff1a;相当于显示器 st…

【Linux】基本指令(四)

目录 &#x1f348;一.sort指令&#x1f348; &#x1f349;二.uniq指令&#x1f349; &#x1f34a;三.wc指令&#x1f34a; &#x1f34b;四.which指令&#x1f34b; &#x1f34e;五.whereis指令&#x1f34e; &#x1f34f;六.top指令&#x1f34f; &#x1f350;七…

【玩转 Cloud Studio】腾讯Cloud Studio 云端开发环境上手体验

目录 1、Cloud Studio简介 2、功能体验 3、Cloud Studio优点 4、总结 1、Cloud Studio简介 Cloud Studio&#xff08;云端 IDE&#xff09;是基于浏览器的集成式开发环境&#xff0c;为开发者提供了一个稳定快速的云端工作站。用户在使用 Cloud Studio 时无需安装&#xff0c;只…

【LCD应用编程】绘制点、线、矩形框

之前获取LCD屏幕参数信息时了解到&#xff0c;LCD屏是 FrameBuffer 设备&#xff0c;操作 FrameBuffer 设备 其实就是在读写 /dev/fb0 文件。除此之外&#xff0c;LCD屏上包含多个像素点&#xff0c;绘制点、线、矩形框本质是在修改这些像素点的颜色。 目录 1、定义 lcd_color…

VS+Qt — Vistual Studio 2022+Qt6安装教程以及解决Qt Vistual Studio Tools下载慢和VS无法打开.ui进行设计的问题

目录 Vistual Studio 2022下载 Qt下载 Qt Vistual Studio Tools下载 方法1 方法2 方法3 方法4 Vistual Studio 2022配置Qt6 创建Qt项目 若VS无法打开.ui进行设计 Vistual Studio 2022下载 以前因为安装库的关系&#xff0c;已经下载过VS2022了&#xff0c;详细请看这…

C++ 学习 ::【基础篇:05】:C++ 函数重载认识及使用、简单介绍:C++ 支持函数重载的原因

本系列 C 相关文章 仅为笔者学习笔记记录&#xff0c;用自己的理解记录学习&#xff01;C 学习系列将分为三个阶段&#xff1a;基础篇、STL 篇、高阶数据结构与算法篇&#xff0c;相关重点内容如下&#xff1a; 基础篇&#xff1a;类与对象&#xff08;涉及C的三大特性等&#…

CSS之基础扫盲

博主简介&#xff1a;想进大厂的打工人博主主页&#xff1a;xyk:所属专栏: JavaEE初阶 目录 文章目录 二、CSS基础语法 2.1 CSS引入方式 2.1.1 内部样式 2.1.2 外部样式 2.1.3 内联样式 2.2 CSS选择器 2.2.1 标签选择器 2.2.2 类选择器 2.2.3 id选择器 2.2.4 通配符选择器 2.2…

HNU-操作系统OS-实验Lab7

OS_Lab7_Experimental report 湖南大学信息科学与工程学院 计科 210X wolf (学号 202108010XXX) 实验目的 理解操作系统的同步互斥的设计实现;理解底层支撑技术:禁用中断、定时器、等待队列;在ucore中理解信号量(semaphore)机制的具体实现;理解管程机制,在ucore内…

动力电池管理系统(BMS)

BMS技术 目录 BMS技术 一、BMS简介 二、BMS主要功能 1、参数检测 2、剩余电量&#xff08;SOC&#xff09;估计 3、充放电控制 4、热管理 5、均衡控制 6、故障诊断 7、信息监控 8、参数标定 9、CAN总线接口 三、BMS架构组成 1、BMS的拓扑架构 1、1集中式架构的B…

JavaEE进阶(5/27)Spring Boot

目录 1.认识Spring Boot 2.Spring Boot的优点 3.SpringBoot项目创建 4.resource文件夹 和test文件夹 5.使用一个Spring Boot项目 1.认识Spring Boot Spring Boot 中的Boot 是启动引导的意思 如果Spring相比于普通java开发是从走演变到了汽车&#xff0c;那么Spring boot 相比…

【博客历程】比起方法和技巧,我更想谈质量与坚持

【博客历程】比起方法和技巧&#xff0c;我更想谈质量与坚持 文章目录 【博客历程】比起方法和技巧&#xff0c;我更想谈质量与坚持[toc]我的第一篇博客为什么坚持写博客为什么选择CSDN何为质量未来 还没准备好&#xff0c;等我怎样怎样时再 还在犹豫什么时候开始&#xff0c;…

ssm+springboot+java高校图书馆图书借阅座位预约管理系统系统

陕理工图书馆管理系统包括多个功能模块&#xff1a;图书类别管理模块、图书管理模块、读者管理模块、借阅管理模块、预约管理、推荐管理。管理员登入后&#xff0c;维护图书借阅的信息。本文介绍了使用Java技术开发陕理工图书馆管理系统的设计与实现过程&#xff0c;首先对实现…

微信小程序 java+nodejs+vue美食定制个性化点餐推荐系统

社会的发展和科学技术的进步&#xff0c;互联网技术越来越受欢迎。手机也逐渐受到广大人民群众的喜爱&#xff0c;也逐渐进入了每个用户的使用。手机具有便利性&#xff0c;速度快&#xff0c;效率高&#xff0c;成本低等优点。 因此&#xff0c;构建符合自己要求的操作系统是非…

Deathnote

Deathnote 1.主机发现 arp-scan -l2.扫描端口 nmap -Pn -sV -P- -A 192.168.80.132开放了80、22端口 3.访问80端口 修改host文件访问80端口时进行了跳转到deathnote.vuln/wordpress&#xff0c;修改hosts文件&#xff0c;将该域名解析到靶机ip windows hosts文件路径&…

canal server 标准化集群搭建(完结)

4.2. 创建 server 所属集群&#xff1a;选择刚才添加的 “集群名称” server 名称&#xff1a; server_1、server_2、server_3 依次类推 server ip&#xff1a;server 的 ip 地址 admin 端口&#xff1a;canal server 与 canal admin 的通信端口&#xff0c;非生产环境从 2…