Java面试题个人总结(冲冲冲!!!加油找工作)

 1.面向对象的特性

继承
子类继承父类,子类会继承父类大多数成员(属性,方法)
私有的成员,静态成员,构造方法除外
代码重用和程序的递增式设计
子类可以实现接口,而且可以实现多个接口变相的实现了多继承

封装
private修饰的属性不能随意读写,必须通过set get方法读写
提高代码的规范和安全性
重用的代码封装成方法,工具类以提升开发效率
多态
静态多态 – 重载
动态多态 – 重写

抽象
具有相同特征和行为的对象可抽象为类
特征–>类的属性
行为–>类的方法

2.谈一谈java的访问修饰符
public 共有的,只要不出工程都可以访问
protected 保护类型,本类,同一个包,子类可以访问
默认 本类和同一个包可以访问
private 私有的 只有本类可以访问

  1. & 和 && 的区别?
    条件1 & 条件2
    如果条件1为false,条件2依据要执行

    条件1 && 条件2
    如果条件1为false,条件2就不执行

4.两个对象的值相同 x.equals(y) 返回true,但却有不同的hashCode
这句话对否?
不对
如果两个对象使用equals()方法比较返回true,说明两个对象在逻辑
上是同一个对象.那么他们的hashCode值应该相同,这样才能保证
他们放入hash集合时不会重复添加

5.是否可以继承String
java.lang.String是不能被继承的因为这个类被final修饰

6.java中参数的传递是值专递还是引用传递?
值传递
参数是基本类型(原始类型),传参就是传递参数的值
参数是对象类型(引用类型),传参传递的是引用值(对象在堆区的地址)
这个不是引用传递

7.重载和重写的区别
重载:同一个类中方法名相同,参数列表不同的两个方法称为重载
参数列表不同:
a. 参数的个数不同
b.参数的类型不同
c.参数类型的顺序不同

 重写:前提是有继承关系
             在子类中有一个与父类方法同名的方法
             这两个方法满足以下条件:
                           a.方法名相同  b.参数列表相同 c.返回值类型相同
                           d.子类方法的访问修饰范围>=父类方法
                                                          pubic   protected
           (private ,final,static 修饰的方法不能被重写,不能被继承的东西都不能被重写)

时间少,只答这个
{ 区别: 作用域不同
重载:同一个类中,重写父子类中
重载:参数列表不同,重写:参数列表相同
重载: 对返回值没有要求,重写返回值也必须相同
重载:对访问修饰没有要求,重写子类方法>=父类方法 }

重载的方法能否根据返回值类型进行区别?
不能 只能根据参数列表区别

转发和重定向的区别
转发:浏览器发送一个请求给服务器,服务器的一个web组件处理这个请求,处理完后
将这个请求交给另外一个web组件处理,第二个web组件处理完这个请求后才向
浏览器回传html文本。
转发始终在一个请求之内,浏览器地址栏始终是第一个web组件的url地址

重定向:浏览器发送一个请求给服务器,服务器的一个web组件处理这个请求,处理完后
向浏览器回发一个url地址,浏览接收到这个url后,立刻向这个url指向的web组件发送
请求,第二个web组件处理第二次请求,处理完后向浏览器回传html文本
重定向涉及两次请求,浏览器地址的url会改变,最终显示的是第二个web组件的地址

区别:
转发只有一次请求,重定向涉及两次请求
转发浏览器地址栏不会改变,始终是第一个web组件的地址
重定向浏览器地址栏会改变,最终显示的是第二个web组件的地址

注意:不论是转发,重定向还是简单的向一个jsp页面发送请求,服务器最终是要向浏览器
回传一个html文本

8.为什么方法不能根据返回类型来区分重载?
重载:在同一个类中,方法名相同,参数列表不同的两个方法称为重载
java的编译器是通过方法的参数列表来确认是否是重载的方法,而不是
依据方法的返回值类型来确认

9.char型变量中能不能存储一个中文汉字,为什么?
能,char可以存储所有的unicode字符,汉字在unicode字符之中
所以char能存储汉字

10.抽象类和接口有什么异同
抽象类
有一些类没有必要实例化,或者实例化没有意义,只用来封装通用
属性和方法,供子类继承或重写,这样一些类就将它设计为抽象类
抽象类用abstract修饰

       抽象方法
             只有方法的声明,没有方法的实现称为抽象方法
             抽象方法也是用abstract修饰

       抽象类的特征:
              a.抽象类有构造方法,但是不能实例化
              b.包含抽象方法的类一定是抽象类,但是抽象类可以没有抽象方法
              c.一个类一旦继承了抽象类,就必须实现抽象类中定义的所有抽象方法
                 否则它自己也必须设计为抽象类
              d.抽象类可以作为向上造型中的父类
   接口
        更加纯粹的抽象类,它剥离了抽象类中哪些非抽象的因素,专注于功能的设计
        和扩展

        接口的特征
                a.接口中只有两种成员:
                        public static final 修饰 的常量
                        public abstract 修饰的方法
                b.接口没有构造方法,也不能实例化
                c.一个类可以实现多个接口,变相的实现多继承
                d.接口可以继承接口,而且是多继承
                e.一个类实现了某个接口,就必须实现接口中定义的所有抽象方法
                   否则它自己就必须设计为抽象类
                 f.接口也可以作为向上造型中的父类


   异同:
           a.抽象类和接口都不能实例化,但是抽象类有构造方法
              接口没有构造方法
           b.抽象类中可以包含一般的方法,可以包含一般类中允许的所有成员
              接口中不能包含一般方法,它只能包含两种成员:
                         public static final 修饰 的常量
                         public abstract 修饰的方法
           c.一个类只能继承一个抽象类,但是可以实现多个接口
           d.一个类不论是继承抽类还是实现接口,都必须重写父类中所有的抽象方法
              否则它自己就必须设计为抽象类
           e.抽象类和接口都可以用于向上造型

11.抽象方法(用abstract修饰的)能否同时被static修饰,native修饰,synchronized修饰
都不能
静态方法(static)通过类名调用,必须有方法体.
本地方法(native),这类方法都是用c、c++编写不可是抽象的
同步方法(synchronized)一定是被直接调用的方法(涉及细节的方法)
而抽象不可能被直接调用

请简述jsp的9个隐式对象
输入输出对象
out
服务器端对客户端的输出流对象
request
请求对象
response
响应对象

作用域对象(存放jsp程序运行过程中数据)
pageContext
当前页面,只要页面跳转,绑定数据就销毁
request
一次请求内,请求完毕,绑定数据就销毁
session
一次会话,会话完毕,绑定数据就销毁
application
与tomcat中运行的工程绑定,一旦启动tomcat
在tomcat服务器中每个工程绑定一个application
停止tomcat,application对象就销毁

page对象
当前页面

exception对象
封装jsp页面发生的异常信息

config对象
jsp的本质是一个Servlet,config对象中存放了该Servlet的初始化信息

  1. 静态变量和实例变量的区别?
    静态变量是与类绑定的变量,只有一份属于类
    class Foo{
    static int a = 10; //a就是静态变量
    }
    调用静态变量 Foo.a

    实例变量就是通过构造方法创建的变量
    Foo f = new Foo();
    f就是一个实例变量,实例还有一个名称就是对象
    实例变量可以依据需求创建多个

  2. == 和 equals()的区别
    ==是比较两个变量(或者对象),是否具有相同的物理地址.
    也就是它们是否在物理上是同一个对象

    equals()比较两个变量(或者对象),是否具有相同的内容
    也就是它们是否在逻辑上是同一个对象

14.break 和 continue的区别
break和continue都是在循环中使用
break是终止循环
continue,结束本次循环,进入下一次循环

15.String s = “hello”; s = s + “world!” 这两行代码执行后
原始的String对象中的内容到底变了没有?
没变
因为字符串的不可变性
对象字符串对象的拼接,截取,转换所有这些操作都是产生新的字符串对象
原对象不发生改变

16.java中实现多态的机制
多态: 同名方法,实现不同的功能,展示出多种形态
多态分为两种:
a.静态多态
重载,…(什么是重载)
b.动态多态
重写
向上造型创建的对象,调用子类重写父类的方法
父类 obj = new 子类()
obj.子类重写父类的方法();

Servlet的生命周期(面试题)
a.浏览器向tomcat服务器发送请求
b.tomcat接收到请求后,加载和解析web.xml文件
c.实例化处理浏览器请求的Servlet对象
http://localhost:8080/servlet01/hello3
url-pattern : /hello3
d.Servlet初始化 (调用init()方法)
e.调用service()方法
service方法内部会依据浏览器的请求类型,如果是get请求就调用doGet()方法
如果是post请求,就调用doPost()方法
f. tomcat停止的时候,会销毁Servlet实例(对象)
在销毁实例之前会调用destrory()方法回收资源

17.java中的异常分为哪几类?
java.lang.Throwable
–java.lang.error(错误)
内存堆栈移出,这些不可用程序处理的问题
–java.lang.Exception(异常)
可以用程序处理的
–java.lang.RuntimeException(运行时异常)
可以处理,也可以不处理
空指针 数组下标越界 算术异常…
一般这类异常不可预测

             不是运行时异常,直接或间接继承Exception,这一类
             称为检查异常(CheckException),这一类异常,程序必须
             处理,常见的有SQLException,IOException,....
            一般来说这一类异常可以预测
  1. 调用下面方法,得到的返回值是什么?
    public int getNum(){
    try{
    int a = 1/0;
    return 1;
    }catch(Exception e){
    return 2;
    }finally{
    return 3;
    }
    }

3
取最后返回的值

19.error 和 exception的区别
java.lang.Throwable
–java.lang.error(错误)
内存堆栈移出,这些不可用程序处理的问题
–java.lang.Exception(异常)
可以用程序处理的

20.java异常处理机制
java.lang.Throwable
–java.lang.error(错误)
内存堆栈移出,这些不可用程序处理的问题
–java.lang.Exception(异常)
可以用程序处理的
两种方式来处理:
a.继续往上抛,抛出给调用者处理
b.使用try catch块进行捕获

21.请写出5个RuntimeException
空指针异常 java.lang.NullPointerException
对象.方法();
当这个对象为null时,就会发生空指针异常
数组下标越界 java.lang.IndexOutOfBoundsException
int[] arr = new int[8];
数组的下标:0~7
arr[9];
算术异常 java.lang.ArithmeticException
int a = 10;
a = a/0
非法参数异常
java.lang.IllegalArgumentException
类型转换异常
java.lang.ClassCastException
Person 人
–Student 学生
–Teacher 老师
Student stu = new Student();
Teacher th = (Teacher)stu;//不行,学生不能转型成老师
//就会报这个异常
Person per = (Person)stu;//行,学生转换成人
//不会报异常
数字格式异常
java.lang.NumberFormatException
//将字符串的"123" 解析成整数的123
//不会有异常
int num = Integer.parseInt(“123”);
//“123a” 不是一个合法的数字格式
//解析的时候就会发生异常
int num = Integer.parseInt(“123a”);

  1. throw 和 throws的区别
    a. throw 是在方法中抛出异常,通常是在某种条件下抛出异常
    public void fun(){
    //…
    if(条件){
    throw new RuntimeException(“xxx”);
    }
    }

b. throws 声明某个方法可能会抛出某个指定异常
public void fun() throws SQLException{
//…
}
调用fun()方法的时候,可能会抛出SQLException

c. throw 和 thorws之间的关联
public void fun(){
//…
if(条件){
throw new 异常类()
}

如果throw 抛出的异常类是一个运行时异常
那么不用再方法中声明这个异常的抛出(不需要throws)

如果throw抛出的异常类是一个检查异常
那么一定要在方法的声明中声明这个异常的抛出(需要throws)
public void fun() throws 异常类{
//…
if(条件){
throw new 异常类()
}

简答:
a. throw 是在方法中抛出异常,通常是在某种条件下抛出异常
throw new XXException(“xxx”);

 b. throws 声明某个方法可能会抛出某个指定异常
 public void fun() throws SQLException{
  //...
 }

23.final finally finalize的区别
final java中的修饰符
可以修饰类,方法,变量
final 修饰类,这个类不能被继承
final修饰方法,这个方法不能被重写
final修饰变量,这个变量会转换成常量
final修饰的是一个基本类型,那么这个变量在初始化化以后
它的值不可改变 final int a = 10;//a就永远是10,不能再改
final修饰的是一个对象,对象的引用地址不能改变,对象的内容
还是可以改变的 Student stu = new Student(…);
不能再次new一个对象赋值给stu
stu = new Student(…);//不行
但是stu的属性值可以改变 stu.setName(“李四”);

 finally 它是try catch finally 捕获异常,处理异常结构的一部分
 它表示 不论发生任何情况(有异常,没异常)都必须执行的代码
 通常用这个结构来了释放资源,比如在Dao方法中关闭三个接口

finalize是Object类的方法,所有的类都可以重写这个方法
当JVM回收某个对象时,JVM会让这个对象调用finalize()方法
释放资源

原理:
int a = 1;
Student stu = new Student();
a = a + 10;
stu.xxx();
//变量或对象使用完后不用管
C,和C++要手动释放
stu = null;

java中不用的对象JVM(虚拟机)会自动回收
当这个对象(stu)被JVM自动回收的时候,对象要调用finalize()方法
释放资源


  1. Math.round(11.5) 等于多少? Math.round(-11.5)又等于多少?
    Mtath.round()四舍五入取整
    Math.round(11.5) 12
    Math.round(-11.5) -11
    注意:如果是 Math.round(-11.6) 就是-12

  2. swtich case结构的参数是否可以用byte,是否可以用
    long,是否可以用String
    可以用byte和String
    不能用long

    jdk1.7以后,switch case结构参数支持如下类型:
    byte short int String enum(枚举类型)

  3. 数组有没有length()方法,String有没有length()方法
    数组没有length()方法,只有length属性
    String 有length()方法,可获得字符串的长度

27.String,StringBuilder,StringBuffer的区别?
String 是java中字符串类型,字符串具有不可变性
一旦创建,其内容就不能再修改,所有的拼接,截取,转化
等操作都是返回新的字符串对象,原对象没有任何改变

StringBuffer可变字符串,它具有字符串所 有的功能
但是它优越地方在于,对它所有的拼接,截取,转化
等操作都是对原对象的直接改变,不会产生新的对象
StringBuffer的操作方法(api),大多是线程安全的就是
用synchronized修饰

StringBuilder是单线程版的StringBuffer,它同StringBuffer
功能一致,但是它的方法不用synchronized修饰

简答: String是java中的字符串对象,字符串具有不可变性
StringBuffer称为可变字符串,对它操作不改变原对象
StringBuilder是线程不安全的StringBuffer,它的方法
不用synchronized修饰

28.什么情况下用"+"运算符进行字符串连接比调用StringBuffer/StringBuilder
对象的append方法连接字符串性能更好?
“+” 单独使用的效率要优于 “+” 和 append混合使用

  1. 说出下面程序的输出:
    字符串的常量池机制:
    String s = “hello”;//直接赋值
    直接赋值创建的字符串,它是存放在常量池中的

    String s = new String(“hello”);//构造方法创建
    在常量池中存放一个"hello",然后复制一份存放在堆中
    s引用的是堆中的对象

//拼接创建
如果全是字面量拼接,拼接后的对象存放在常量池中
如果拼接中有引用变量,拼接后的对象存放在堆中

字符串.intern():获得字符串在常量池中的版本
注意字符串对象有可能在常量池中,也有可能在堆中
常量池中有的堆中不一定有,堆中有的常量池中一定有
因为对中的字符串都是从常量池中复制出来的

 main{
   String s1 = "Programming";
   String s2 = new String("Programming");
   String s3 = "Program";
   String s4 = "ming";
   String s5 = "Program" + "ming";
   String s6 = s3 + s4;
   System.out.println(s1==s2);
   /*
       false
       s1 直接赋值 s1是常量池中的对象
       s2 是new 出来的,所以s2在堆中
   */
   System.out.println(s1==s5);
   /*
        true
        s1 存放在常量池中
        s5 是两个字面量拼接,也是存放在常量池中
   */
    System.out.println(s1==s6);
    /*
        false
        s1 存放在常量池中
        s6 是两个引用变量拼接,存放在堆中
    */

     System.out.println(s1==s6.intern());
     /*
       true
        s1 存放在常量池中
        s6.intern() 是取s6在常量池中的版本
      */
    System.out.println(s==s2.intern());
      /*
          false
          s2 是new出来的对象,一定在堆中
          s2.intern() 是取s2在常量池中的版本
     */
  }

30.如何取得年月日,小时分钟,秒
java.util.Calendar 日历类
cal.get(Calendar.YEAR) 年
cal.get(Calendar.MONTH) 0~11 月
cal.get(Calendar.Date) 如
cal.get(Calendar.HOUR_OF_DAY) 时
cal.get(Calendar.MINUTE) 分
cal.get(Calendar.SECOND) 秒

31.从1970年1月1日0时0分0秒到现在经历的毫秒数
System.currentTimeMills();

32.如何获得某月的最后一天
获得日历对象
Calendar类对象 cal
获取这个对象所在月的最大天数
大月最大天数31 小月的最大天数30
2月份是29或28
int max = cal.getActualMaximun();
然后使用set方法进行设置
cal.set(Calendar.DAY_OF_MONTH,max)
那么cal所表示的日期就是指定月的最后一天

  1. 如何格式化日期
    如何将一个Date对象转换为格式化的字符串
    Date dd = new Date();
    SimpleDateFormat sdf = new SimpleDateFormat(“格式定义”);
    String s = sdf.format(dd);
    s就是日期dd按照指定格式转换成的字符串

34.如何打印昨天当前的时刻
将当前时刻倒退一天
//获得当前系统时间
Calendar cal = Calendar.getInstance();
//在当前系统时间的基础上后退一天
cal.add(Calendar.Date,-1);
打印 cal 的年月日 时分秒

  1. java的基本数据类型有哪些,各占及格字节?
    整数4种 字节数
    byte 1
    short 2
    int 4
    long 8

    浮点数2种
    float 4
    double 8
    布尔值
    boolean 1
    字符类型
    char 2

36.String是基本类型?
不是,String是引用类型

  1. short s = 1, s = s +1 正确吗? s += 1正确吗?
    前者不正确,后者正确
    short s =1;
    //整数字面量的默认值是int类型
    //整数字面量默认按32bit存储
    //s = s +1;
    s +=1; //包含隐式的转换
    //等价 s = (short)(s+1)

  2. int 和 Integer有什么区别?
    int 是基本类型
    Integer是int的包装类型
    int 不能接收null值,不能调用方法
    Integer可以接收null,也可以调用方法

  3. 下面Integer类型的数值比较输出的结果为?
    public class Test03{
    public static void main(String[] args){
    Integer f1 = 100,f2=100,f3=150,f4=150
    System.out.println(f1f2);
    System.out.println(f3
    f4);
    }
    }
    输出 true,false
    f1,f2引用是常量池中同一个100,因为100在-127~128这个范围
    f3,f4引用的是堆中两个不同的对象,因为150超出-127~128这个范围

40 String类常用方法
int length() 返回字符串的长度
String trim() 返回去掉前后空格的字符串
String toLowerCase() 返回一个内容与原字符串相同,但是所有字符小写的字符串
String toUpperCase() 返回一个内容与原字符串相同,但是所有字符大写的字符串
char charAt(int index) 截取字符串中参数索引index指定的字符串,参数索引0~字符串的长度-1
int indexOf(String str) 在一个字符串中查询参数子字符串str,如果找到了就返回它首字母的起始
索引,如果没有找到返回-1
String substring(int start,int end) 在一个字符串中截取一个子字符串,从参数start位置开始到
end-1位置结束

41.String,StringBuffer,StringBuilder的区别
String 是java中的字符串类型
String 具有不可变性,对他所有的拼接,截取,转换都是
产生新的字符串对象,原对象不会有改变
StringBuffer,称为可变字符串,它具有String类所有的功能,也可以
转换为String类,但是对他的拼接,截取,转换都不会产生新对象
都是对原对象的改变
StringBuffer是线程安全的,StringBuilder是线程不安的StringBuffer
其余的功能跟StringBuffer一样

  1. java中数据类型是如何进行转换的
    基本类型:
    小类型转换为大类型是自动转换(隐式转换)
    byte a = 10; int b = a;
    大类型转换为小类型是强制转换
    int a = 100; byte b = (byte)a;

引用类型:
子类转换成父类是自动转换的,称为向上转型
Child extends Father
Father obj = new Child();
父类转换成子类是强制转换
Father f = new Father();
Child c = (Child)f;
没有继承关系的对象是不能转换,如果转换
就会抛出造型异常 java.lang.ClassCastException

43.java中有几种类型的流
a.按照流的方向: 输入流 输出流
b.按照流的作用:
字节流 (直接操作文件,一个字节一个字节的传输数据)
FileInputStream 字节输入流
FileOutputStream 字节输出流
字符流 (依赖字节流,一个字符一个字符对的传输数据)
InputStreamReader 字符输入流
OutputStreamWriter 字符输出流
处理流(对字节流字符流功能的加强,如提供缓冲区,行读,行写等)
BufferReader 缓冲输入流
BufferWriter 缓冲输出流
PrintWriter
序列化相关的两个流
ObjectInputStream 对象输入流
ObjectOutputStream 对象输出流

简答:
        a.按照流的方向: 输入流  输出流
        b.按照流的作用: 字节流  字符流    处理流

44.字节流如何转换为字符流
通过依赖构造
new 字符流( 字节流参数)
创建一个字节流,做为字符流构造方法的参数

45.如何将一个java对象序列化到文件里
java对象的类模板必须实现序列化接口 java.io.Serializable
然后使用对象输出流将这个java对象输出的文件中
java.io.ObjectOutputStream – 对象输出流

47.字符流与字节流的区别
字节流是最底层的流是直接操作文件的,传输数据的单位是字节
其他的流要操作文件都必须依赖字节流
字符流是以字符为单位传输数据,可设置字符的编码集,它单独不能
工作,必须依赖字节流

48.什么是java的序列化,如何实现java的序列化?
序列化
就将java对象,包括文件,视频,音频,各种类型的数据转换为01编码
在网络间进行传输
如何实现序列化
java对象的类模板必须实现序列化接口 java.io.Serializable
然后使用对象输出流将这个java对象输出的目标位置

49.已知一个HashMap<Integer,User>, User有两个属性姓名(name,String) ,年龄 (age,int)
编写一个排序方法,使得HashMap中的键值对按照user对象的年龄降序排列
排序好后返回一个有序的HashMap
见Demo5.java

50.请问ArrayList,HashSet,HashMap是线程安全的吗?如果不是那么如何获得线程安全的集合
不是
Vector 是线程安全的ArrayList
HashTable 是线程安全的HashMap
HashSet没有线程安全的版本

还可以通过下列转换方法,将线程不安全的集合转换为线程安全的集合
Set s=Collections.synchronizedSet(new Hashset<…>());
Map m=Collections.synchronizedMap(new HashMap<…>());
List l=Collections.synchronizedList(new ArrayList<…>());

  1. ArrayList内部是如何实现的?
    模仿jdk写一个ArrayList
    接口–ok
    构造方法 – ok
    add() 添加–OK remove() 删除–OK
    clear()清空 get(i) 查询

  2. 并发集合与普通集合的区别
    并发集合:线程安全的集合,操作方法是由synchronized
    这类集合在多线程并发的环境下,不会出现线程冲突的问题
    Vector HashTable ,但是效率较低
    普通集合:不能处理线程安全的问题,操作方法没有synchronized修饰
    这类集合在多线程并发的环境下,会出现线程冲突的问题
    ArrayList LinkedList HaseSet HashMap…
    这类集合效率较高


java中集合的体系
 java.util.Collection(单列数据)
        java.util.List 有序的 
              ArrayList(线性表,底层是数组结构)     LinkedList(链表,底层是结点结构)
              Vector(线程安全的ArrayList)
        java.util.Set 无序的 
              HashSet

 Map(双列数据)      
       HashMap  HashTable(线程安全的HashMap)

  1. List三个子类的特点
    ArrayList 线性表 底层结构是数组 ,所以查询快,增删慢
    数组通过下标访问,查询快
    增删一个元素,这个元素之后的所有元素都要做相应的移动,增删慢

    LinkedList 链表,底层是链表的结点结构 ,所以查询慢,增删快
    Vector 底层是数组 是线程安全的ArrayList,效率较ArrayList低

54.List,set和Map的区别
List,set 存储是单列数据
Map存储是双列数据,也就是键值对

List 是有序事务集合,set是无序的集合
  1. HashMap 与 HashTable有什么区别?
    HashTable是线程安全的HashMap
    HashTable中方法基本与HashMap一致,只是添加了synchorized关键字

56.数组和链表的区别,适用场景,为什么?
什么是变量?
int a = 1;//a是一个变量
内存中存储数据的空间,存储的数据可以覆盖
a = 2;

   什么是数组? (广义,包括线性表 ArrayList)
      内存中连续存储数据的空间

   什么是链表?
        内存中离散存放数据的空间

   数组读取数据(查询)效率就比较高,因为数组是通过下标定位数据
   int[] arr = {....}
   arr中存放实际是数组内容的首地址

   内存空间的利用率比较低,因为内存中连续的空间比较难分配获得
   所以数组用在,数据量不是很大,查询比较多的场景

  链表查询的效率不如数组,但是增删的效率高于数组
  由于链表的存储空间是离散,所以它的存储空间比较容易分配获得
  链表用在长度难以估计,增删比较频繁的场景

57.用面向对象的方法求出数组中重复元素的个数,按照如下格式输出
1 出现:2次
8 出现:4次
6 出现:3次

什么是面向对象编程
对象读写属性
对象调用方法

代码:Demo.java

  1. java中ArrayList和LinkedList的区别?
    ArrayList称为线性表,底层是动态数组,有索引维护,查询效率较高,增删效率较低
    适用于长度相对固定,查询比较多而增删比较少的业务

    LinkedList称为链表,底层是链表的节点结构,查询效率相对较低,而增删的效率较高
    适用于查询较少,而增删比较频繁的业务

59.List list = new ArrayList() 和 ArrayList list = new ArrayList()的区别?
第一种方式:List list = new ArrayList() 是向上造型的创建方法
创建的对象只能调用子类重写父类的方法,如 add() get() remove()…
而不能调用子独有的方法

第二种方式和 ArrayList list = new ArrayList()
创建的对象是纯粹的子类对象,可以调用重写父类的方法以及自己扩展的方法

60.如果业务逻辑是更新操作,那么使用ArrayList和LinkedList那个更加适合
所谓更新操作指的是在集合中添加,删除元素
如果更新是发生在集合的末尾,并且业务中有较多查询,那么就使用ArrayList
如果更新发生在集合的头部或者中间,查询的业务也不是很频繁,那么就使用LinkedList

61.请用两个队列模拟栈结构 (机试题)
队列: 集合,先进先出,后进后出
栈: 集合, 先进后出,后进先出
代码实现:Demo8888.java

  1. Collection 和 Map集合的体系
    集合有两个顶层接口
    Collection 单列数据
    Map 双列数据 键值对

    Collection
    List 有序,可重复
    set 无序,不可重复
    Queue 队列

    Map
    HashMap

63.Map 中的key和value可以为null吗?
HashMap 中的key和value 都可以为null
HashTable中key和value都不能为null

  1. 多线程的创建方式
    简答:
    a.继承Thread类
    b.实现Runnable接口

    a.继承java.leng.Thread类
        public class XXTHread extends Thread{
             //重写run方法
             public void run(){
                  //线程的业务逻辑
             }
        }
      创建线程对象: XXTHread th = new XXTHread();
    

    b.实现java.lang.Ruunable接口
    public XXRunnable implements Runnable{
    //实现run方法
    public void run(){
    //线程的业务逻辑
    }
    }
    创建线程对象: XXRunnable r = new XXRunnable();
    Thread th = new Thread®;

  2. java中wait和sleep方法有哪些不同?
    wait和sleep都是让当前运行的线程进入阻塞状态,也就是交出cpu的控制权
    如果当前线程运行的方法或者代码块是同步的,sleep是不会释放锁的,而wait
    会释放锁

    Thread.sleep(500); 调用sleep方法,线程阻塞500毫秒后,自动进入可运行状态
    重新参与cpu控制权的争夺

    wait()方法一旦调用,线程就一直阻塞,不会自动进入可运行状态,一定要等到其他的
    线程调用 notify() 或者 notifyAll()方法,才能把它唤醒,它重新参与cpu控制权的争夺

    sleep()是Thread类的静态方法,只能这样调用:Thread.sleep(xxx);
    wait()是Object类的方法,所有对象都可以调用wait()方法

    简答:
    a. sleep是Thread类的静态方法,调用 Thread.sleep(xxx);
    wait()是Object类的方法,任意对象都可以调用
    b.sleep()阻塞线程,不会释放同步锁
    wait() 阻塞线程会释放同步锁
    c. sleep()阻塞线程后,经过指定的毫秒数,线程会苏醒,自动进入可运行状态
    wait() 阻塞线程,一定要其他线程调用notify()或者notifyAll()才会苏醒

66.线程和进程的区别?
进程: 操作系统分配资源的基本单位
线程: cpu分配资源的基本单位,进程是由线程组成的

各个进程之间内存空间是相互独立的
同一进程内各个线程之间的内存资源是可以共享的    
  1. 请说出同步线程及线程调度的相关方法?
    同步线程:让两个线程不冲突
    wait(): 让一个线程处于阻塞状态,并且释放同步锁
    sleep():让当前线程进入阻塞状态(睡眠),不会释放同步锁
    notify():唤醒一个被wait()方法阻塞的线程
    notifyAll():唤醒所有被wait()方法阻塞的线程

  2. 启动一个线程是调用run()方法还是start()方法?
    调用start()方法
    run()是线程的业务方法
    调用start()方法启动线程后,线程会自动的调用run()方法

69.静态嵌套类和内部类的不同?
public class Foo{
public static class Goo{}; //Goo 就是静态嵌套类

       public class Moo{};//Moo就是内部类
  }
  //一般类实例化
   Demo  demo = new Demo();
   //静态嵌套类实例化 Foo.Goo类
   Foo.Goo go = new Foo.Goo();
   //内部类实例化 Foo.Moo类
   //首先要创建Foo对象,在此基础上new Moo();
   Foo.Moo mo = new Foo().new Moo(); 

70.java的设计模式有哪些?
java中的设计模式有23种,具体如下:
a.创建型
抽象工厂模式、工厂方法、建造者模式、原型模式、单态模式

b.结构型
      适配器模式、桥接模式、组合模式、外观模式、装饰者模式、享元模式、代理模式、

c.行为型
      责任链模式、命令模式、解释器模式、迭代模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式、访问者模式

常见的有七种,具体如下:单例模式、工厂模式、建造(Builder)模式、观察者模式、适配器(Adapter)模式、代理模式、装饰模式

71.请编写一个单例模式?
什么是单例模式?
Student stu = new Student();
Student stu2 = new Student();

学生类的类模板Student.java 可以创建多个实例
有些类的实例只需要一个就够用了,多了是浪费资源
那么就用一种设计模式来规范它的实例化,让他只能创建一个对象
这种设计模式就是单例模式

   单例模式分为两种: 饱汉模式,饥汉模式
   代码: Foo.java  Goo.java
  1. 请编写一个工厂设计模式
    如何创建对象?
    Student stu = new Student();
    直接通过构造方法创建对象

    工厂是左什么的?生成产品的
    java对象的工厂,自然就是生产java对象
    
    a.工厂方法模式
           见代码demo3
    b.抽象工厂模式  
          使用接口定义抽象工厂,接口中的抽象方法定义工厂要要创建的对象
          然后用具体的工厂实现抽象工厂
          这么做的目的是为了代码的易扩展性,后续添加的功能或者模块不会影响
          已开发的功能和模块
          具体见:demo4文件夹
    
  2. 建造者模式
    将各种产品集中起来管理,用来创建复合对象(比如,工厂对象)
    代码:通过建造者模式,建造工厂对象
    demo4/PersonFactoryBuilder.java

  3. 适配器模式
    接口做什么用的? 定义功能 (设计,规范性)
    interface Ieat{
    void eat();//定义吃的功能
    }
    cook
    eat
    drink

    扩展接口的功能定义满足用户的需求
    父类的引用指向子类的实例
    Father obj = new Child();
    Connection conn = DriverManager.getConnection(…);

    interface Istudy{
    void read();
    void code();
    void review();
    void test();
    }

  4. 装饰模式(Decorator)
    和适配器模式对比
    eat() – 原始功能
    用户需求扩展
    cook()
    eat() – 原始的功能没有改变
    drink()
    sleep()
    通过新增方法来扩展功能

      装饰模式
           eat(){
                print("做饭")
                print("吃饭");
                print("洗碗")
           }
    

    代码见 demo6

  5. 策略模式(strategy)
    demo7

  6. 观察者模式
    观察者
    杂志的读者
    张三 李四 tom marry
    读者收到邮件和链接就可以查阅新的内容
    被观察者
    网络杂志 – 定期更新 --发邮件,链接给每一个订阅的读者

    用接口定义功能
    用抽象类封装通用方法
    再用具体类继承抽象类,实现接口

78.说说原生JDBC操作数据库的流程
a.加载驱动类 Class.forName(驱动字符串)
b.获得连接对象 DriverManager.getConnection(url,user,password);
c.获得预编译命令对象 PreparedStatement
d.如果sql有参数,就设置参数
e.查询执行 executeQuery()方法,增删改就执行executeUpdate()方法
f. 如果是查询,处理结果集 ResultSet
g.关闭资源,后打开的先关闭
顺序是:结果集对象,预编译命令对象,连接对象

79.为什么要使用PreparedStatment对象?
1. PreparedStatement是Statement的子类,所以Statement具有的功能
PreparedStatement全部都继承下来
2. Statement 向数据库发送的是SQL语句,而PreparedStatement向数据库发送的
编译好的SQL语句,所以后者的执行速度高于前者,提高了数据库的性能
3. Statement 没有设置参数的功能,遇到SQL中有参数的情况只能拼接,而PreparedStatement
具有设置参数的功能,可以防止sql拼接过程中由于参数类型变化造成的错误
4. Statement不能防止SQL注入,而PreparedStatement可以,提高了系统的安全性

80.关系数据库中连接池机制是什么?
连接池也是一个java对象
它用于存放和管理从数据库获得的连接
当连接池被创建和初始化的时候,它从数据库中获得一批连接预先存放在连接池中
(initSize:初始化数量)
应用程序要使用的时候,就从连接池中获取连接对象,而不是直接从数据库中获得
使用完毕后,不是将连接关闭,而是将连接对象放回连接池中
一般来说,连接池有一个最大连接数(maxSize),连接池中连接的数量不能超过这个参数
还有一个最小连接数(minSize),连接池中连接的数量不能小于这个参数。还有其他
一系列的参数 最大空闲数,最小空闲数,最大等待时间…这都是依据用户的生产环境
动态设置的

81.http常见的状态码有哪些?
200 请求成功
301 请求的url(地址)已经被服务器永久的移除
302 重定向
400 请求的语法错误,不能被服务器所理解
401 请求未经授权,客户向服务器请求这个资源未被授权
403 服务器拒绝请求,拒绝提供相应的资源和服务
404 按照客户端指定url,服务器找不到指定的资源
500 服务器运行过程中发生错误,不能响应客户端的请求
503 服务器当前不能处理客户端的请求,一段时间后可能恢复正常

82.GET和POST的区别?
GET请求向服务器发送的参数会拼接在URL后面,会出现在浏览器器地址栏
POST请求向服务器发送的参数,会放置在HTTP协议包体中相对安全

GET请求提交的数据最多只能1024个字节
POST请求提交数据理论上没有上限,所以可以传输较大的数据

83.重定向和转发的区别?
重定向:客户端浏览器向服务器发送一个请求,服务器的一个web组件(Servlet jsp Controller…)
来处理这个请求,处理完毕后,向客户端发送一个302状态码和一个url地址
客户端浏览器读到302状态码后,立刻向回传的url指向的web组件发送请求
由于重定向是两次请求,所以地址栏会改变,地址栏中最终是第二个web组件的url

  转发:客户端浏览器向服务器发送一个请求,服务器的一个web组件(Servlet jsp Controller...)
  来处理这个请求,处理完毕后,将这个请求再交给服务器内部另外一个web组件处理
  第二个web组件处理请求,处理完毕后,可以继续转发,也可以回传一个网页文件,等等操作
  转发涉及多个web组件,都在一个请求之内,所以浏览器地址栏始终是第一个web组件的url

  区别: 重定向:两次请求,浏览器地址栏会发生改变
           转发:一次请求,浏览器地址栏不会发生改变

84.Cookie和Session的区别
Cookie是存放在客户端浏览器中用于保存用户信息的一个对象
Cookie在服务器端创建,发回给客户端浏览器,又称为客户端状态跟踪对象

Session指会话,多个请求称为一次会话
Session是服务器端用于保存用户的信息的一个对象,Session的生命周期就是一个
会话(一般指浏览器一开一关之间所有的请求),又称为服务器端状态跟踪对象

区别:(简答)
a.Cookie是保存在客户端浏览器中,Session是保存在服务器端
b.Session可以存放任意类型的java对象,Cookie只能存放String类型

  1. 什么是JSP? 什么是Servlet?JSP和Servlet的区别?
    JSP
    java server page 又称动态网页
    它是运行在java服务器端的web组件,可以依据客户端的不同请求,生成不同
    的页面,依据请求的需要在页面加载不同的信息

Servlet
它是运行在java服务器端的web组件,用于处理客服端的请求,它侧重于逻辑控制
业务运算,一般来说不做数据展示

JSP本质上就是一个Servlet,.jsp文件并不能在java服务器的虚拟机上运行,它要被解析和
编译成一个Servlet才能在服务器上运行
JSP侧重于数据的展示,在mvc中是视图层组件
Servlet侧重于逻辑控制,在mvc中是控制层组件

  1. jsp的隐式对象有哪些?各有什么作用?
    输入输出对象
    out --对客户端浏览器的输出流
    request–请求对象
    response --响应对象

    作用域对象
    pageContext – 绑定当前页面的数据(页面一跳转数据就销毁)
    request–绑定一次请求内的数据(请求结束数据就销毁)
    session --绑定一次会话内的数据
    application --绑定web应用生命周期内的数据(tomcat启动到停止),这个对象被访问该
    web应用的所有用户共享

    其它
    page – 代表JSP页面本身
    exception对象 – 封装了JSP页面抛出的异常信息
    config对象 – 取得服务器的配置信息

87.什么是xml,xml的优点,缺点,xml解析方式又哪几种?分别是什么是
xml extensable markup language 可扩展标记语言
优点:结构清晰,结构与数据分离,易于扩展,可做配置文件
缺点:数据传输效率较低,解析xml需要消耗一定的资源

 xml的解析方式主要有两种
 a.DOM解析
       将整个xml读入内存中作为一颗文档树
       可做读写的操作,不适合数据量比较大xml文件
 b.SAX解析
        基于事件驱动
        只能读,不能修改
        适合文件的数据量比较大,只有读操作的情况

88.谈谈你对ajax的认识
异步发送请求,局部的刷新页面,从而提升用户体验度
减少网络间不必要的数据传输

  1. SQL查询语句完整的执行顺序
    1.from 表 找到表(数据源)
    2.where … 一行一行的过滤数据
    3.group by 组标识(数据按什么分组),给数据分组
    4.having…一组一组的过滤数据
    5.select 选取数据
    6.order by 对选取的数据进行排序

  2. SQL的聚合函数有哪些?各有什么作用?
    count() 计数
    sum() 求和
    max()求最大值
    min() 求最小值
    avg() 求平均值

  3. SQL连接查询中左连接和右连接的区别?
    左连接和右连接同属于外连接
    外连接的特性是驱动表中所有的记录必须要出现在结果集中
    驱动表中不匹配的记录,在匹配表中对应的字段就填充空值
    左连接就是关键字(left join) 左边表做驱动表,右边的表做匹配表
    右连接就是关键字(right join) 右边表做驱动表,左边的表做匹配表

  4. 什么是SQL注入?
    登录
    select * from t_user where user_name=‘admin’ and user_pass=‘123’
    使用SQL注入,不需要知道用户名和密码就能登录
    select * from t_user where user_name=‘xxx’ and user_pass=‘aaa’
    or 1<>2
    获得所有用户的用户名和密码
    如何防止SQL注入,jdbc中的Statement语句对象对于SQL中的参数只能做拼接
    不能防止SQL注入,用PreparedStatement替换它,PreparedStatement可以预编译
    SQL语句防止SQL注入
    select * from t_user where user_name=? and user_pass=?
    ?: ‘xxx’
    ?: ‘aaa’ or 1<>2
    select * from t_user where user_name=‘xxx’ and user_pass=’‘aaa’or 1<>2’

93.MySQL性能的优化?
用户登录 select * from t_user where username=? and password=?
明确的知道这条sql只会返回一条记录
select * from t_user where username=? and password=? limit 1
for(…遍历t_user.){
if(username=xxx && password=xxx){
将记录放入结果集中
break // limit 找到第一条记录就终止查询
}
}

创建表的时候默认选中:InnoDB 

假如只是查询的话,不需要事务处理 可以用MyISAM 
对于处理千万级的数据也是很快的
如果速度不够还可以加为单个字段添加 索引

应用场景:
1).MyISAM管理非事务表。它提供高速存储和检索,以及全文搜索能力。
如果应用中需要执行大量的SELECT查询,那么MyISAM是更好的选择。

              2).InnoDB用于事务处理应用程序,具有众多特性,包括ACID事务支持。
                 如果应用中需要执行大量的INSERT或UPDATE操作,则应该使用InnoDB,
                 这样可以提高多用户并发操作的性能。


简答:
   a.   明确的知道这条sql只会返回一条记录 加limit 1
   b.   正确的选择数据库引擎 MyISAM 和 InnoDB(默认)
            如果业务中没有事务,需要查询海量的数据那么就使用MyISAM
            如果业务中有事务,有大量的增删改操作,那么就使用InnoDB
   c.   not exists 代替 not in  
            not exists 查询的时候可以走索引,提升查询的效率
            not in 不能走索引 而且过滤的时候要和not in(..) 中的值一个一个的比较
            效率较低      
   d. 尽量不采用不利于索引的操作符
          not in  in  is null is not null <>
   e. 某个字段经常用来做查询条件,就给这个字段加索引
        select * from t_emp where ename like '%xxx%'
        alter table t_emp add index(ename)
  1. 事务的四大特征是什么?
    ACID
    A–原子性
    一个事务内,同一组增删改操作,要么同时成功,要么同时失败
    不可分割
    C–一致性
    完整性 + 正确性
    完整性:不违反数据库的约束条件
    正确性:就是保证数据的正确
    I–隔离性
    两个事务,同时执行,并行不悖,串行化(异步)–并行(同步)
    D–持久性:事务对数据库的修改,会持久的保存在数据库中
    修改会更新到硬盘文件中

  2. mysql中事务的四种隔离级别分别是什么?
    脏读:读取未提交的数据
    不可重复读: 在同一个事务中,读取的数据被其他事务修改,所以多次读取的结果不一样
    幻读:一个事务对表中所有的记录做了修改
    同时,另一个事务向表中添加了一条记录
    这时在第一个事务看来还有一条记录没有被修改,像幻觉一样

    隔离级别:
    Read uncommitted(读未提交):一个事务可以读取其他事务没有提交的数据
    这时最低的隔离级别,一般不会设置成这样
    Read commited(读已提交): 一个事务只能读取其他事务已经提交的数据
    大多数数据库都是这种设置
    Repeatable read(可重复读):一个事务,可以读取其他事务已经提交的数据
    但是,每次读到的结果都与第一次读到的相同,mysql就是这种设置
    Serializable(串行读):一个事务读取其他事务操作的数据,不能看到新增加的数据
    这种设置是为了避免幻读

96 mysql如何创建存储过程?
create procedure 过程名(参数)
begin
代码
end;
参数分为两种,输入参数和输出参数

   存储过程的优点:
        代码封装 (可以承担部分后台代码的业务功能)
        提升系统的执行效率
  存储过程的缺点:
        它也是一个数据库对象,创建管理和维护它需要
         消耗数据库服务器的资源
  1. select * from admin left join log
    on admin.admin_id = log.admin_id
    where log.admin_id>10
    如何优化
    不以整个admin表作为驱动表
    而以下面的查询做为驱动表,admin表的部分记录
    (select * from admin where admin_id>10)

    select * from (select * from admin where admin_id>10) tb
    left join log on tb.admin_id = log.admin_id

    驱动表 left join 匹配表
    尽可能让驱动表的记录少于匹配表

    select * FROM XXX where age>? and …
    for(遍历表的记录) {
    if(条件){
    就将记录放入结果集
    }else{
    不放入结果集
    }
    }

for(驱动表){ //外层循环的次数尽可能少,查询效率就高
for(匹配表){
on 连接条件
}
}
—>结果集
for(结果集){
where…
}

  1. select * from admin order by admin_id limit 100000,10
    前提 :admin_id 是个 int 而且是自增长

    sql的执行顺序
    from 表
    where 一行一行过滤
    select 选取结果集
    order by 按照某个条件排序
    limit 按照序号截取

    select * 和 order by都是处理全表的数据
    优化:
    select * from admin where admin_id between 100001 and 100011 order by admin_id
    select * 和 order by 只操作10条记录

  2. 尽量避免在列上做运算,这样会导致索引失效
    select * from t_emp where age>20
    create index xx_age_idx on t_emp(age)
    select * from t_emp where age+10>30 // age + 10 一做运算就不能走索引,效率慢
    select * from admin where yezdmin_time)>2018//一用函数索引就失效
    优化: select * from admin admin_time>‘2018-12-31’

  3. 什么是存储过程,使用存储过程的好处?
    存储过程是一种数据库对象,它封装了一组完成特定功能的SQL语句
    优点: a.一次编译存放在数据库中,后续可以反复调用
    b.减少网络流量,提升数据库服务器的执行效率
    c.安全性较单纯的SQL语句更好

101.Oracle中字符串用什么连接
||
select ‘hello’ || ‘world’ from dual
得到 ‘helloworld’

102.Oracle中如何进行分页查询?
oracle分页有两种方式
a.rownum
要进行分页的查询
select * from t_emp where xx and xx… order by esalary desc
加序号
(select e.,rownum rn from t_emp e where xx and xx… order by esalary desc) tb
tb是一张临时表
再查询临时表,通过rn实现分页
select * from
(select e.
,rownum rn from t_emp e where xx and xx… order by esalary desc) tb
where tb.rn between start and end
起始序号: start = (pageNo-1)PageSize +1
结束序号: end = pageNo
pageSize
b.row_number() over()
select * from
(select e.*,row_number() over(order by esalary desc) rn from t_emp e where xx and xx… ) tb
where tb.rn between start and end

  1. 存储过程和数据库函数的特点与区别?
    过程是用来处理业务功能,分担了一部分后台java程序的任务
    函数经常嵌入在SQL中使用,作用于表中的某些字段,以得到想要的结果
    select concat(ename,‘的薪资是’,esalary) from t_emp
    select * from admin where year(admin_date)>2019
    区别: 过程没有返回值,它通过输出参数或者输入输出参数将运算结果返回给
    调用环境.函数有返回值

  2. 存储过程与SQL相比有哪些优缺点? 什么时候应该使用存储过程?
    什么时候应该使用SQL?
    优点:a.提升数据库服务器的性能
    b.降低网络开销
    c.增强数据库的安全性,防止SQL注入
    d.封装比较复杂业务功能,分担一部分后台java程序的任务
    缺点: a.它也是一个数据库对象,一旦创建需要消耗数据库服务器的资源
    而且需要维护
    b.当业务逻辑变更的时候,修改起来没有SQ灵活
    c.可移植性差
    Oracle的存储过程不能移植到mysql数据库中

    对于效率和规范性要求比较高的业务功能中,建议采用存储过程
    涉及到复杂的算法和业务逻辑的功能,建议采用存储过程
    对于一般业务功能,多采用SQL

  3. 数据库系统性能调优
    1.数据库设计
    a.对查询进行优化,尽量避免全表扫描,在where 以及order by 后的字段上建立索引
    b.在where子句尽量避免null值判断,如select * from t_emp where deptno is null
    因为会禁止查询引擎使用索引,可以在相关字段上设置默认值以替代null值
    如select * from t_emp where deptno=‘xx’
    c.某些字段的值分布的范围比较狭窄
    某些字段只有几个值,比如性别sex,只有‘男’,'女’两个值,那么这样的字段就不适合
    建索引,因为建了索引对查询的效率提升不大
    d.索引不是越多越好,一张表的索引最大不超过6个,对原表的增删改,会引起对索引的增删改,
    和索引顺序的重排,如果这些操作特别的频繁,表中涉及数据量又比较大,那就会极大影响数据库
    的性能
    e.可以使用数值类型的字段(int float double…) 不要使用字符类型(varchar varchar2 char text…)
    因为在做查询和表连接的时候,如果使用的是字符类型,数据库引擎要对其中每个字符逐一比较,而使用
    数值类型的话,只需要比较一次
    ******************************************
    from t_emp e inner join t_dept d
    on e.deptno = d.deptno

     'd001'  'd001'--字符数组
       10 = 20
    ************************************************
    f. 能够使用varchar/nvarchar的地方,不要使用char/nchar
      ************************************* 
      varchar(100) 100个字节 UTF-编码  英文数字符号($%#@..)一个字节,中文('好','你')3个字节
      nvarchar(100) 100个字符,不管什么编码,也不管是中文还是英文数字,符号
     ******************************************
       
    g.尽可能少用临时表,以减少系统资源的销毁,当必须要使用的时候,使用完后,一定要显示删除
       首先truncate table,然后在drop table(临时表)     
    

    2.SQL语句
    a. 在where子句尽可能避免使用 != <> or in not in,因为这样会导致数据库引擎放弃使用索引,而进行全表扫描
    b . 当查询中有参数的时候,数据库引擎会放弃使用索引,进行全表扫描
    select * from t_emp where deptno=@dno
    如果依据程序员的经验明确判断使用索引比较快,就可以强制使用索引
    select * from t_emp with(索引名) where deptno = @dno --索引是建立在deptno字段上
    c. 在where子句中避免使用表达式,这会导致数据库引擎放弃使用索引,走全表扫描
    select * from t_emp where esalary * 1.1>10000 --esalary上建了索引
    修改为
    select * from t_emp where esalary >10000/1.1 --这样才会走索引
    d. 在where子句中避免进行函数操作
    t_emp有ename字段,在这个字段上建立索引
    select * from t_emp ename=‘zs’ -->没有函数会走索引
    select * from t_emp substring(ename,0,1) =‘z’ -->使用了函数不会走索引
    e.用exixs代替in,用not exists代替 not in
    f. select * from t_emp * 会逐个的检查所有字段
    不要使用* 而要使用具体的字段,不需要字段不要加
    select ename,esex from t_emp
    g.避免使用游标,因为游标的效率比较低
    h.尽量避免向客户端返回大量的数据(使用分页)
    i.尽量避免大事物的操作,提高系统并发能力


          尽可能在where子句中不使用!=或者<>,因为这会使数据库引擎放弃使用索引,进行全表扫描
          尽可可能避免在where子句中使用or,如select * from t_emp where deptno='d001' or deptno='d002'
           优化成:
                  select * from t_emp where deptno='d001'
                  union all
                  select * from t_emp where deptno='d002'
         如果在deptno上建个索引

#a就会放弃使用索引,进行全表扫描
#b自动走索引,走索引可定快

select * from t_emp where deptno=‘d001’ or deptno=‘d002’ #a

select * from t_emp where deptno=‘d001’ #b
union ALL
select * from t_emp where deptno=‘d002’

在ename上建个索引
#a不会走索引,会全表扫描
select * from t_emp where ename like ‘%abc%’ #a
#b走索引
select * from t_emp where ename like ‘abc%’ #b


   3.JDBC       
         a. 大量数据和少量数据的操作要分开,少量数据(相对),对于大量数据的操作
             不是ORM框架(关系数据库)能搞定,要使用大数据框架(hadoop)
         b.控制好内存,灵活处理数据,不是一次性将数据读取到内存中,而是边读边处理
            比如,分页操作,mybatis懒加载操作
         c.合理利用内存,有的数据要缓存,不必每次都查询数据库
            要缓存的数据时哪些? 用户经常使用的数据
  1. SpringMVC的工作原理(重点记忆)
    浏览器请求—>tomcat—>解析web.xml(配置了前端控制器)–>前端控制器找HandlerMapping
    HandlerMapping(其中是一个个键值对)
    一个键值对就是一个HandlerAdapter -->结构: key(请求路径):/demo/hello value(控制器): HelloController
    HandlerAdapter通过Handler对象去调用控制器
    控制器是如何运作的?最经典的过程
    a.到数据库查数据 b.将查询出的数据放到作用域中 c.转发到一个视图(jsp)
    员工列表:查询出所有员工的信息,将员工信息放入到model(request作用域)中, return “ListEmp”(目的是要转发到ListEmp.jsp)
    这个过程最终会有一个结果,返回给HandlerAdapter,这个结果就是ModelAndView对象
    Mode(作用域) and View(视图)
    ModelAndView 对象被HandlerAdapter 返回给前端控制器(DispatcherServlet)
    前端控制做两个事情:a.调用视图解析器ViewResolver,找到要转发的视图(jsp)的位置
    如何找? prefix="/WEB-INF/jsp/" suffix=".jsp" view中包含的信息(“ListEmp”)
    找到了: /WEB-INF/jsp/ListEmp.jsp
    b. 再将Model对象中数据渲染到视图中生成真正的视图(html)
    最后前端控制器将真正的视图(html)返回给客户端浏览器,完成响应过程

107.SpringMVC常用的注解
@RequestMapping
@ResponseBody
@Controller
@Service
@Repository

  1. 如何开启注解驱动
    在Spring的主配置文件中添加:
    mvc:annotation-driven/

  2. 如何解决请求参数的中文乱码问题
    如果是POST的请求,那么在web.xml中配置一个CharacterEncodingFilter过滤器,设置为UTF-8
    对于GET有两种方式:
    a.修改tomcat的配置文件server.xml
    在标记中添加编码UTF-8编码设置
    <Connector port=“8080” protocol=“HTTP/1.1” connectionTimeout=“20000"redirectPort=“8443”
    URIEncoding=“UTF-8” />
    b. 对参数进行重新编码
    String username = request.getParameter(“username”);
    username = new String(username.getBytesv-1”),“UTF-8”);

  3. 谈谈你对Spring的理解(重点)
    Spring是一个对象工厂,传统的java企业级开发中需要通过new 或者 getInstance方法获得对象
    使用Spring,Spring容器能够提供我们需要的对象。Spring容器可以创建对象以及管理对象与对象
    之间的关系

    同时Spring也是一个框架粘合剂,它可以整合其他的框架或者第三方插件,让它们协调工作
    其他框架或者第三方插件的api通过spring的api进行调用

    Spring容器的核心是IOC和AOP
    IOC:反转控制,不是通过new创建对象,而是在配置文件设定对象的包名.类名,容器读取包名.类名
    通过反射创建对象.对象属性的赋值,也是通过反射实现的(配置)
    称为依赖注入(DI)

    AOP:面向切面编程,抽取出各个功能模块中通用的业务,抽象成切面对象(Aspect),再将这个切面对象通过特定方式
    (前置,后置,环绕,异常,最终) 织入具体的功能模块中,具体的功能模块执行的时候,切面对象提供的方法也自动
    执行。

  4. Spring中的设计模式有哪些?
    a.单例模式
    不论是xml配置文件中定义的bean还是注解创建的对象放入Spring容器中都是单例
    除非手动修改scope属性为prototype
    b.模板模式
    Spring将一些通用业务封装成模板,比如jdbcTemplete封装了JDBC的操作
    c. 动态代理模式
    Service对象,Dao对象都是接口声明,而Spring容器会返回一个实现类对象,那么这个
    对象其实不是我们自己定义的子类,而是Spring创建的代理对象,它增强了原对象的功能
    所以原对象才可以加事务,加AOP切面,设置懒加载…
    d.工厂模式
    Spring是一个对象工厂,这个工厂可以创建对象(通过反射的方式),它同时会管理对象与对象之间的
    关系

  5. Spring能帮我们做什么?
    a.使用配置文件通过反射创建对象,同时维护对象与对象之间的依赖关系
    b.Spring aop能够无耦合的实现日志记录,性能统计,安全控制
    c.能够以简单的方式管理数据库事务
    d.Spring能与第三方框或者插件架无缝集成,比如struts2,hibernate,mybatis,Shiro,Log4j,…
    从而提供完整的j2ee解决方案

113.请描述一下Spring的事务
Spring采用声明式事务管理,分为两种方式a.配置文件 b.注解
声明式事务代替原有编程式事务(通过代码实现),使得事务管理和业务逻辑解耦
实现需要在Spring容器中配置一个事务管理器transactionManager
然后通过aop的方式织入当具体的业务功能中

114.编程式事务和声明式事务的区别?
编程式事务:自己写事务处理类,然后调用
声明式事务:在配置文件中定义事务,或者通过注解定义事务(推荐使用)

  1. BeanFactory常用放入实现类有哪些?
    通过代码手动创建Spring容器:
    ApplicationContext ac = new ClassPathXmlApplicatinContext(“applicationContext.xml”);
    子接口:
    ApplicationContext,
    AutowireCapableBeanFactory,
    ConfigurableApplicationContext,

     子类:
          ClassPathXmlApplicatinContext 
          FileSystemXmlApplicationContext, 
          XmlBeanFactory
    
  2. 解释Spring JDBC,Spring DAO ,Spring ORM
    【Spring DAO】 就是使用Spring框架编写DAO的规范,比如在Dao类上要加注解@Repository

    【Spring JDBC】 spring封装的数据访问层组件,提供一个jdbc开发的模板,jdbcTemplate,
    还提供了一个JdbcDaoSupport抽象类,封装了基本的连接数据库,增删改查的功能。同时
    还提供了一个异常转换器将所有在Dao中抛出的异常转换为 DataAccessException

    【Spring ORM】 Spring 调用和管控 数据库访问层框架的模块,这些数据库访问层框架包括
    mybatis,hibernate,…它集成对数据源和事务的管理

117.简单介绍一下Spring web模块
它提供一个应用程序上下文,可以整合struts这一类的控制层框架,同时可以处理上传文件,页面传参,
将页面参数自动封装成控制器方法参数对象

  1. Spring配置文件有什么作用
    a.
    Spring的配置文件是用于指导Spring工厂进行Bean的生产、依赖关系注入及Bean实例分发的“图纸”,
    它是一个或多个标准的XML文档,J2EE程序员必须学会并灵活应用这份“图纸”,准确的表达自己的“生产意图”。
    b.
    Spring配置文件用于指导Spring容器创建对象,管理对象以及维护对象与对象之间的依赖关系.它由一个或者
    多个标准的xml文件组成,是整个软件系统设计的重要组成部门

  2. 什么是Spring IOC,IOC有哪些优点
    Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,
    Ioc意味着将你设计好的对象交给Spring容器控制,而不是传统的在你的对象内部直接控制。

    优点:
    使得对象与对象之间是松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。

  3. ApplicationContext的实现类有哪些
    //创建Spring容器
    ApplicationContext ac = new ClassPathXmlApplicationContext(“applicationContext.xml”);
    ClassPathXmlApplicationContext:类路径加载
    FileSystemXmlApplicationContext:文件系统路径加载
    AnnotationConfigApplicationContext:用于基于注解的配置
    WebApplicationContext:专门为web应用准备的,从相对于Web根目录的路径中装载配置文件完成初始化

  4. BeanFactory与ApplicationContext有什么区别?
    BeanFactory是Spring容器的顶层接口
    ApplicationContext是BeanFactory的子接口
    BeanFactory提供IOC容器的基本功能,采用的延迟初始化的策略,也就是创建容器的时候不实例化bean
    而在应用程序获取bean的时候才实例化bean
    ApplicationContext是在BeanFactory的基础上建立的,除了提供IOC容器的基本功能外,它还提供了
    事件发布,国际化等功能.ApplicationContext中的bean在容器启动后,全部初始化完成。

122.什么是依赖注入(DI)
依赖注入(Dependency Injection)
传统开发中对象是由程序员通过构造方法 new创建的,这样创建的对象不方便管理,代码耦合度很高
Spring框架采用依赖注入的方式实现控制反转,对象的创建交给Spring容器,Spring容器通过反射创建
对象,并且有Spring容器统一管理对象与对象之间的依赖关系.这样做降低代码的耦合度。

123.有哪些类型的IOC(依赖注入)方式?
a. set 注入

// setAge
// ref 指向的dog是容器中另外一个bean,它id为dog

b. 构造器注入 //必须定义bean的对象要有对应的构造器



   c. 静态工厂方法注入
   d.实例工厂方法注入
  https://550516671-qq-com.iteye.com/blog/803999
  1. 什么是Spring beans?它的定义需要包含什么?
    就是组成Spring应用的java对象(Spring容器中的那些java对象)
    Dao对象 Service对象 Controller对象 MyBatis的SessionFactory
    DataSource(数据源对象) CacheManager(缓存管理器) Cache(缓存对象) …
    那些通过 定义或者,注解扫描创建的对象

    它要包含容器必须知道的元数据(描述数据的数据)
    比如 class,实体类的包名.类名
    id|name ,bean的唯一标识
    scope, 定义是单例还是多例

  2. 在Spring中如何定义Bean的作用域?Bean的作用域有几种?
    通过scope属性定义bean的作用域

    Bean作用域的种类:
    a. singleton 默认值 单例
    b. prototype(原型) 多例
    c. request 每次http请求都会创建一个bean
    d.session 在一个 Http session中,创建一个bean
    f.global-session:在一个全局的Http Session中(类似Servlet的application,为所有用户共享的)
    创建一个bean

  3. Spring框架中单例的bean是线程安全的吗?
    不是

127.什么是Spring内部的bean






  定义一个汽车类的bean
          <bean class="com.itdjx.spring.dependency.injection.Car" id="xx" name="xx">
            <constructor-arg value="Ferrari" index="0"/>
            <constructor-arg value="Italy" index="1"/>
            <constructor-arg value="22500000" type="double"/>
        </bean>

使用内部bean

128.在Spring中如何注入一个java集合
a. List


tom //集合中是字符串或者整数
// 集合中是对象


b. Set


tom //集合中是字符串或者整数
// 集合中是对象

c. Map


// value是整数或者字符串
//value 是对象,这个对象必须存在于容器中

d. Properties


123 //value是整数或者字符串

//value 是对象,这个对象必须存在于容器中


  1. 什么是Bean的自动装配,解释不同方式的自动装配
    无需手动设置bean 的 property 属性的值或者引用spring容器会自动依赖
    a. xml配置文件
    在bean标签中添加autowire属性
    autowire=“byName” ,按照属性名自动装配
    autowire=“byType”,按照对象的类型自动装配
    b.注解
    @Resouce
    先按照指定的name装配,如果没有指定,就按照属性名装配
    ,最后按照类型(type)装配
    @Autowired
    默认就按照类型(type),如果要按照name(属性名称)装配,需要添加
    @Qualifer属性指定对应的属性名称

  2. 什么是基于java的Spring注解配置,给一些注解的例子
    在java类上,属性上,方法上加上注解,注解一般是@xxx的形式,以替换原来
    xml的配置。它使得开发更加的方便,高效
    比如,@component 这个注解加载类上,就会通过反射创建这个的类的对象,放入Spring容器中
    替换了原来的配置
    @Resource 这个注解加载属性上或者set方法上,Spring会自动在容器中搜索对应类型的对象
    然后注入给加注解的属性,替换了原来 配置

  3. 怎样开启注解?
    // 开启注解扫描,base-package属性定义的包下所有的类
    // 只要加了注解就生效,放入spring容器
    <context:component-san base-package=“com.emp”>
    //开启springmvc注解
    mvc:annotation-driven

132.在Spring框架如何更加有效的使用JDBC?
Spring提供了一个模板JdbcTemplate,和一个抽象类JdbcDaoSupport
Spring框架在这个模板和抽象类中封装了大量的操作jdbc的方法(增删改查),
调用的时候只要编写sql和传入参数即可,对于返回值要封装成对象的业务,提供
了一个RowMapper接口可以自动完成封装。
JdbcTemplate是自动注入数据源
JdbcDaoSupport需要通过set方法手动注入数据源

  1. Spring 支持的ORM框架有哪些?
    Mybatis(iBatis) Hibernate JPA
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值