面试小记---java基础知识
**static 和 final 的理解**
static:是静态变量修饰符,修饰的是全局变量,所以对象是共享的,在开始类设计的初期就分配空间。
final:声明式属性,方法,类。分别表示属性不可变,方法不可覆盖,类不可继承,内部访问的是局部变量,局部变量必须定义成final类型的
**SpringMVC的理解**
SpringMVC是基于过滤器对Servlet进行封装的一个框架,在web.xml配置DispatcherServlet类,每次通过此类来管理收到的请求并进行处理。
**get 和 post 的区别**
1.get是通过URL提交数据,数据在URL上可以看到,post方式数据放在html header内提交,我发在地址栏看到
2.get提交方式最多只能提交1024字节,而post则没有此限制
3.get一班用作小数据提交,post用作大数据的情况下
**怎么优化sql语句**
1. select语句中不使用‘*’来查询全部
2. 减少访问数据库的次数
3. 整合简单,减少无关联数据库的访问
4. 删除重复记录
5. 使用TRUNCATE 代替 DELETE
6. 尽量多使用commit
**硬件之间的网络传输协议**
- 物理层
- 数据链路层
- 网络层
- 传输层
- 会话层
- 表示层
- 应用层
**Mybatis 怎么实现数据的持久化**
### 加载配置并初始化
触发条件:加载配置文件(一个个配置文件,一个是java代码注解)
将sql的配置信息加载成为一个个MappedStatement对象,其中包括传入参数映射配置 ,执行sql语句,结果映射配置,存储在内存中。
### 接受调用请求
触发条件:调用Mybatis提供的API
传入参数:为SQL的ID 传入的参数
处理过程:将请求传递给下层的请求处理层进行处理
### 处理操作请求
触发条件:API接口层传力请求过来
传入参数:为SQL的ID的传入的参数
处理过程:
1. 根据sql的ID查找对此那个的MappedStatement对象
2. 根据传入参数对象解析MappedStatement对象,得到最终的要执行的sql执行参数
3. 获取数据库连接,根据得到的最终sql语句和执行传入的参数到数据库执行,获取到执行结果
4. 更具MappedStatement对象的结果映射配置得到执行结果进行转换处理,并最终得到处理结果
5. 释放连接资源
**前端和后端是如何进行交互 交互过程**
通过链接或者表单提交,使用ajax异步交互,则是对数据库进行交互管理
1:前台一般对数据库内容按照页面代码控制进行检索并展示出来形成页面
2:后台则是对数据库进行增删改查
**json数据传送到后台**
前端使用JSON.Stringify();转化成字符串 后台主要是是利用json的相关jar接受,
我使用SpringMVC 的@RequestBody 绑定一个对应的实体类,其转化为对应的json数据对应其各个字段,从而接受到前端标端传入的各个数据。
**数据库中的存储过程,触发器,视图,索引**
存储过程:是一系列预先编译好的,能实现特定数据操作功能的的sql代码集,存储在sql server服务器上
触发器:特殊的存储过程,存储过程是是手动调用的,触发器是由事件自动调用的
视图:不占物理存储空间,只是一种逻辑对象,可将看成一个虚表,有一个select语句指定,用于检索数据库表中某些行或列数据的语句存储定义
索引:是数据库中的对象之一,是为了加速对表中数据行的检索而床创建的一种分散的一种存储结构。
**adstract 和 interface 的区别**
abstract不能创建实例对象
interface中的方法默认是public abstract类型,成员变量默认是public static final 类型
抽象类可以有构造方法,接口中不能有构造方法
抽象类中可以有普通成员变量,接口中没有普通成员变量
抽象类中可以包含静态方法,接口不能有静态方法
一个类可以实现多个接口,但只能继承一个抽象类
接口中的抽象方法默认是public static 类型,抽象类中的方法可以是public protected 和默认类型
抽象类中的成员变量可以任意指定,而接口中的成员变量只能是pubic static final类型
**基本排序**
数据
int[] a = {2,4,6,7,123,54,78,2,6};
快速排序
public static void quickSort(int[] arr, int start,int end){ if(start > end){ System.out.println("起始位置选择错误"); return; } // 设定基准,分开数据 int base = arr[start]; int i = start; int j = end; // 开始一趟排序将数据分成两个部分,一部分比基准小,一部分比基准大 do{ while (arr[i] < base && i < end) i++; while (arr[j] > base && j > start) j--; if(i<=j){ int t = arr[i]; arr[i] = arr[j]; arr[j] = t; i++; j--; } // 开始确定其比基准数比较的次数 for(int x = 0; x < arr.length;x++){ System.out.print(arr[x]+" "); } System.out.println(""); }while(i <= j); if(j > start) quickSort(arr,start,j); if(i < end) quickSort(arr, i, end); } }
简单排序
for(int i = 0; i < a.length-1;i++) for(int j =i+1; j < a.length;j++) { if (a[i] > a[j]) { temp = a[i]; a[i] = a[j]; a[j] = temp; } }
冒泡排序
for(int i = 0; i < a.length-1;i++) for(int j = 0; j <a.length-1-i;j++){ if(a[j] > a[j+1]){ int t = a[j+1]; a[j+1] = a[j]; a[j] = t; } }
选择排序
public static void selectSort(int[] arr){ for(int i = 0; i < arr.length;i++){ int k = i; for(int j = i; j < arr.length;j++){ if(arr[k] < arr[j]){ k = j; } } int temp = arr[k]; arr[k] = arr[i]; arr[i] = temp; } }
插入排序
public static void insertSort(int[] arr){ System.out.println("--------------------"); int j , temp; for(int i = 0; i < arr.length;i++){ temp = arr[i]; for(j = i;j > 0 && temp < arr[j-1];j--){ arr[j] = arr[j-1]; } System.out.println("j = "+j+"i = "+i); // 将插入的元素不小于此原有数组中的元素时候,将数据插入到后面 arr[j] = temp; for(int ii = 0 ; ii < arr.length; ii++){ System.out.print(arr[ii]+" "); } System.out.println(""); } System.out.println("--------------------"); }
**单例模式**
线程安全懒汉写法
class Single{
private static Single s;
private Single(){}
public static Single getInstance(){
System.out.println("s = "+s);
if(s == null) {
s = new Single();
return s;
}
else
return s;
}
}
# native
-------
java 可以和c或者其他语言联合编程
通过javah 编译java文件,使其生成.h 文件将其头信息复制到c语言文件中,在通过gcc生成动态链接库,然后使用java命令编译,运行
面试题
**SpringMVC工作原理**
首先用户请求DispatcherServlet
然后DispatcherServlet查询一个多个HandlerMapping,
HandleMapping提交到Controller,返回ModelAndView,
DispatcherServlet根据ModelAndView查询其对应的ViewResoler视图解析器找到指定的视图
将结果显示到页面上。
**文件的输入输出流,字节流,字符流**
字节输入流:InputStream
字节输出流: OutputSream
字符输入流:Writer
字符输出流:Reader
字节输出(输入)流是已byte为单位:图片,视频,压缩包,音频,安装包
字符输出(输入)流是已char为单位:txt,json,xml,html,css,javascript
**手动写jdbc原生程序**
1. 注册驱动 Class.forName("驱动包权限类名");
2. 获取数据库的链接,DriverManager.getConnection(url,root,password);
3. 创建数据库语句,用于执行,(Connection).createStatement();
4. 将结果集存在resultSet里面,其中使用其next()方法可以跳转到下一个结果上,通过getObject(**String()**)通过其数据库对应的字段名,来获取结果
5. 释放开启的资源
**sql语句注入问题解决**
使用期预处理对象PreparedStatement来处理sql语句,将其中的需要对应的参数替换掉
- 前面同样的注册,获取数据库连接
- 在通过连接获取其预处理语句执行
- 编写数据库的语句,需要参数的则是使用?代替
- 在预处理语句中设置其各个参数
- 执行,将结果放入ResultSet中
String sqlP = "select * from employee where id = ? or id = ?"; PreparedStatement ps = con.prepareStatement(sqlP); ps.setString(1,"11"); ps.setString(2,"18"); boolean execute1 = ps.execute(); System.out.println("预处理:"+execute); ResultSet resultSet1 = ps.executeQuery(); while (resultSet1.next()) System.out.println(resultSet1.getObject("address"));
字符串反转:StringBuilder中有一个方法可以直接反转
reverse().toString()
String str = "abcdef";
char[] chars = str.toCharArray();
for(int i = 0; i < chars.length/2;i++){
char temp = chars[i];
chars[i] = chars[chars.length-i-1];
chars[chars.length-i-1] = temp;
}
**切割字符串**
1. spilt 效率低,简单
2. StringTokenizer专门的切分字符串类
3. 使用String的subString(,)查分字符,处理好其字符串的溢出问题
**对jvm的工作原理的简单理解**
jvm的字符码的工作是由字符解释器来解释的
1. 代码装入
2. 代码校验
3. 代码进行
**将一个小数四舍五入 保留两位有效数字**
设置其中需要保留的小数
BigDecimal 中有个方法,setScale(保留位数,BidDecimal.ROUND_HELF_DOWN)
**instanceof**
result = Object instanceof class
result : Boolean
Object : 继承类或者是实现类
class: 继承那个类的class
**最常见的runtime exception**
ArithmeticException ArrayStoreException BufferOverflowException BufferUnderflowException CannotRedoException CannotUndoException ClassCastException CMMException ConcurrentModificationException DOMException EmptyStackException IllegalArgumentException IllegalMonitorStateException IllegalPathStateException, IllegalStateException ImagingOpException IndexOutOfBoundsException, MissingResourceException NegativeArraySizeException NoSuchElementException NullPointerException ProfileDataException ProviderException RasterFormatException, SecurityException SystemException UndeclaredThrowableException UnmodifiableSetException UnsupportedOperationException
**局部变量前面不能放置任何访问修饰符**
**字符串容器的选择是**
选择StringBuffer 或者StringBuilder 可改变字符串,比String速度快
**当复制大量数据时,使用System.arraycopy()命令。**
**IO流复习**
转换流
inputSteamReader
outputStreamWriter
将字节流转换成字符流
对象流
ObjectOutputStream
ObjectInputStream
将对象序列化到文件中,需要读出来的时候,在反序列化,其中对象需要实现Serializable
缓冲流
BufferedReader
BufferedWrite
字符流
FileReader
FileWriter
字节流
FileInputStream
FileOutputStream
(转换流(缓冲流(字符、字节流、文件输入/输出、键盘读写)))
打印流
PrintWrite
PrintStream
**反射**
1. 获取class文件: 1. new 对象 , 在使用其getClass()方法 2. 每个对象都有个class静态字段,获取后再使用期getClassLoader() 3. 通过forName(需要反射类的权限类名) 2. 获取其反射类的构造方法用来创建其对象实例 其中构造方法有私有的,共有的 getConstructors() 获取所有共有的构造方法 getDeclaredConstructors() 获取私有的,受保护的,默认的构造方法 获取单个构造方法 getConstructor(class...parameterTypes)传入其对应参数的.class属性 3. newInstance()获取其无参构造方法 newInstance(...)获取其指定参数的构造方法 4. 获取其方法、属性、执行等等 5. 取消java类型检查机制 其构造方法后有setAccesible(true)
优点: 降低类之间的耦合性,在类运行时加载器类,可以实现动态创建对象和编译,灵活性提高。
缺点:速度降低,反射是一种解释性的操作,总是慢于直接执行的java代码
**多线程**
创建线程的方式:
1. 继承Thread类
2. 试下Runnable接口
wait()和sleep()的异同
反对使用stop(),是因为它不安全。它会解除由线程获取的所有锁定,而且如果对象处于一种不连贯状态, 那么其他线程能在那种状态下检查和修改它们。结果很难检查出真正的问题所在。suspend()方法容易发生死锁。 调用suspend()的时候,目标线程会停下来,但却仍然持有在这之前获得的锁定。此时,其他任何线程都不能访问锁定的资源, 除非被"挂起"的线程恢复运行。对任何线程来说,如果它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就会造成死锁。 所以不应该使用suspend(),而应在自己的Thread类中置入一个标志,指出线程应该活动还是挂起。若标志指出线程应该挂起,便 用wait()命其进入等待状态。若标志指出线程应当恢复,则用一个notify()重新启动线程。
请说出你所知道的线程同步的方法。
wait():使一个线程处于等待状态,并且释放所持有的对象的lock。 sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常。 notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。 Allnotity():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。
Java中的线程有四种状态分别是:运行、就绪、挂起、结束
轻量级数据安全机制
volatile,不将数据缓存到cpu中,每次直接从cpu中读取新的数据,每次刷新数据时候,数据都是最新的。
**jsp**
实现servlet的单线程模式
<%@page isThreadsafe="false"%>
页面间的对象传递方式
request session application cookie
**XML解析技术**
DOM、SAX、STAX
**多态**
public class A { public String show(D obj) { return ("A and D"); } public String show(A obj) { return ("A and A"); } } public class B extends A{ public String show(B obj){ return ("B and B"); } public String show(A obj){ return ("B and A"); } } public class C extends B{ } public class D extends B{ } public class TestP { public static void main(String[] args) { A a1 = new A(); A a2 = new B(); B b = new B(); C c = new C(); D d = new D(); System.out.println("1--" + a1.show(b)); System.out.println("2--" + a1.show(c)); System.out.println("3--" + a1.show(d)); System.out.println("4--" + a2.show(b)); System.out.println("5--" + a2.show(c)); System.out.println("6--" + a2.show(d)); System.out.println("7--" + b.show(b)); System.out.println("8--" + b.show(c)); System.out.println("9--" + b.show(d)); } } result: 1--A and A 2--A and A 3--A and D 4--B and A 5--B and A 6--A and D 7--B and B 8--B and B 9--A and D
-------------------------
-------------------------
# sql语句相关(mysql)
...未完待续