java面试题总结

1.HashMap和HashTable区别
两者都是实现Map接口
HapMap可以允许key和value都可以为null
HashTable的key或者value不能为null
HashTable为线程安全的
在hashMap的基础上,ConcurrentHashMap将数据分为多个segment,默认16个(concurrency level),
然后每次操作对一个segment加锁,避免多线程锁得几率,提高并发效率。
新版本jdk更改设计,变为cas无锁算法
HashMap:哈希表((Hash table)既满足了数据的查找方便,同时不占用太多的内容空间,使用也十分方便。哈希表也有好多种实现,最常用的一种方法---拉链法:可以理解为链表的数组(链表+数组)。
解决hash冲突的方法
  1. 开放定址法(线性探测再散列,二次探测再散列,伪随机探测再散列)
  2. 再哈希法
  3. 链地址法
  4. 建立一个公共溢出区
Java中hashmap的解决办法就是采用的链地址法

2.集合类
Conllection   Map
Collection 包含 Set和List
Set:无序不可重复
List:有序可重复
Map:key value键值对形式存在的 key值不能重复

3.线程的几种状态
就绪(Runable)--start》--  运行(Running)---wait---等待中(Waiting) ---sleep---睡眠中(Sleeping)
----Blocked----阻塞----------死亡(Dead)  

4.创建线程
实现Runable 继承Thread  实现Callable(有返回值)  

5.接口和抽象类的区别
接口的访问修饰符都是public的  抽象类的可以是public private protecte
接口是绝对抽象 不能被实例化 抽象类也不能被实例化
接口中声明的成员变量是fianl修饰的 抽象类修饰的不是fianl的
类实现接口,必须实现所有的接口中方法
类实现抽象类,如不全部实现所有方法  类必须也是抽象类
接口中的方法隐含的都是抽象的
抽象类中的方法可以是抽象的也可以是非抽象的
类可以实现多个接口  只能继承一抽象类

6.基本类型  byte short long int char double float boolean 

7.List
Array可以包含基本类型或对象类型  ArrayList只能包含对象类型
Array是不可变的  ArrayList的大小是可变的
ArrayList的查询速度快  添加删除慢  添加需要计算索引值
LinkedList的查询速度慢
存储内容比较:
  • Array数组可以包含基本类型和对象类型,
  • ArrayList却只能包含对象类型。
但是需要注意的是:Array数组在存放的时候一定是同种类型的元素。ArrayList就不一定了,因为ArrayList可以存储Object。
Array和ArrayList空间大小比较:
  • 它的空间大小是固定的,空间不够时也不能再次申请,所以需要事前确定合适的空间大小。
  • ArrayList的空间是动态增长的,如果空间不够,它会创建一个空间比原空间大一倍的新数组,然后将所有元素复制到新数组中,接着抛弃旧数组。而且,每次添加新的元素的时候都会检查内部数组的空间是否足够。

8.异常处理完成后,Execption对象会发生什么变化
下一个垃圾回收时会被回收掉

9.修饰符权限
public   protected   default   private
当前类    当前包       子孙类     其他包
public都可以  protect 除了其他包  default 当前类,当前包 private 当前类

10.final、finally
final修饰的类的不能被继承  修饰的方法不能被重写  修饰的变量不能被修改
finally try catch异常代码块  

11.单例模式(饿汉模式:不安全)
public class Singleton(){
    private Singleton(){}
    private static Singleton singele = null;
    private static synchronized Singleton getSingleton(){
        if(singleton == null)
        singleton = new Singleton();
        return singleton;
    }
}
//双重判断
publiic class Singleton()
{
    private Singleton(){}
    private static volatile Singleton singleton = null;
    
    public static Singleton getSingleton()
    {
        if(null == singleton)
        {
            synchronized(Singleton.class)
            {
                if(null == singleton)
                {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}
12.连接数据库
获取驱动
建立连接
编写语句
执行语句
返回结果
释放链接

13.找错
public class Thing(){
    void Ting(){
    final String s = "";
    int len = s.length();
    }
}
局部变量不能被final修饰
14.找错
abstract class Something { 

    private abstract String doSomething (); 

} 
方法的修饰符不能为private  因为抽象类是让子类来实现的

15.找错
abstract class Something { 

public int add(final int a){
    return ++a;
}
} 
final 修饰的变量不能被修改

16.找错
class Something { 
    int i; 
    public void doSomething() { 
        System.out.println("i = " + i); 
    } 
}  
int 的默认值为0  所以没有错
假如在int前面加final

17.找错
public class Something { 
    public static void main(String[] args) { 
        Something s = new (Something); 
        System.out.println("s.doSomething() returns " + doSomething()); 
        //不直接调用doSomething()方法
        //因为当前的main方法是static的,不能直接调用非静态方法()
    } 

    public String doSomething() { 
        return "Do something ..."; 
    } 
} 
18.找错
当前文件类名 Thing.java 
class Something { 
    private static void main(String[] something_to_do) {         
    System.out.println("Do something ..."); 
    } 
} 
Java的Class名字不一定和其文件名相同。但public class的名字必须和文件
名相同。
19.&和&& 区别    &是位运算符。&&是布尔逻辑运算符
对于:&  -- >  只要左右两边有一个为false,则为false;只有全部都为true的时候,结果为true
对于:&& -- > 只要符号左边为false,则结果为false;当左边为true,同时右边也为true,则结果为true
20.error和exception的区别
error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。
exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。

21. i++ 和 ++i 区别
{int i=0;  int j=i++;}
{int i=0; int z=++i;}
运算过后,j=0;表明i++是指先把i赋值给j然后再自身加1;
运算过后,z=1;表明++i是指先自身加1后赋值给z;
22.Java程序的种类有:
(a)内嵌于Web文件中,由浏览器来观看的_Applet 
(b)可独立运行的 Application 
(c)服务器端的 Servlets
23.Servlet的生命周期
Servlet被服务器实例化之后,容器运行其init方法,请求到达是运行service方法,service方法会自动派遣运行于请求的doget或dopost,当服务器决定将实例销毁的时候调用destroy方法
24.java的设计模式 23
分为三大类别
创建型 5 工厂方法  静态方法  建造者 原型  单例
结构型 7 装饰器 适配器 组合 代理 享元 外观 桥接 
行为型 11 迭代子 状态 模板 备忘录 解释器 责任链  观察者 命令 访问者 中介者 策略
25.线程池
Executor接口表示线程池,它的execute(Runable task)方法用来执行Runable类型的任务
Executor的子接口ExecutorService声明了管理线程池的一些方法
Executors类包含了一些静态方法,它负责生成各种类型的线程池ExecutorService的实例
Executors类生成的ExecutorService实例的静态方法
①newCachedThreadPool()     在有任务时才创建新线程,空闲线程被保留60秒
②newFixedThreadpool(int nThread) 线程池中包含固定的线程数目,,空闲线程一直会保留
③newScheduledThreadPool(int corePoolSize) 线程池能按照时间计划来执行任务,允许用户设定计划任务的时间,
参数为线程池的最小数量,当任务较多,线程池可能会创建更多的工作线程来执行任务
④newSingleThreadExecutor() 线程池创建一个工作线程,依次执行每个任务
⑤newSingleThreadScheduleExecutor() 线程池创建一个工作线程,它能按照时间计划来执行任务

ExecutorThreadPool下参数的默认队列为BlockingQueue
它的实现类有ArrayBlockingQueue、DelayQueue、LinkedBlockingQueue、SynchronousQueue等6个
具有给定(固定)容量的 LinkedBlockingQueue----②newFixedThreadpool
创建一个具有给定的(固定)容量和指定访问策略的 ArrayBlockingQueue,它最初包含给定 collection 的元素,并以 collection 迭代器的遍历顺序添加元素。
创建一个具有指定公平策略的 SynchronousQueue
26.单例模式
懒汉、饿汉、登记式、枚举、静态内部类、双重校验锁
27.六原则一法则
单一职责 依赖倒转 接口隔离 合成聚合复用 开闭 里氏替换 迪米特法则
28.jvm的内存分布
堆(java head)、栈(stack)、程序计数器(program counter register)、方法区(method area)、本地方法栈(native method stack)
29.工厂模式:将对象的创建和使用分开
30.redis和memcached区别
reids是单线程的 memached是多线程的
在redis中,并不是所有的数据都一直存储在内存中,这个和memcached相别一个最大的区别。redis只会缓存所有的key的信息,
如果redis发现内存的使用量超过了某一个阀值,Redis根据“swappability = age*log(size_in_memory)”计 算出哪些key对应的value需要swap到磁盘。
然后再将这些key对应的value持久化到磁盘中,同时在内存中清除。
1.redis不止支持简单的key/valuel类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
2.redis支持数据备份,即master-slave模式的数据备份。
3.redis支持数据持久化,可以将内存中的数据保存到磁盘中,重启的时候可以再次加载进行使用。
4.Memcached基本只支持简单的key-value存储,不支持枚举,不支持持久化和复制等功能
31.redis存储数据
putAll()-----map
entries(key)

rightPush()------list
leftPush()
range() 
32.成员量和局部变量的区别
1.成员变量定义在类中,局部变量定义在方法中
2.成员变量在当前类有效,局部变量在当前方法体中有效
3.成员变量存储在堆中,局部变量存在栈中
33.构造函数和一般函数的区别
构造函数和类名相同,在对象创建时就被调用,用于初始化,初始化只执行一次
一般函数,对象创建后需要调用才能执行,可以被调用多次
34.成员变量和静态变量的区别
1.成员变量属于对象,也成实例变量
2.静态变量属于类,也可以称类变量
3.成员变量存在堆中,静态变量存在方法区中
4.成员变量随着对象创建而存在,回收之后消失
5.静态变量类初始化而存在,随着类消失而消失
6.成员变量只能对象调用,静态变量可以被类或对象所调用
35.final特点: 可以修饰变量、方法、类
修饰的变量初是一个常量,只能赋值一次
修饰的方法不能被覆盖
修饰的类不能被继承
36.Exception、Error
Java中的异常类都继承Throwable,Throwable对象可以分为两组。一组是unchecked异常,一组是checked异常
error通常是指Java的内部错误以及资源耗尽错误,我们不能在编程层面上解决Error
exception类有特殊的衍生类RuntimeException.是java程序自身引起的,程序员在编程上犯错,该异常是可以通过java程序避免
37.多线程
可以并存于同一进程空间,在JVM的进程空间,一个stack代表了方法调用的次序。对于多线程来说,进程空间需要多个stack
用来记录不同线程的调用次序,多个stack互不影响,但所有的线程将共享堆(heap)中的对象
38.Mysql: Every derived table must have its own alias (每个派生出来的表都必须有一个自己的别名)
进行嵌套查询的时候的子查询的结果是作为一个派生类来进行上一级查询,应该在子查询的结果来加一个别名
update t_ticket_info set ticket_type = 1
        WHERE ticket_no = 
        (select minno from (select min(ticket_no) as minno from t_ticket_info where ticket_type = 0) as a)
加入不在sql最后的那个子查询 as a ,就会 出现这个错误
39.JVM
栈(stack)是运行时的单位,堆是存储的单元
栈解决程序的运行问题,即程序如何执行,或如何处理数据(栈代表处理逻辑,栈中存储的都是基本数据类型或对象的引用)
堆解决的是数据存储问题,即数据怎么放,放在那(堆代表数据)
40.创建视图
create view  user_view as select * from t_user_info
    desc user_view
41.sql优化基本常识
在where查询,=左边进行函数、运算符或表达式运算
在where中避免出现!=和<>
在where中避免对字段进行null值判断
模糊查询尽量不要前置百分号
使用exists来代替in和not in
41.数据库事务的隔离级别和特性
    MYSQL
  ① Serializable (串行化):可避免脏读、不可重复读、幻读的发生。
  ② Repeatable read (可重复读):可避免脏读、不可重复读的发生。
  ③ Read committed (读已提交):可避免脏读的发生。
  ④ Read uncommitted (读未提交):最低级别,任何情况都无法保证。
    ORACLE
    ①③
    特性:ACID 原子性 一致性 隔离性 持久性
42.springmvc原理
    1、客户端发出一个http请求给web服务器,web服务器对http请求进行解析,如果匹配DispatcherServlet的请求映射路径(在web.xml中指定),web容器将请求转交给DispatcherServlet.
    2、DipatcherServlet接收到这个请求之后将根据请求的信息(包括URL、Http方法、请求报文头和请求参数Cookie等)以及HandlerMapping的配置找到处理请求的处理器(Handler)。
    3-4、DispatcherServlet根据HandlerMapping找到对应的Handler,将处理权交给Handler(Handler将具体的处理进行封装),再由具体的HandlerAdapter对Handler进行具体的调用。
    5、Handler对数据处理完成以后将返回一个ModelAndView()对象给DispatcherServlet。
    6、Handler返回的ModelAndView()只是一个逻辑视图并不是一个正式的视图,DispatcherSevlet通过ViewResolver将逻辑视图转化为真正的视图View。
    7、Dispatcher通过model解析出ModelAndView()中的参数进行解析最终展现出完整的view并返回给客户端。
43.aop ioc
控制反转
控制权由对象转交给容器
容器根据配置文件来创建实例和各个实例之间的依赖关系
核心:BeanFactory,工厂创建的实例称作bean
面向切面编程
代理:动态代理和静态代理
静态代理:针对每个具体类来编写代理类
          针对一个接口来编写一个代理类
44.mybatis
MyBatis应用程序根据XML配置文件创建SqlSessionFactory,
SqlSessionFactory在根据配置,配置来源于两个地方,一处是配置文件,一处是Java代码的注解,
获取一个SqlSession。SqlSession包含了执行sql所需要的所有方法,可以通过SqlSession实例直接运行映射的sql语句,
完成对数据的增删改查和事务提交等,用完之后关闭SqlSession。
45.String类为什么是final修饰的
主要是为了“效率” 和 “安全性” 的缘故。若 String允许被继承, 由于它的高度被使用率, 可能会降低程序的性能,所以String被定义成final。
46.System.out.println(2/3);  0  System.out.println(3/2);  1
47.http get和post请求的区别  与head请求有什么区别
get提交:请求的通过地址栏传递参数,传参数的大小长度受浏览器限制,所传参数可见不安全
POST提交:不是通过url传递参数,是提交的是表单,把提交的数据放置在是HTTP包的包体中
48.httpsession什么时候被销毁
可以通过web.xml文件配置session的失效时间,单位为分钟
<seesion-config>    <session-timeout>10</session-timeout></seesion-config>
可以通过session.invalidate()方法来销毁session对象。
49.MD5加密
任意长度的数据,算出的MD5值长度都是固定的。
目前没有软件能有效地破解 MD5。大多数时候只是把常见字符串的 MD5 存了起来为彩虹表,然后直接反查。
50.什么是sql注入
就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令
参数化查询
51.排序
String source[] = { "dad", "bood", "bada", "Admin", "Aa ", "A ", "Good", "aete", "cc", "Ko", "Beta", "Could" };       
List<String> list = Arrays.asList(source);       
Collections.sort(list, String.CASE_INSENSITIVE_ORDER);       
System.out.println(list);       
System.out.println("-------------------------------");       
sort(source);       
System.out.println(Arrays.toString(source));
52.关于高并发的秒杀问题
Redis 可以应对高并发场景,是因为它的读写请求均是单线程机制,不存在并发问题。而且 Redis 是基于内存的,读写速度也比 MySQL 快得多

53.hashMap的put、get的原理  (数组和链表的结合体,底层是一个数组结构,数组的每一项又是一个链表)
get:
先对key检查是否为null,为null放将到table数组的第一个位置
对key进行hashcode运算计算hash值
indexFor(hash,table.lenth)用来计算Entry对象在table数组中的精确位置,方法参数的hash就是根据key的hashcode方法计算出来的hash
获取table数组的索引,会得迭代链表,通过equals方法检查key是否有相等的

  • HashMap有一个叫做Entry的内部类,它用来存储key-value对。
  • 上面的Entry对象是存储在一个叫做table的Entry数组中。
  • table的索引在逻辑上叫做“桶”(bucket),它存储了链表的第一个元素。
  • key的hashcode()方法用来找到Entry对象所在的桶。
  • 如果两个key有相同的hash值,他们会被放在table数组的同一个桶里面。
  • key的equals()方法用来确保key的唯一性。
  • value对象的equals()和hashcode()方法根本一点用也没有。
54.votile
1.防止重排序
2.实现可见性
可见性问题主要是一个线程修改了共享变量,而另一个线程却看不到。
可见性的问题的主要原因是每个线程都拥有自己的一个高速缓存区-----线程工作内存
votile 修饰i 多线程 每次i++ 100次循环  最后输出一定是小于等于100的
i++ 复合操作 包括三部
①读取i的值
②对i加1
③将i的值写回内存
volatile是无法保证这三个操作是具有原子性的,可以通过Automiclnteger或Synchronized来保证i++的
原子性
55.原子类
1)AutomicBoolean
2)AutomicInteger
3) AutomicLong
原子类自增1
public class Demo{
    private static AtomicInteger count = new AtomicInteger(0);
    public static void increment() {
        count.getAndIncrement();
    }
Synchronized 自增1
public class Demo(){
    private static int i = 0;
    public synchronized static int getInc(){
    i++;    
}
}
56.双亲委托模型
Java中ClassLoader的加载采用了双亲委托机制,采用双亲委托机制加载类的时候采用如下的几个步骤:
1.  当前ClassLoader首先从自己已经加载的类中查询是否此类已经加载,如果已经加载则直接返回原来已经加载的类。
每个类加载器都有自己的加载缓存,当一个类被加载了以后就会放入缓存,等下次加载的时候就可以直接返回了。
2.  当前classLoader的缓存中没有找到被加载的类的时候,委托父类加载器去加载,父类加载器采用同样的策略,首先查看自己的缓存,然后委托父类的父类去加载,一直到bootstrp ClassLoader.
3.  当所有的父类加载器都没有加载的时候,再由当前的类加载器加载,并将其放入它自己的缓存中,以便下次有加载请求的时候直接返回。
57.@Autowired (srping的)与@Resource(j2ee)
都可以用来装配bean. 都可以写在字段上,或写在setter方法上。
@autowired默认按照类型装配的,
默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,如:
@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用,如下:
Java代码
@Autowired()  @Qualifier("dao")
private Dao dao;

猜你喜欢

转载自blog.csdn.net/shy415502155/article/details/80526760