java 面试总结(都是亲身面试的经历)

  • 时间:
  • 浏览:26
  • 来源:跟我学网络

一、如何比较两个对象,比如学生类,根据属性年龄比较大小

import java.util.*;
public class Demo10 {
	public static void main(String[] args) {
		Person p1 = new Student(9, "m", "gd", "广");
		Person p2 = new Student(3, "m", "gd", "广");
		Person p3 = new Student(5, "m", "gd", "广");
		List<Person> list = new ArrayList<Person>();
		list.add(p1);
		list.add(p2);
		list.add(p3);
		//排序
		Collections.sort(list);
		for (int i = 0; i < list.size(); i++) {
			Person p = (Person) (list.get(i));
			System.out.println(p.getAge());
		}
	}
}
class Person implements Comparable {
	private int age;
	//龄
	private String sex;
	//性别
	private String placeOfOrigin;
	//籍贯
	public int getAge() {
		return this.age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getSex() {
		return this.sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public String getPlaceOfOrigin() {
		return this.placeOfOrigin;
	}
	public void setPlaceOfOrigin(String placeOfOrigin) {
		this.placeOfOrigin = placeOfOrigin;
	}
	//实现Comparable接口
	public int compareTo(Object obj) {
		Person p = (Person) obj;
		if (this.age > p.age) {
			return 1;
		} else if (this.age == p.age) {
			return 0;
		} else {
			return -1;
		}
	}
}
class Student extends Person {
	private String school;
	//读校
	public Student(int age, String sex, String placeOfOrigin, String school) {
		setAge(age);
		setSex(sex);
		setPlaceOfOrigin(placeOfOrigin);
		this.school = school;
	}
	public String getSchool() {
		return this.school;
	}
	public void setSchool(String school) {
		this.school = school;
	}
}
class CollegeStudent extends Person {
	private String tutor;
	//导师
	private double subsidy;
	//补助
	public String getTutor() {
		return this.tutor;
	}
	public void setTutor(String tutor) {
		this.tutor = tutor;
	}
	public double getSubsidy() {
		return this.subsidy;
	}
	public void setSubsidy(double subsidy) {
		this.subsidy = subsidy;
	}
}

二、给你一个set 如何根据学生类的name进行对象排序

三、给你一台服务器,要你装Tomcat,你得做什么

       在Linux上安装:上传安装包 解压之后,配置  tomcat7\conf\tomcat-users.xml,在文件的最下面,</tomcat-users>的上面添加

<role rolename="manager-gui"/>

<role rolename="manager-script"/>

<role rolename="manager"/>

<role rolename="admin-gui"/>

<user username="admin" password="admin" roles="manager-gui,manager,manager-script,admin-gui"/>

四、怎么取map中的key

        两种方法  Map 的   map.keySet();和map.entrySet();方法

测试代码:

package com.lyt.test;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class MapTest {
	public static void main(String[] args) {
		getKeySet();
		getEntrySet();
	}
	//根据Map 中的 keySet()方法获取
	public static void getKeySet(){
		System.out.println("--------keySet()方法获取-------------");
		Map map = new HashMap();
		map.put(1, "a");
		map.put(2, "b");
		System.out.println(map.keySet());
		Collection s = map.keySet();
		System.out.println(s);
		Iterator iter2 = (Iterator)map.keySet().iterator();
		while(iter2.hasNext()){
			System.out.print(iter2.next() + ", ");
		}
		System.out.println("========得到value的方法========");
		Collection c = map.values();
		System.out.println(c);
		Iterator iter1 = (Iterator)map.values().iterator();
		while(iter1.hasNext()){
			System.out.print(iter1.next() + ", ");
			//一个一个获取value值
		}
	}
	//根据Map 中的 entrySet()方法获取
	public static void getEntrySet(){
		System.out.println("--------entrySet()方法获取-------------");
		Map map = new HashMap();
		map.put(1, "a");
		map.put(2, "b");
		System.out.println(map.entrySet());
		Collection s = map.entrySet();
		System.out.println(s);
		Iterator iter2 = (Iterator)map.entrySet().iterator();
		while(iter2.hasNext()){
			System.out.print(iter2.next() + ", ");
		}
	}
}

五、hashmap是怎么存储数据的

       hashmap 实质上一个数组和链表的结合体,记得严尉敏版的C数据结构上将这个称为“散列表”。对于hashmap存储可以这样理解,数组用于存储key,链表用于存储value,每个链表都链接在数组中的一个元素上。

       arraylist 实质上就是一个顺序的动态数组,开始时以一默认值开一数组,满了后再扩容,且实现了动态添加和删除。

二者性能区别:hashmpa 用于快速查找,但是arraylist基本上不浪费空间。各有利弊吧

查看详情:http://blog.csdn.net/vking_wang/article/details/14166593

六、是不是用了maven,有对项目分过模块吧,你知道为什么要分吗?(这个没法说 自己想吧)

1、什么业务场景下我们使用递归写法,请举一个例子,并予以说明

2、dubbo、webservice或你熟悉的接口与http接口的区别?我们在做这些接口交互时应当注意什么?

webservice做接口 跟http做接口有啥区别 :协议不一样

3、为何我们在开发中要使用到序列号和反序列号,你都知道哪些序列化工具,并描述各自的优缺点

      序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决对象流读写操作时可能引发的问题(如果不进行序列化可能会存在数据乱序的问题)。要实现序列化,需要让一个类实现Serializable接口,该接口是一个标识性接口,标注该类对象是可被序列化的,然后使用一个输出流来构造一个对象输出流并通过writeObject(Object obj)方法就可以将实现对象写出(即保存其状态);如果需要反序列化则可以用一个输入流建立对象输入流,然后通过readObject方法从流中读取对象。序列化除了能够实现对象的持久化之外,还能够用于对象的深度克隆

4、列举关系型数据库和非关系型数据库的区别?对于目前nosq数据库说说它的应用场景和优势

5、简述hibernate和mybatis的区别,你偏向使用哪种,为什么?

      参见:http://blog.csdn.net/liyintaoliuyun/article/details/51446758

6、我们在使用springmvc进行开发时,是如何对数据进行封装的和校验的,对于restful的传输风格是否了解,说说它的特点

7、简述spring的事务特性?什么业务场景需要用到事务控制

8、java为什么要有垃圾回收?什么时候进行?如何进行检测内存泄漏

     GC是垃圾收集的意思,内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法。Java程序员不用担心内存管理,因为垃圾收集器会自动进行管理。要请求垃圾收集,可以调用下面的方法之一:System.gc() 或Runtime.getRuntime().gc() ,但JVM可以屏蔽掉显示的垃圾回收调用。

垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低优先级的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。在Java诞生初期,垃圾回收是Java最大的亮点之一,因为服务器端的编程需要有效的防止内存泄露问题,然而时过境迁,如今Java的垃圾回收机制已经成为被诟病的东西。移动智能终端用户通常觉得iOS的系统比Android系统有更好的用户体验,其中一个深层次的原因就在于Android系统中垃圾回收的不可预知性。

补充:垃圾回收机制有很多种,包括:分代复制垃圾回收、标记垃圾回收、增量垃圾回收等方式。标准的Java进程既有栈又有堆。栈保存了原始型局部变量,堆保存了要创建的对象。Java平台对堆内存回收和再利用的基本算法被称为标记和清除,但是Java对其进行了改进,采用“分代式垃圾收集”。这种方法会跟Java对象的生命周期将堆内存划分为不同的区域,在垃圾收集过程中,可能会将对象移动到不同区域:

  • 伊甸园(Eden):这是对象最初诞生的区域,并且对大多数对象来说,这里是它们唯一存在过的区域。
  • 幸存者乐园(Survivor):从伊甸园幸存下来的对象会被挪到这里。
  • 终身颐养园(Tenured):这是足够老的幸存对象的归宿。年轻代收集(Minor-GC)过程是不会触及这个地方的。当年轻代收集不能把对象放进终身颐养园时,就会触发一次完全收集(Major-GC),这里可能还会牵扯到压缩,以便为大对象腾出足够的空间。

与垃圾回收相关的JVM参数:

  • -Xms / -Xmx --- 堆的初始大小 / 堆的最大大小
  • -Xmn --- 堆中年轻代的大小
  • -XX:-DisableExplicitGC --- 让System.gc()不产生任何作用
  • -XX:+PrintGCDetail --- 打印GC的细节
  • -XX:+PrintGCDateStamps --- 打印GC操作的时间戳

9、你们公司的项目都用了那些框架,都用了Spring的那些核心,项目中怎么体现的

spring参照http://blog.csdn.net/lovesomnus/article/details/46470255

10、你们是如何实现分布式的

11、你用过什么缓存数据库。什么情况下需要用到

12、你在项目中用过多线程吗?你知道如何实现多线程吗?你那里为什么要用到多线程

        Java 5以前实现多线程有两种实现方法:一种是继承Thread类;另一种是实现Runnable接口。两种方式都要通过重写run()方法来定义线程的行为,推荐使用后者,因为Java中的继承是单继承,一个类有一个父类,如果继承了Thread类就无法再继承其他类了,显然使用Runnable接口更为灵活。

补充:Java 5以后创建线程还有第三种方式:实现Callable接口,该接口中的call方法可以在线程执行结束时产生一个返回值,代码如下所示:

package com.lyt.test;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
* 实现Callable接口,该接口中的call方法可以在线程执行结束时产生一个返回值
* @author Administrator
*
*/
class MyTask implements Callable<Integer> {
	private int upperBounds;
	public MyTask(int upperBounds) {
		this.upperBounds = upperBounds;
	}
	@Override
	public Integer call() throws Exception {
		int sum = 0;
		for (int i = 1; i <= upperBounds; i++) {
			sum += i;
		}
		return sum;
	}
}
public class Test {
	public static void main(String[] args) throws Exception {
		List<Future<Integer>> list = new ArrayList<>();
		ExecutorService service = Executors.newFixedThreadPool(10);
		for (int i = 0; i < 10; i++) {
			list.add(service.submit(new MyTask((int) (Math.random() * 100))));
		}
		int sum = 0;
		for (Future<Integer> future : list) {
			while (!future.isDone())
			;
			sum += future.get();
		}
		System.out.println("返回值:" + sum);
	}
}

13、你了解消息队列吗?

14、你们的项目业务量有多大?如果某张表数据量越来越大,查询会越来越慢,你会怎么处理

        写sql的时候 注意优化 不用这么多的join ,做分区做索引

下面举两个简单的例子:

图书馆的例子:一个图书馆那么多书,怎么管理呢?建立一个字母开头的目录,例如:a开头的书,在第一排,b开头的在第二排,这样在找什么书就好说了,这个就是一个聚集索引,可是很多人借书找某某作者的,不知道书名怎么办?图书管理员在写一个目录,某某作者的书分别在第几排,第几排,这就是一个非聚集索引

字典的例子:字典前面的目录,可以按照拼音和部首去查询,我们想查询一个字,只需要根据拼音或者部首去查询,就可以快速的定位到这个汉字了,这个就是索引的好处,拼音查询法就是聚集索引,部首查询就是一个非聚集索引.

    看了上面的例子,下面的一句话大家就很容易理解了:聚集索引存储记录是物理上连续存在,而非聚集索引是逻辑上的连续,物理存储并不连续。就像字段,聚集索引是连续的,a后面肯定是b,非聚集索引就不连续了,就像图书馆的某个作者的书,有可能在第1个货架上和第10个货架上。还有一个小知识点就是:聚集索引一个表只能有一个,而非聚集索引一个表可以存在多个。



SQL索引有两种,聚集索引和非聚集索引,索引主要目的是提高了SQL Server系统的性能,加快数据的查询速度与减少系统的响应时间 

创建索引的语法:

CREATE [UNIQUE][CLUSTERED | NONCLUSTERED]  INDEX  index_name  

ON {table_name | view_name} [WITH [index_property [,....n]]

说明:

UNIQUE: 建立唯一索引。

CLUSTERED: 建立聚集索引。

NONCLUSTERED: 建立非聚集索引。

Index_property: 索引属性。

 UNIQUE索引既可以采用聚集索引结构,也可以采用非聚集索引的结构,如果不指明采用的索引结构,则SQL Server系统默认为采用非聚集索引结构。

删除索引语法:

DROP INDEX table_name.index_name[,table_name.index_name]

说明:table_name: 索引所在的表名称。

index_name : 要删除的索引名称。

使用系统存储过程:sp_helpindex 查看指定表的索引信息。

执行代码如下:

Exec sp_helpindex book1;

15、在项目中可能碰到这种情况,公司要出报表了,但是后台业务还在跑,这会导致报表查询会被死锁,你有什么好的解决办法吗?

做后台业务的方法和出报表的方法做线程同步

或者后台业务处理完给个标示  然后才可以出报表(做标示比较好 个人推荐)

16、某个账户表中有N个账户,每个账户在记账的时候都会被不同的记账流程所操作进行余额更新,你是如何避免数据不一致以及死锁的?

        余额更新的方法加锁

17、你了解过restful吧,你能说说它吗?它和webservice有什么异同

       协议不一样,

如果数据类型比较复杂 用webservice

18、你了解Linux吗?如果让你修改一个文件,你怎么改?

vim 文件名.xml等等文件 执行之后进去 然后  i  就可以操作了,:qw  保存并退出

参照:http://blog.csdn.net/liyintaoliuyun/article/details/51407006

19、你们项目中对请求验证是怎么做的?