java程序员面试笔记day03

1.字符串的字面量是否自动生成一个字符串的变量?

String  str1  =  “abc”;

Sring  str2  =   new String (“abc”);

对于str1:Jvm在遇到双引号时会创建一个String对象,该String对象代表的值是abc,实际上,在创建该对象之前会在String对象池中搜索该字符串对象是否已经被创建,如果已经被创建,就直接返回一个字符串的引用,否则先创建再返回一个引用。

对于str2:需要的额外的工作是:会创建一个新的的string对象,通过new关键字来实现,并且返回一个引用给str2.

Str1==str2会返回false,因为指向的并不是同一个引用。

equals方法会进行字符序列的比较,则会返回true.

2.字符串对象池的作用是什么?

java虚拟机在启动的时候会实例化9个对象池,用来存储8种基本数据类型的包装类对象和String对象。

作用:避免频繁的创建和撤销对象而影响系统的性能。

例子:

 1 package test;
 2
 3 import java.util.HashSet;
 4
 5 class Dog{
 6
 7 public Dog(String name, int age) {
 8
 9 super();
10
11 this.name = name;
12
13 this.age = age;
14
15 }
16
17 private String name;
18
19 private int age;
20
21 private static HashSet<Dog> pool = new HashSet<Dog>();
22
23 //使用对象池得到对象的方法
24
25 public static Dog newInstance(String name,int age){
26
27 for(Dog dog :pool){
28
29 if(dog.name.equals(name)&&dog.age==age){
30
31 return dog;
32
33 }
34
35 }
36
37 //否则实例化一个新的dog
38
39 Dog dog = new Dog(name,age);
40
41 pool.add(dog);
42
43 return dog;
44
45 }
46
47 }
48
49 public class Main {
50
51 public static void main(String[] args) {
52
53 Dog dog1 = Dog.newInstance("xiaobai",1);
54
55 Dog dog2 = Dog.newInstance("xiaobai", 1);
56
57 Dog dog3 = new Dog("xiaobai",1);
58
59 System.out.println(dog1==dog2);
60
61 System.out.println(dog1==dog3);
62
63 }
64
65 }

本质理解:如果调用了new方法,则返回false,因为对象有了新的引用,如果没有调用new方法,就引用的是同一个对象,则返回true.

3.StringBuffer和StringBuilder的区别和应用场景?

java的String对象是不变性,只能被创建,但是不能改变其中的值。

 1 Demo1:
 2
 3 package test;
 4
 5 public class Main {
 6
 7 public static void main(String[] args) {
 8
 9 String a  = "a";
10
11 String b  = "b";
12
13 String c = "c";
14
15 //采用这种方式,可以创建5个对象
16
17 String abc = a+b+c;
18
19 //使用stringbuffer可以解决性能问题
20
21 //如果要保证是线程安全的,用stringbuilder
22
23 StringBuffer sb = new StringBuffer();
24
25 sb.append(a);
26
27 sb.append(b);
28
29 sb.append(c);
30
31 }
32
33 }
34
35 Demo2:
36
37 1 String s = "abcd";
38     2 s = s+1;
39     3 System.out.print(s);// result : abcd1

首先创建对象s,赋予一个abcd,然后再创建一个新的对象s用来执行第二行代码,也就是说我们之前对象s并没有变化,所以我们说 String类型是不可改变的对象了,由于这种机制,每当用String操作字符串时,实际上是在不断的创建新的对象,而原来的对象就会变为垃圾被GC回收掉,可想而知这样执行效率会有多低。

而StringBuffer与StringBuilder就不一样了,他们是字符串变量,是可改变的对象,每当我们用它们对字符串做操作时,实际上是在一个对象上操作的,这样就不会像String一样创建一些而外的对象进行操作了,当然速度就快了。

1 Demo3:
2
3 1 String str = “This is only a” + “ simple” + “ test”;
4 2 StringBuffer builder = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);

你会很惊讶的发现,生成str对象的速度简直太快了,而这个时候StringBuffer居然速度上根本一点都不占优势。其实这是JVM的一个把戏,实际上:

1 String str = “This is only a” + “ simple” + “test”;

其实就是:

String str = “This is only a simple test”;

所以不需要太多的时间了。但大家这里要注意的是,如果你的字符串是来自另外的String对象的话,速度就没那么快了,譬如:

string str2 = “This is only a”;

String str3 = “ simple”;

String str4 = “ test”;

String str1 = str2 +str3 + str4;

这时候JVM会规规矩矩的按照原来的方式去做。

Demo4:

StringBuilder与 StringBuffer

    StringBuilder:线程非安全的

    StringBuffer:线程安全的

  当我们在字符串缓冲去被多个线程使用是,JVM不能保证StringBuilder的操作是安全的,虽然他的速度最快,但是可以保证 StringBuffer是可以正确操作的。当然大多数情况下就是我们是在单线程下进行的操作,所以大多数情况下是建议用StringBuilder而不 用StringBuffer的,就是速度的原因。

4.如何输出反转后的字符串?

三种方式的实现:

 1 package test;
 2
 3 public class Main {
 4
 5 public static void main(String[] args) {
 6
 7 String s = "hello world";
 8
 9 for(int i =s.length();i>0;i--){
10
11 System.out.print(s.charAt(i-1));
12
13 }
14
15 System.out.println();
16
17 System.out.println("--------------");
18
19 char[] array = s.toCharArray();
20
21 for(int i = array.length;i>0;i--){
22
23 System.out.print(array[i-1]);
24
25 }
26
27 System.out.println();
28
29 System.out.println("--------------");
30
31         StringBuffer buff = new StringBuffer(s);
32
33         System.out.println(buff.reverse().toString());
34
35 }
36
37 }

5.如何利用指定的字符集创造String对象?

不论是字符串的字面量,还是用String的构造方法创造字符串对象,都不会指定特定的字符集。平台的默认字符集是GBK或者GB2312,当我们用输入法输入中文后,这些中文的默认编码是GBK,但是JVM在编译的时候会按照unicode进行重新的编码。

利用特定的字符集进行编码:

 1 package test;
 2
 3 import java.io.UnsupportedEncodingException;
 4
 5 public class Main {
 6
 7 public static void main(String[] args) throws UnsupportedEncodingException {
 8
 9 String s = "哈哈哈";
10
11 String b = new String(s.getBytes(),"GBK");
12
13 String c  = new String(s.getBytes(),"UTF-8");
14
15 System.out.println(b);
16
17 System.out.println(c);
18
19
20
21 }
22
23 }
24
25 结果:哈哈哈  ??????

解释:实际上是对原有的字符串先转换为字节数组,然后用一种新的编码方法进行二次编码。

6.如何理解数组在java中作为一个类?

数组属于引用类型,每一个数组实例都是一个对象,这些对象同属于一个类。

java数组的实质是一个类,该类还保存了数据类型的信息。该类通过成员变量的形式保存数据,并且通过[],使用下标来访问这些数据,在处理基本数据类型时,数组保存的是变量的值,如果初始化,系统为之初始化为0;处理引用类型的数据时数组保存的书数据的引用,默认初始化为null.

7.new Object[5]语句是否创建了5个对象?

并没有创建5个对象,只是开辟了存放五个对象的内存空间。

Object[] objarr = new Object[5];

创建一个存储object的数组,长度为5,这5个元素的值都为null,只有为这些元素分别赋予了具体的对象,才会使得元素指定特定的引用。

8.二维数组的长度是否固定?

实质:先创建一个一维数组,然后该数组的元素再引用另外一个一维数组,在使用二维数组时,通过两个中括号来访问每一层维度的引用,直到访问到最后的数据。

二维数组的长度没必要去指定,他们的长度是各异的。

Int[][] arr = new int[3][];

第一维的长度是固定的为3,但是第二维的长度却不固定,可以变。

9.深拷贝和浅拷贝?

浅拷贝:只复制一个对象,对象内部存在的指向其他对象数组或者引用则不复制

深拷贝:对象,对象内部的引用均复制

10.什么是集合?

集合代表了一种底层的机构,用来拓展数组的功能,它的每一种形式代表了某一种数据结构。

Set:无序存放,不允许重复,可以存放不同类型的对象

List:有序存放,允许重复,可以存放不同类型的对象

SoretdSet:排好序列set

sortedMap:排好序列的map

注意:所有的集合实现类都只能存放对象,如果存放基本数据类型的数据,则需要使用包装类。

11.java中的迭代器是什么?

迭代器模式又称为游标模式,提供一种方法,访问一个容器对象中的元素,但是隐藏对象的内部细节。

实际上,迭代器就是一个接口Iterator,实现了该接口的类是可迭代类。

一个列子:

 1 package test;
 2
 3 import java.util.ArrayList;
 4
 5 import java.util.Iterator;
 6
 7 import java.util.List;
 8
 9 public class Main {
10
11 public static void main(String[] args){
12
13 List<String> list = new ArrayList<String>();
14
15 list.add("hello");
16
17 list.add("world");
18
19 Iterator<String> it = list.iterator();
20
21 //hasnext判断是否有下个元素,next()用于输出下一个元素
22
23 while(it.hasNext()){
24
25 System.out.println(it.next());
26
27 }
28
29 }
30
31 }

12.java中的比较器是什么?

当用户自己自定义了一个类,这个类需要进行比较,这个时候就要使用到comparable和comparator接口。

Comparable:进行比较类需要实现的接口,仅仅包含一个CompareTo()方法,(在类中需要重写该方法)只有一个参数,返回值类型为int型,如果该返回值大于0,表示本对象大于参数对象,如果小于0,表示本对象小于参数对象,等于0,则相等。

一个例子:

 1 package test;
 2
 3 public class User implements Comparable{
 4
 5 public User(String name, int age) {
 6
 7 super();
 8
 9 this.name = name;
10
11 this.age = age;
12
13 }
14
15 public String getName() {
16
17 return name;
18
19 }
20
21 public void setName(String name) {
22
23 this.name = name;
24
25 }
26
27 public int getAge() {
28
29 return age;
30
31 }
32
33 public void setAge(int age) {
34
35 this.age = age;
36
37 }
38
39 @Override
40
41 public int compareTo(Object o) {
42
43 // TODO Auto-generated method stub
44
45 return this.age-((User) o).getAge();
46
47         //如果当前类的age大于参数的age 返回大于0的数
48
49 //相等则返回0
50
51 }
52
53 private String name;
54
55 private int age;
56
57 }
58
59 主函数测试:
60
61 package test;
62
63
64
65 public class Main {
66
67 public static void main(String[] args){
68
69     User   user1 = new User("hello",10);
70
71     User  user2 = new User("wwww",20);
72
73     if(user1.compareTo(user2)<0){
74
75      System.out.println("user1‘s age is smaller");
76
77     }else{
78
79      System.out.println("equal");
80
81     }
82
83 }
84
85 }

comparator也是一个接口,它的实现者被称为比较器,包含一个compare()方法,有两个参数,comparator不会被集合元素实现类所实现,而是单独实现或者是用匿名内部类实现。

一个例子:

首先自己定义一个比较器,用于比较特定的属性:

  1 package test;
  2
  3 import java.util.Comparator;
  4
  5 public class MyComparator implements Comparator {
  6
  7
  8
  9 @Override
 10
 11 public int compare(Object o1, Object o2) {
 12
 13          User u1 = (User)o1;
 14
 15          User u2 = (User)o2;
 16
 17          return u1.getAge()-u2.getAge();
 18
 19 }
 20
 21 }
 22
 23 实体类:
 24
 25 package test;
 26
 27 public class User{
 28
 29 public User(String name, int age) {
 30
 31 super();
 32
 33 this.name = name;
 34
 35 this.age = age;
 36
 37 }
 38
 39 public String getName() {
 40
 41 return name;
 42
 43 }
 44
 45 public void setName(String name) {
 46
 47 this.name = name;
 48
 49 }
 50
 51 public int getAge() {
 52
 53 return age;
 54
 55 }
 56
 57 public void setAge(int age) {
 58
 59 this.age = age;
 60
 61 }
 62
 63
 64
 65 private String name;
 66
 67 private int age;
 68
 69 }
 70
 71 测试函数:
 72
 73 package test;
 74
 75 public class Main {
 76
 77 public static void main(String[] args) {
 78
 79 User user1 = new User("hello", 10);
 80
 81 User user2 = new User("wwww", 20);
 82
 83 int res;
 84
 85     MyComparator comparator = new MyComparator();
 86
 87     res= comparator.compare(user1, user2);
 88
 89     if(res>0){
 90
 91      System.out.println("user1‘s age bigger");
 92
 93     }else if(res<0){
 94
 95      System.out.println("user2‘s age bigger");
 96
 97     }else{
 98
 99      System.out.println("equal");
100
101     }
102
103 }
104
105 }

13.Vector和arraylist的区别?

都是List接口的实现类,都代表链表形式的数据结构。

Vector是线程安全的,保证了线程安全,但是此时的执行效率会低一些,如果要求执行效率则使用arrayList.在使用方法上二者基本一样。

14.HashTable和HashMap的区别?

二者在保存元素都是无序的。

1>HashTable的方法是线程同步的,hashmap不能同步,在多线程的情况下要使用HashTable.

2>HashTable 不允许null值,key和value都不允许。HashMap允许null值,key和value都允许。

3>HashTable有一个contains方法,功能和containsvalue功能一样

4>HashTable使用Enumeration遍历,HashMap使用Iterator进行变量。

5>HashTable 中的hash数组的初始化大以及其增长方式不同

6>哈希值的使用不同,hashTable直接使用对象的HashCode,HashMap会重新计算哈希值。

如果没有要求是线程安全的,推荐使用hashMap,更符合java集合框架的设计思路。

15.集合使用泛型单来什么好处?

集合使用泛型后可以达到元素类型明确的目的,避免了手动类型转换的过程,同时也让开发者明确了容器保存的是什么类型的数据。这样,在每次从集合中取得的数据就不用每次取出一个进行类型的转换。需要注意的是,java的泛型是停在编译层的,jvm在对待泛型数据时,会依然把他们当成是object来处理,只是jvm会在底层帮助开发者完成类型的转换。

16.如何把集合对象中的元素进行排序?

vector和arraylist linkedlist本身不可以进行元素的排序。

可以使用java.utils.collections类下的sort方法进行排序。

如果列表中的全部是相同类型的数据元素,并且这个类实现了comparable接口,可以简单调用sort方法,如果没有实现comparator,就要传递一个comparator的实例作为第二个参数。

一个例子:

Student 类要实现Comparable接口,重写compareTo方法

  1 package test;
  2
  3 public class Student implements Comparable<Student> {
  4
  5 @Override
  6
  7 public String toString() {
  8
  9 return "Student [name=" + name + ", age=" + age + "]";
 10
 11 }
 12
 13 public String getName() {
 14
 15 return name;
 16
 17 }
 18
 19 public void setName(String name) {
 20
 21 this.name = name;
 22
 23 }
 24
 25 public int getAge() {
 26
 27 return age;
 28
 29 }
 30
 31 public void setAge(int age) {
 32
 33 this.age = age;
 34
 35 }
 36
 37 public Student(String name, int age) {
 38
 39 super();
 40
 41 this.name = name;
 42
 43 this.age = age;
 44
 45 }
 46
 47 @Override
 48
 49 public int compareTo(Student o) {
 50
 51         if(this.age>o.age){
 52
 53          return 1;
 54
 55         }else if(this.age<o.age){
 56
 57          return -1;
 58
 59         }else{
 60
 61          return 0;
 62
 63         }
 64
 65 }
 66
 67 private String name;
 68
 69 private int age;
 70
 71
 72
 73 }
 74
 75 测试类中按照三种方式去排序:
 76
 77 package test;
 78
 79 import java.util.ArrayList;
 80
 81 import java.util.Collections;
 82
 83 import java.util.Comparator;
 84
 85 import java.util.Iterator;
 86
 87 import java.util.List;
 88
 89 public class Main {
 90
 91 @SuppressWarnings("unchecked")
 92
 93 public static void main(String[] args) {
 94
 95 List<Student> list = new ArrayList<Student>();
 96
 97 list.add(new Student("admin", 20));
 98
 99 list.add(new Student("dddd", 30));
100
101 list.add(new Student("wwww", 60));
102
103 System.out.println("default order...");
104
105 // 默认的顺序
106
107 @SuppressWarnings("rawtypes")
108
109 Iterator it = list.iterator();
110
111 while (it.hasNext()) {
112
113 System.out.println(it.next());
114
115 }
116
117 System.out.println("desc order...");
118
119 // 降序排序
120
121 @SuppressWarnings("rawtypes")
122
123 Comparator comp = Collections.reverseOrder();
124
125 Collections.sort(list, comp);
126
127 @SuppressWarnings("rawtypes")
128
129 Iterator it1 = list.iterator();
130
131 while (it1.hasNext()) {
132
133 System.out.println(it1.next());
134
135 }
136
137 System.out.println("by name order...");
138
139
140
141 // 按照名字进行排序
142
143 Collections.sort(list, new Comparator<Student>() {
144
145 @Override
146
147 public int compare(Student o1, Student o2) {
148
149 return o1.getName().compareTo(o2.getName());
150
151 }
152
153 });
154
155 Iterator it2 = list.iterator();
156
157 while (it2.hasNext()) {
158
159 System.out.println(it2.next());
160
161 }
162
163 }
164
165 }
时间: 2024-10-04 14:22:40

java程序员面试笔记day03的相关文章

《Java程序员面试宝典》学习笔记(基本语法部分)

这是我学习欧立奇<Java程序员面试宝典>第三版的笔记.这篇是基本语法部分. ClassLoader主要对类的请求提供服务,当JVM需要某类时,它根据名称向ClassLoader要求这个类,然后由ClassLoader返回这个类的class对象. 在Java中,字符只以一种形式存在,那就是Unicode.在JVM内部一切都由Unicode表示,而输出到外部后(JVM和OS的交界处就是各种输入/输出流)转换为其他形式的编码. Java用了中间缓存变量的机制,所以,j=j++可换成如下写法: te

《JAVA 程序员面试宝典(第四版)》读书笔记之前言

工作五年了一直在小的软件公司混,总感觉自己的专业知识没有太大的提升.当然了中间也换了一两家公司,面试的公司就很多家,总感觉正规的软件公司(无论大小)对于基础知识的考核都非常重视,而不管你说你之前服务过什么NB公司,做过什么样NB的项目,上来就先拿一份基础的题目来考核你看一下你的水平.一开始我是排斥的,总感觉考这些东西没有什么用,反正有的东西工作中不一定就用得到,只要自己能够做出东西来就可以了.问题来了怎么样子才算“做出东西”呢?这个问题总感觉很难从理论上来回答,就拿我这几年工作的事情来说吧,在这

Java程序员面试体会,还没找到工作的“猿猿们”看过来!

类似的话题,我大约在几个月前跟大家聊过.这一次,我要根据这段时间的体会,再给大家整理一下. 今天,很轻松地拿到了神州数码的offer.虽然工资不是特别高,虽然很多人一毕业就能进入这样的公司,但是对我这个半路出家的大专生来说,能进去纯属意外. 今天的面试,谈到了以前我接过一些私单,项目经理问我,那你现在还有没有做私活的想法?我说,彻底没有!他问我,为什么?我说,这几年,虽然做私活挣了一些钱,但我损失的远远不止那点钱.那些重复.繁琐,很难有技术水平提升的工作,占用了我大部份的业余时间,如果这些时间用

金九银十,浅谈关于java程序员面试的一些事项

本篇博文针对的是应届毕业生以及工作两三年左右的java程序员. 为什么要跳槽? 这是一个很广义的问题,每个人心中都有一份答案. 例如: 公司的待遇不好, 薪资涨幅不符合预期要求, 厌倦了出差的荒无天日的繁重工作, 公司的妹子太少, 领导太傲娇, 同事之间关系太逼格, 某某同学跳槽到某某公司之后涨到了多少多少钱, 某某同学的朋友的同事的三姑妈家的大儿子的好基友在某某高就, 等等辞职理由. 咱们就不多说了,还是谈谈怎么应付面试吧. 以下内容是我在面试中总结的一些经验,希望这些可以给各位带来帮助和启迪

《Java程序员面试笔试宝典》之字符串创建与存储的机制是什么

在Java语言中,字符串起着非常重要的作用,字符串的声明与初始化主要有如下两种情况:(1) 对于String s1=new String("abc")语句与String s2=new String("abc")语句,存在两个引用对象s1.s2,两个内容相同的字符串对象"abc",它们在内存中的地址是不同的.只要用到new总会生成新的对象. (2) 对于String s1 = "abc"语句与String s2 = "

《Java程序员面试笔试宝典》终于在万众期待中出版啦~

<Java程序员面试笔试宝典>终于在万众期待中出版啦~它是知名畅销书<程序员面试笔试宝典>的姊妹篇,而定价只要48元哦,恰逢求职季节,希望本书的出版能够让更多的求职者能够走进理想的企业 在这里,众多知名企业面试官将为你撕开神秘的求职面纱: 在这里,各种求职达人将现身说法为你揭开求职谜团: 在这里,各种类型的企业招聘细节都会被展露无疑: 在这里,我们将为你抽丝剥茧,还原IT行业的真相: 在这里,我们将为你指点迷津,告诉你职场上的风风雨雨: 在这里,我们将为你点石成金,成为那盏指引你前

《Java程序员面试笔试宝典》之为什么需要public static void main(String[] args)这个方法

public staticvoid main(String[] args)为Java程序的入口方法,JVM在运行程序的时候,会首先查找main方法.其中,public是权限修饰符,表明任何类或对象都可以访问这个方法,static表明main方法是一个静态方法,即方法中的代码是存储在静态存储区的,只要类被加载后,就可以使用该方法而不需要通过实例化对象来访问,可以直接通过类名.main()直接访问,JVM在启动的时候就是按照上述方法的签名(必须有public与static修饰,返回值为void,且方

JAVA程序员面试总结,高手整理加强版

每个程序员.或者说每个工作者都应该有自己的职业规划,分享高手整理的java程序员面试总结给愿意思考自己未来的朋友们. 第一阶段:三年 我 认为三年对于程序员来说是第一个门槛,这个阶段将会淘汰掉一批不适合写代码的人.这一阶段,我们走出校园,迈入社会,成为一名程序员,正式从书本 上的内容迈向真正的企业级开发.我们知道如何团队协作.如何使用项目管理工具.项目版本如何控制.我们写的代码如何测试如何在线上运行等等,积累了一定的 开发经验,也对代码有了一定深入的认识,是一个比较纯粹的Coder的阶段. 第二

Java程序员面试失败的5大原因

下面是Java程序员面试失败最有可能的5大原因,当然也许这5点原因适用于所有的程序员,所以,如果你是程序员,请认真阅读以下内容. #1 说得太少 尤其是那些开放式的问题,如“请介绍下你自己”或“请讲一下你曾经解决过的复杂问题”.面试官会通过你对这些技术和非技术问题的回答来评估你的激情.他们也会通过模拟团队氛围和与你的交流互动来判断你的经验和能力. 所以,仅仅只用两三句话来回答不但不能显示出你对这个专业的兴趣,还会让整个面试过程显得非常无聊.如果你不能很好地说明你的经验.成就和技能可以给企业带来的