网站首页 包含标签 Java面试 的所有文章

  • Java String面试题汇总

    文章目录 Java中String是关键字吗? 为什么String是不可变的? 什么是字符串常量池? 什么是String intern()? 如何使用正则表达式查找匹配的字符串? 如何比较两个字符串? Java中的字符串是如何工作的? 如何检查回文字符串? 如何在字符串中删除或替换字符? 如何将字符串转换为小写或大写? 我们可以在’ switch ‘语句中使用String吗? 如何打印一个字符串的所有排列组合? 如何翻转字符串中的每个单词? 如何分割一个字符串? 为什么不应该使用字符串来存储密码? 字符串是线程安全的吗? 为什么String是HashMap键的最佳选择? String、StringBuffer和StringBuilder之间有什么区别? 如何连接多个字符串? 统计给定程序中的字符串对象数量 统计字符串中每个字符的出现次数? 在不使用 StringBuilder 或 StringBuffer 的情况下反转字符串? 总结 给定的Java String面试问题涵盖了字符串方法、字符串不可变性和内存泄漏问题,以及简单的示例和用例。我将尽力涵盖Java面试中最常问的String类相关问题。 Java中String是关键字吗? 不是的。String不是Java中的保留关键字。它是一种派生数据类型,也就是一个类。 public class StringExample { public static void main(String[] args) { Integer String = 10; System.out.println(String); //输出 10 } } 为什么String是不可变的? 第一个原因是性能改进。Java语言的开发旨在加快应用程序的开发速度,因为在之前的语言中它的速度不是那么快。JVM的设计者必须足够聪明,能够识别到实际应用程序将主要由字符串组成,这些字符串是标签、消息、配置、输出和其他形式的数据。看到这种过度使用,他们想象了字符串的不当使用可能有多危险。因此,他们提出了字符串池的概念。字符串池实际上是一组大部分是唯一的字符串。字符串池背后的基本思想是一旦创建了字符串,就可以重用它。这样,如果在代码中创建了一个特定的字符串20次,应用程序只有一个实例。 我认为第二个原因是安全性考虑。字符串是Java编程的各个方面中最常用的参数类型。无论是加载驱动程序还是打开URL连接,都需要将信息作为字符串参数传递。如果字符串不是不可变的,就会引发一系列安全性问题。 什么是字符串常量池? 字符串常量池是常规堆内存中的一块特定内存区域,用于存储这些字符串常量。在应用程序的生命周期中,字符串变量引用这些常量。 在Java中,我们可以通过多种方式创建字符串。例如,使用字符串字面值和使用new关键字。 String str1 = "abc"; String str2 = new String("abc"); 使用字符串字面值会导致JVM验证是否已经存在一个与字符串”abc”(相同的字符序列)。如果存在这样的字符串,JVM会将现有对象的引用赋给变量str;否则,将创建一个新的对象”abc”,并将其引用赋给变量str1。 当使用new关键字时,Java会在正常的堆内存中创建一个新的String对象。我们必须使用intern方法将字符串从堆内存移到字符串池中。 为了更好地利用内存并提高性能,建议使用字符串字面值来创建字符串。除非需要显式复制原始字符串,否则不需要使用构造函数,因为字符串是不可变的。 什么是String intern()? 当调用String的intern()方法时,如果字符串池已经包含与此字符串相同内容的字符串(由equals()方法确定),则返回池中的引用。否则,将此String对象添加到池中,并返回池中此新String对象的引用。 简单来说,字符串池化是将一个String对象从常规堆内存移动到字符串常量池中,并使用池中的对象引用的过程。 String str = new String("abc"); str.intern(); 对于intern()方法,对于任何两个字符串s1和s2,只有当s1.equals(s2)为true时,s1.intern() == s2.intern()才为true。 这意味着如果s1和s2是不同的字符串对象,并且具有相同的字符序列,那么在两者上调用intern()将导致由两个变量引用的单个字符串池字面值。 默认情况下,请记住所有字面字符串和具有字符串值的常量表达式都会被池化。 如何使用正则表达式查找匹配的字符串? 我们可以使用Pattern和Matcher API进行正则表达式匹配。String类提供了自己的matches()方法。我们应该直接使用matches()方法。该方法在函数定义内部也使用Pattern.matches()。 String str = new String("Welcome to panziye.com"); System.out.println(str.matches("(.*)ziye(.*)")); //Prints true System.out.println(Str.matches("(.*)www(.*)")); //Print false 如何比较两个字符串? 面试中的另一个受欢迎的领域。通常有两种比较对象的方法: 使用==运算符 使用equals()方法 ==运算符用于比较对象引用。因此,如果两个字符串对象引用字符串池中的相同字面值或堆中的相同字符串对象,则’s == t’将返回true,否则返回false。 equals()方法在String类中被重写,并验证String对象所持有的字符序列。换句话说,equals()方法比较字符串对象的值。如果它们存储相同的字符序列,’s.equals(t)’将返回true,否则返回false。 Java中的字符串是如何工作的? 与其他编程语言一样,Java中的字符串是字符序列。这更像是一个用于处理该字符序列的实用类。这个字符序列以char数组类型的以下变量维护: /** 值使用char 数组存储 */ private final char value[]; 各种字符串方法在不同的情况下使用以下变量来维护数组中的位置: /** 偏移量(offset)是存储中首个被使用的索引。*/ private final int offset; /** 计数(count)是字符串中字符的数量。 */ private final int count; 如何检查回文字符串? 如果一个字符串的值在反转后仍然相同,那么它就是回文字符串。要检查回文字符串,可以将字符串反转,然后将其与原始字符串进行比较。 如果原始字符串和反转后的字符串相同,那么给定的字符串就是回文字符串。 String originalString = "abcdcba"; StringBuilder strBuilder = new StringBuilder(originalString); String reverseString = strBuilder.reverse().toString(); boolean isPalindrame = originalString.equals(reverseString); System.out.println(isPalindrame); //true 如何在字符串中删除或替换字符? 要替换或删除字符,可以使用String.replace()或String.replaceAll()方法。 这两种方法都接受两个参数。第一个参数是要替换的字符,第二个参数是要放入字符串中的新字符。 如果想删除字符,可以在第二个参数中传递空字符。 String originalString = "howtodoinjava"; //Replace one character System.out.println( originalString.replace("h", "H") ); //Howtodoinjava //Replace all matching characters System.out.println( originalString.replaceAll("o", "O") ); //hOwtOdOinjava //Remove one character System.out.println( originalString.replace("h", "") ); //owtodoinjava //Remove all matching characters System.out.println( originalString.replace("o", "") ); //hwtdinjava 如何将字符串转换为小写或大写? 要将字符串转换为小写或大写,可以使用String.toLowerCase()和String.toUpperCase()方法。 String blogName = "PanZiYe.com"; System.out.println(blogName.toLowerCase()); //panziye.com System.out.println(blogName.toUpperCase()); //PANZIYE.COM 我们可以在’ switch ‘语句中使用String吗? 可以,自Java 7以来,我们可以在switch语句中使用String类。在Java 7之前,这是不可以的,我们必须使用if-else语句来实现类似的功能。 如何打印一个字符串的所有排列组合? 排列是将字符元素重新排列,以使每个排列在其他排列方面都是唯一的。例如,下面是字符串“ABC”的排列 – ABC、ACB、BAC、BCA、CBA 和 CAB。 长度为N的字符串有N!(N阶乘)个排列。 import java.util.HashSet; import java.util.Set; public class StringExample { public static void main(String[] args) { System.out.println(getPermutations("ABC")); //Prints //[ACB, BCA, ABC, CBA, BAC, CAB] } public static Set<String> getPermutations(String string) { //All permutations Set<String> permutationsSet = new HashSet<String>(); // invalid strings if (string == null || string.length() == 0) { permutationsSet.add(""); } else { //First character in String char initial = string.charAt(0); //Full string without first character String rem = string.substring(1); //Recursive call Set<String> wordSet = getPermutations(rem); for (String word : wordSet) { for (int i = 0; i <= word.length(); i++) { permutationsSet.add(charInsertAt(word, initial, i)); } } } return permutationsSet; } public static String charInsertAt(String str, char c, int position) { String begin = str.substring(0, position); String end = str.substring(position); return begin + c + end; } } 如何翻转字符串中的每个单词? 要分别翻转每个单词,首先要对字符串进行分词,将所有单词分隔成一个数组。然后,对每个单词应用翻转单词的逻辑,最后将所有单词连接起来。具体代码可以参考:反转字符串中的单词 如何分割一个字符串? 使用String.split()方法,该方法会根据给定的正则表达式来分割字符串。它也被称为根据分隔符获取字符串标记。 split()方法返回一个字符串数组,数组中的每个字符串都是一个独立的标记。 为什么不应该使用字符串来存储密码? 我们知道在Java中,字符串存储在常量池中。一旦一个字符串被创建在字符串池中,它会一直在池中存在,除非被垃圾回收。在这段时间内,任何恶意程序都可以访问物理内存中的内存区域并访问字符串数据。 如果我们将密码存储为一个字符串,它将在内存中保留的时间比所需的时间长,因为垃圾收集周期是不可预测的。这会使敏感的密码字符串容易受到黑客攻击和数据盗窃的威胁。 有人可能会提出一个观点,即在使用后将字符串设置为空。但是,这是不可行的,因为我们知道一旦一个字符串被创建,就无法操纵它,例如无法更改它的内容。字符串是不可变的。 但是,字符数组是可变的,我们可以在使用后覆盖它们的内容。因此,我们的应用程序应该使用char[]来存储密码文本,并在使用密码后替换数组内容为空白。 总之,使用char[]而不是字符串来存储密码是更安全的做法,因为它可以在使用后覆盖密码,减少了敏感信息被恶意访问的风险。这是更好的密码安全实践。 String password = "123456"; //不能使用字符串 char[] passwordChars = new char[4]; //从数据库等系统中获取密码。 //使用密码 for(char c : passwordChars) { c = ' '; } 字符串是线程安全的吗? 是的,字符串是线程安全的,因为它们是不可变的。 请记住,所有不可变的实例都是线程安全的,这是它们的设计特点。 为什么String是HashMap键的最佳选择? 在Java中,Map的键必须是不可变的,并且应该遵守equals()和hashCode()方法之间的约定。String类满足这两个条件。 此外,String类提供了许多有用的方法,用于比较、排序、分词或大小写转换。在对Map执行CRUD操作时,可以使用这些方法。 所有这些特点使得String类非常适合用作Map中的键,而不是创建我们自己的类。 String、StringBuffer和StringBuilder之间有什么区别? String类表示字符序列,并提供了处理字符的有用方法。String类的实例是不可变的。因此,每次我们使用String类进行字符串连接时,都会创建一个新对象,其中包含连接后的字符串。 StringBuilder类用于以更节省内存的方式执行字符串连接操作。它在内部维护char[],只在这个数组中操作内容。当我们在执行所有操作后需要获取完整的连接字符串时,它会使用存储的字符数组创建一个新的String。 StringBuffer与StringBuilder类非常相似,唯一的区别是它是线程安全的,它的所有方法都是同步的。 如何连接多个字符串? 根据是否需要线程安全,使用StringBuffer或StringBuilder类。在这两个类中,使用append()方法来连接字符串。 统计给定程序中的字符串对象数量 String s1 = "panziye.com"; String s2 = "panziye.com"; String s3 = new String("panziye.com"); 上面的代码将创建2个对象。 第一条语句将在字符串池中创建第一个字符串字面量。 第二条语句不会创建任何新对象,s2将引用与s1相同的字符串常量。 第三条语句将在堆内存中创建一个新的字符串对象。 统计字符串中每个字符的出现次数? 要找出给定字符串中每个字符的出现次数,我们使用了HashMap,其中字符作为键,其出现次数作为值。 每次字符出现新的次数时,我们将增加该字符的计数值。代码实现可以参考《Java中查找字符串中的重复字符》 在不使用 StringBuilder 或 StringBuffer 的情况下反转字符串? 反转字符串的最佳方法是使用 StringBuffer.reverse() 和 StringBuilder.reverse() 方法。尽管如此,面试官可能会要求您编写自己的程序,以检查您的技能水平。 请使用下面给出的基于递归的示例来反转字符串。 该程序从字符串中取出第一个字符,并将其放置在字符串的最后位置。它使用这种替换方式来反转字符串中的所有字符,直到整个字符串被反转。 具体代码实现可以参考:《基于递归的示例来反转字符串》 总结 以上就是我认为面试时经常被问到的关于String类问题,希望对你的面试有帮助。如果你知道更多关于Java String面试题问题,可以留言。 ...

    2023-09-16 186
  • 谈谈hashCode()和equals()的区别

    Java面试题:请你谈谈hashCode()和equals()的区别是什么?为什么重写equals()就要重写hashCode()? 得分点:hashCode() 用途,equals() 用途,hashCode()、equals() 约定 标准回答: 在Java中,hashCode() 方法的主要用途是获取对象的哈希码,而 equals() 方法主要用来比较两个对象是否相等。这两个方法之间存在两个约定: 约定一:相等对象必须具有相同的哈希码 如果两个对象被认为相等,那么它们必须具有相同的哈希码。这意味着如果 equals() 方法返回 true,那么这两个对象的 hashCode() 值也必须相等。 约定二:相等的哈希码不一定表示相等的对象 两个对象的哈希码相等不一定意味着这两个对象相等。换句话说,如果两个对象的 hashCode() 值相等,它们仍然需要通过 equals() 方法进行进一步的比较来确定是否相等。 另外,需要注意的是,默认情况下,Object 类提供的 equals() 方法使用 == 运算符来比较两个对象,即只有两个对象是同一个对象时,才会返回相等的结果。然而,在实际业务中,通常的需求是,如果两个不同的对象的内容相同,就应该认为它们相等。因此,通常需要重写 equals() 方法,以满足业务需求。 由于 hashCode() 方法与 equals() 方法具有联动关系,因此在重写 equals() 方法时,通常也需要重写 hashCode() 方法,以确保这两个方法始终满足上述两个约定。这有助于维护对象在哈希表等数据结构中的正确行为。 ...

    2023-09-01 327
  • 谈谈==与equals()的区别

    文章目录 得分点 标准回答 Java面试题:谈谈==与equals()的区别? 得分点 == 和 equals() 比较基本变量用法,== 和 equals() 对比引用变量的用法 标准回答 在Java中,== 和 equals() 都是用于判断两个变量是否相等的方式。以下是它们的用法: 基本变量的比较: 使用 == 运算符比较两个基本类型的变量。如果两者都是数值类型(不一定需要数据类型完全相同),只要它们的值相等,== 运算符将返回 TRUE。 引用变量的比较: 对于两个引用变量,只有当它们指向同一个引用时,== 运算符才会返回 TRUE。这意味着它们引用的是同一个对象。 equals() 方法: equals() 方法是 Object 类提供的一个实例方法,因此所有的引用变量都可以调用 equals() 方法来判断它们是否相等。 默认情况下,equals() 方法与 == 运算符没有区别,它同样要求两个引用变量指向同一个对象才会返回 TRUE。 但是,如果我们希望自定义判断相等的标准,可以通过重写 equals() 方法来实现。重写 equals() 方法时,相等条件是由业务要求决定的,因此 equals() 方法的实现是由业务要求决定的。这允许我们根据对象的属性或其他条件来定义相等性。 更多关于==与equals()的区别的深入说明,请参考文章《Java String equals()方法》 ...

    2023-09-01 320
  • 请你谈谈Java 8的新特性有哪些

    Java面试题:请你谈谈Java 8的新特性有哪些? 得分点:Lambda表达式、Java 8对接口的改进 标准回答: Java 8 是一个具有丰富特性的版本,其中引入了许多重要的改进。以下是其中几个关键特性: Lambda表达式: Lambda 表达式是 Java 8 中引入的一项重要特性,它允许将功能视为方法参数,或将代码视为数据。使用 Lambda 表达式,我们可以更简洁地表示单一方法接口(称为函数接口)的实例,从而实现更灵活的编程。 方法引用: 方法引用是 Java 8 中的另一个有用的语法,它允许直接引用已有的 Java 类或对象(实例)的方法或构造函数。与 Lambda 表达式结合使用,方法引用可以使代码更加紧凑和清晰,减少了冗余代码。 Java 8对接口的改进: Java 8 允许在接口中定义默认方法,这些方法必须使用 default 关键字修饰。这个特性的引入使得在现有接口中添加新方法变得更加容易,而不会破坏现有的实现类。 Stream API: Java 8 引入了新的 Stream API(java.util.stream),它支持对元素流进行函数式操作。Stream API 与 Collections API 集成,可以对集合进行批量操作,例如顺序或并行的 map-reduce 转换,使得处理数据集合更加方便和高效。 Date Time API: Java 8 引入了强大的 Date Time API,用于更有效地处理日期和时间。这个 API 提供了丰富的类和方法,用于解决以前在 Java 中处理日期和时间时常见的问题,使得日期和时间处理更加简便和可靠。 ...

    2023-09-01 356
  • 一位00后程序员面试近2个月的经验总结

    文章目录 首先,不要裸辞,不要裸辞,不要裸辞 第三,要对预期薪资和被拒原因有所了解 第四,锚定薪资 第五,要准备好涨薪的说辞 第六,要主动询问,预判结果 第七,不断迭代升级 总结 最近我读了一些关于找工作的文章,特别是一位00后找工作的经历,历时2个月,使用了各种途径,也遇到了各类公司。读完之后,我深感新一代的年轻人令人钦佩。他们在找工作过程中运用了许多技巧,避免了许多坑,也掌握了一些要点,我将其中的一些经验总结如下,供大家参考。 首先,不要裸辞,不要裸辞,不要裸辞 这是非常重要的。在当前的市场环境下,找工作时千万不要轻率地辞去现有的工作。裸辞会带来被动、心态不稳和议价权缺失等问题。如果手头没有备选工作,没有收入来源,而且对未来的工作也没有明确的计划,那么你会陷入非常被动的境地。无论是面试还是谈薪资,你都处于劣势。一旦找工作的时间过长,超过一个月甚至更久,你可能会陷入自我怀疑的情绪中,同时,下家公司也会根据你的找工作空档期来评估你的能力。 其次,内推是首选通道。这位00后的前端工程师在找工作时不仅使用了传统的招聘网站,还在技术平台和技术社区发表文章,寻求内推机会。他通过这些渠道获得了20多个内推机会。只要你的思路足够开阔,你就能比别人拥有更多的优势。与直接投简历相比,通过技术平台和社交平台的内推能更好地展示自己,更快地与公司拉近距离。在简历筛选过程中,你已经脱颖而出。 第三,要对预期薪资和被拒原因有所了解 在找工作的过程中,除了能力本身之外,大多数被拒的原因是期望薪资过高。许多HR也会直接告诉你:今年市场不景气,求职者众多,许多公司都在降低成本,如果你是在互联网红利时期,你的薪资期望是可以的,但现在可能就不太可能了。当然,这些原因一方面是HR的议价技巧,另一方面也反映了市场现实。 第四,锚定薪资 在简历中,不要写具体的数字,而是给出一个薪资范围,其中最低值是你理想的薪资。当面试结束后,了解具体的福利待遇、工作节奏和奖金等情况后,再根据自己的预期和面试情况进行调整。这样的调整也是试探市场,了解自己目前能够获得的薪资范围。最好是在拿到一个offer之后,再适当地上调一部分。 第五,要准备好涨薪的说辞 当HR问你为什么要提高薪资时,比如,HR会问,你上家公司才12k,现在希望18k,为什么涨幅会这么高呢?你可以回答说,经过几年的努力和业务积累,你的技术水平和业务逻辑显著提高,可以创造更大的价值。同时,你对这个行业非常热爱,平时80%的业余时间都用来学习和提升自己。另外,你也可以根据公司的工作强度、业务复杂度和挑战程度来说明涨薪的理由。 第六,要主动询问,预判结果 在找工作的过程中,许多人在回复“等消息”之后就只是等待,而有一部分求职者会在一段时间后主动询问HR和面试官,以获得更多的预判信息。甚至可以询问没有获得offer的原因,以备后续找工作时使用。在这个过程中,你实际上可以争取到更多的机会,甚至能够扭转公司正在犹豫的结果,你的主动行为会为你带来更多的机会。 第七,不断迭代升级 无论是面试中遇到的技术问题还是其他问题,面试后都需要进一步学习,为下一次面试做准备。对于面试中不懂的内容,可以查阅资料,咨询专家,动手实践等等,甚至可以整理成文章。无论采取何种形式,都是对面试过程的回顾和总结,不断迭代,让自己做好下一次面试的准备。 总结 总之,找工作的过程中还有许多其他注意事项,需要不断总结和迭代。学习他人的面试经验,提前做好准备,形成自己的面试方法论,能够让你脱颖而出。面试前后的努力往往比工作中的努力更重要,因为选择错误会大打折扣。最后,希望大家都能够获得满意的工作机会。 ...

    2023-08-23 195

联系我们

在线咨询:点击这里给我发消息

QQ交流群:KirinBlog

工作日:8:00-23:00,节假日休息

扫码关注