问:TCP/IP有几次握手?
答:三次握手。
第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
问:网络七层协议有哪几层?
答:有上到下分别是:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层
问:HTML和JSP有什么区别?
答:HTML是静态页面,JSP是动态页面运行时需要转换成servlet;
HTML可以直接打开,JSP要通过中间服务器比如Tomcat才能打开;
JSP有<%%>可以在里面写代码,而HTML没有<%%>;
扩展:执行过程:JSP先翻译,翻译成Servlet执行
如: test.jsp 要变成 test_jsp.java 然后编译成 test_jsp.class
而 test_jsp.java 本身就是一个servlet.
所以 jsp只是servlet的一个变种,方便书写html内容才出现的。
servlet是根本,所有jsp能做的,servlet全能做。
问:JSP和Servlet有什么区别?
答:1、JSP经编译后就变成了Servlet(JSP的本质就是Servlet);
2、JSP更擅长表现于页面显示,Servlet更擅长于逻辑控制( JSP侧重于视图,Servlet主要用于控制逻辑);
3、JSP中的内置对象都是必须通过HttpServletRequest对象,HttpServletResponse对象以及HttpServlet对象得
到,Servlet中没有内置对象,
4、在Struts框架中,JSP位于MVC设计模式的视图层,而Servlet位于控制层;
问:有用过Linux、SVN、maven吗?说几个maven命令。
SVN
问:Servlet和SpringMVC有什么区别?
答:基本的J2EE开发模式JSP+Servlet+JDBC
Servlet是SpringMVC的核心
问:你了解过http协议吗?
答:HTTP协议是用于从万维网服务器传输超文本到本地浏览器的传送协议。
HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。
问:post和get的区别
答:get 是从服务器上获取数据,post 是向服务器传送数据;
get 安全性非常低,post 安全性相对较高(比如一个登陆页面,通过 Get 方式提交数据时,用户名和密码将出现
在 URL 上,如果页面可以被缓存或者其他人可以访问客户这台机器,就可以从历史记录获得该用户的帐号和密
码);
get方式传输的数据量小(一般在2KB左右)但是执行效率比post高
问:IOC的理解
答:IOC(控制反转):所有的类都会在Spring容器中登记,告诉Spring你是个什么东西,你需要什么东西,然后Spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。所有的类的创建、销毁都由Spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是Spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被Spring控制,所以这叫控制反转。
DI(依赖注入):比如对象A需要操作数据库,以前我们总是要在A中自己编写代码来获得一个Connection对象,有了 spring我们就只需要告诉spring,A中需要一个Connection,至于这个Connection怎么构造,何时构造,A不需要知道。在系统运行时,spring会在适当的时候制造一个Connection,然后像打针一样,注射到A当中,这样就完成了对各个对象之间关系的控制。A需要依赖 Connection才能正常运行,而这个Connection是由spring注入到A中的,依赖注入的名字就这么来的。
问:对Tomcat的了解
答:是一个web服务器,运行jsp和servlet,使用HTTP与客户端(通常是浏览器)进行通信。
核心内容是Connector和Container组件
Connector:当从浏览器传过来http请求之后,web容器会创建一个request和response对象。在Tomcat中,负责该创建工作的是Connector组件
Container:Container容器有四个子容器:Engine、Host、Context和Wrapper,他们之间是父子包含关系。
1)、Engine
2)、Host(虚拟主机)
3)、Context(所属的web应用上下文)
4)、Wrapper(针对的是每个具体的servlet,可以说他是最直接和servlet打交道的。)
问:Linux常用的命令
答:推荐网址
Linux在哪里输入命令:ubutun里边可以中ctrl+alt+t直接呼出终端
问:java八个基本类型为什么要提供包装类
答:是为了在各种类型间转化,通过各种方法的调用。否则你无法直接通过变量转化。
在Java是面向对象编程,但八大基本类型却不是对象。所以八大基本类型都有对应的包装类型。
J2SE5.0后提供了自动装箱与拆箱的功能,所以需要通过包装类来转换。
问:java中的对象类型与基本数据类型的区别
答:栈内存中,基本类型存放的是数值,
引用类型存放的是引用的类在堆内存中的地址
问:八个基本类型所占用的空间?位是什么?
答:byte 8位 short 16位 int 32位 long 64位 float 32位 double 64位 char 16位 boolean 1位
位是一个bit,二进制中的0,1
问:ArrayList下面的API
答:
package collection;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public static void main(String [] args){
List<String> list = new ArrayList<String>();
//往list加入10个随机字符串
for(int i = 0;i < 10 ;i++){
list.add(arraylistTest.GenRandomString(5));
}
//往list中插入一个固定字符串
list.add("abc");
//1.判断arraylist是否为空
boolean isEmpty = list.isEmpty();
System.out.println("arraylist是否为空:" + isEmpty);
//2.返回列表中的元素数
int size = list.size();
System.out.println("arraylist中的元素个数为:" + size);
//3.判断arrayList中是否含有指定元素
boolean isExist = list.contains("abc");
System.out.println("arraylist中是否含有abc:" + isExist);
//4.返回arraylist中元素第一次出现的位置,若没有则返回-1
int index = list.indexOf("abc");
System.out.println("arraylist中第一次出现abc的位置是" + index);
//5.返回arraylist中元素最后一次出现的位置,若没有则返回-1
int lastIndex = list.lastIndexOf("abc");
System.out.println("arraylist最后一次出现abc的位置是" + lastIndex);
//6.返回包含此列表中所有元素的数组(按顺序),相当于数组 API和collection API的桥梁,返回一个object的数组
Object[] objectArray = list.toArray();
System.out.println("生成的数组为");
for(Object obj : objectArray){
System.out.println(obj);
}
//7.返回列表中指定位置的元素,如果超出返回,则会抛出IndexOutOfBoundsException
String s = list.get(0);
System.out.println("列表中第一个元素是:" + s);
//8.用指定的元素替代此列表中指定位置上的元素,返回值是以前位于该位上的元素
String old = list.set(0, "abc");
System.out.println("第一个元素" + old + "被替换成了abc");
//9.将元素插入到列表的尾部
System.out.println("是否插入成功:" + list.add("def"));
//10.将元素插入到指定位置,返回类型为void
list.add(0, "ghi");
//11.移除指定位置的元素
System.out.println("元素" + list.remove(0) + "已被移除");
//12.移除此列表中首次出现的指定元素(如果存在)
System.out.println("元素是否被移除:" + list.remove("abc"));
//13.按照指定 collection 的迭代器所返回的元素顺序,将该 collection 中的所有元素添加到此列表的尾部
List<String> list2 = new ArrayList<String>();
list2.add(arraylistTest.GenRandomString(5));
list2.add(arraylistTest.GenRandomString(5));
list.addAll(list2);
System.out.println("新列表为:");
for(String str: list){
System.out.println(str);
}
//14.移除列表中所有元素
list.clear();
System.out.println("移除所有元素后列表的长度为:" + list.size());
}
//生成指定长度的随机字符串
public static String GenRandomString(int length){
charArray = "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
char[] randomChar = new char [length];
for(int i = 0; i < randomChar.length; i++){
randomChar[i] = charArray[random.nextInt(61)];
}
return new String(randomChar);
}
问:ArrayList里面的数组初始化多大?什么时候把数组扩充?
答:初始为一个长度为10的Object类型数组;调用add()方法的时候自动扩容(将原来的数组内容copy到新数组,删除原来的数组,往新数组中插入元素)
问:HashMap的API?
答:
package collection;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class HashMapTest {
public static void main(String[] args) {
//hashMap是Map接口的实现,存储键值对,并允许null值和null键,此实现是非同步的
Map<Integer, Integer> map = new HashMap<Integer,Integer>();
//插入一些键值对
for(int i = 0; i < 10 ; i++){
map.put(i, i + 1);
}
//1.返回此映射中的键-值映射关系数。
int size = map.size();
System.out.println("共有键值对:" + size);
//2.判断map中是否不包含键值对
boolean isEmpty = map.isEmpty();
System.out.println("判断map中包含键值对:" + isEmpty);
//3.得到指定键映射的值,如果对于该键来说,此映射不包含任何映射关系,则返回 null
int value = map.get(1);
System.out.println("键1映射的值是:" + value);
//4.判断map中是否包含指定键
boolean isExist = map.containsKey(1);
System.out.println("map中包含键为1的映射关系:" + isExist);
//5.判断map中是否包含指定值
isExist = map.containsValue(-1);
System.out.println("map中包含值为-1的映射关系" + isExist);
//6.在map中关联指定键与值,如果该映射以前包含了一个该键的映射关系,则旧值被替换。
//返回值为与 key 关联的旧值;如果 key 没有任何映射关系,则返回 null。
map.put(11,56);
//7.将指定map的所有映射关系复制到当前map中
Map<Integer, Integer> map2 = new HashMap<Integer,Integer>();
map2.put(12, 23);
map.putAll(map2);
//8.移除指定键的映射关系
map.remove(1);
System.out.println("键为1的映射关系存在吗" + map.containsKey(1));
//9.得到map中的所有键
Set<Integer> set = map.keySet();
System.out.println("map中的键为:");
for(Integer integer : set){
System.out.println(integer);
}
//10.得到map中的所有值
Collection<Integer> collection = map.values();
System.out.println("map中的键为:");
for(Integer integer : collection){
System.out.println(integer);
}
//11.得到map中的所有键值对
Set<Entry<Integer,Integer>> set2 = map.entrySet();
for(Entry<Integer,Integer> entry : set2){
System.out.println("键 " + entry.getKey() + "值 " + entry.getValue());
}
//12.从此map中移除所有映射关系。此调用返回后,map将为空。
map.clear();
System.out.println("map中的映射数为:" + map.size());
}
}
问:HashMap为什么线程不安全?如何解决HashMap线程不安全?HashTable为什么线程安全?它通过什么手段保证线程安全?单例模式中为什么用synchronized?
答:
替代HashMap的集合类
synchronized是一个同步锁:因为在项目中如果有很大的并发量的情况下,有可能造成同时又多个程序执行这个类实例化的方法,因此我们需要在创建类实例化方法的时候添加同步执行。
问:String、StringBuffer、StringBuild的区别?StringBuffer为什么可以追加?
答:String是不可变的、StringBuffer可变线程安全、StringBuild线程不安全
(1)基本原则:如果要操作少量的数据,用String ;单线程操作大量数据,用StringBuilder ;多线程操作大量数据,用StringBuffer。
(2)不要使用String类的"+"来进行频繁的拼接,因为那样的性能极差的,应该使用StringBuffer或StringBuilder类,这在Java的优化上是一条比较重要的原则。
StringBuffer追加用它的append()方法
问:Spring的一些特性?AOP包含几个概念?你写的AOP包含几个部分、如何配置(比如日志)?什么时候触发AOP(有哪几种通知方式)?
答:IOC、AOP
实现AOP:有接口声明用JDK动态代理 无接口声明用cglib
概念:切面、连接点、处理逻辑、切点、目标类、代理类、插入
通知方式:前置通知before、后置通知afterReturning、环绕通知around、异常通知throwAdvice
问:IOC中bean的生命周期(怎么去配、有哪些)? Control层的生命周期?
答:
1、 通过构造器或工厂方法创建Bean实例
2、为Bean的属性设置值和对其它Bean的引用
3、调用Bean的初始化方法
4、Bean可以使用了
5、当容器关闭时,调用Bean的销毁方法
在 Bean 的声明里设置 init-method 和 destroy-method 属性, 为 Bean 指定初始化和销毁方法。
session 单例 Object
问:MySQL的安装、创建数据库、给这个数据库创建用户、赋一些权限?接触过分区表?
答:
问:mybatis和hibernate比较,前者的优势?SQL语句中参数的#和$占位符的区别?
答:
MyBatis可以进行更为细致的SQL优化,可以减少查询字段。
MyBatis容易掌握,而Hibernate门槛较高。
1、 #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #user_id#,如果传入的值
是111,那么解析成sql时的值为order by "111", 如果传入的值是id,则解析成的sql为order by "id".
2、 $将传入的数据直接显示生成在sql中。如:order by $user_id$,如果传入的值是111,那么解析成sql时的值为
order by user_id, 如果传入的值是id,则解析成的sql为order by id.
3、#方式能够很大程度防止sql注入。
4、$方式无法防止Sql注入。
5、$方式一般用于传入数据库对象,例如传入表名.
6、一般能用#的就别用$.
MyBatis排序时使用order by 动态参数时需要注意,用$而不是#
#{}
使用#{}意味着使用的预编译的语句,即在使用jdbc时的preparedStatement,sql语句中如果存在参数则会使用?作占位符,我们知道这种方式可以防止sql注入,并且在使用#{}时形成的sql语句,已经带有引号,例,select * from table1 where id=#{id} 在调用这个语句时我们可以通过后台看到打印出的sql为:select * from table1 where id='2' 加入传的值为2。也就是说在组成sql语句的时候把参数默认为字符串。
${}
使用${}时的sql不会当做字符串处理,是什么就是什么,如上边的语句:select * from table1 where id=${id} 在调用这个语句时控制台打印的为:select * from table1 where id=2 ,假设传的参数值为2
从上边的介绍可以看出这两种方式的区别,我们最好是能用#{}则用它,因为它可以防止sql注入,且是预编译的,在需要原样输出时才使用${},如,
select * from ${tableName} order by ${id} 这里需要传入表名和按照哪个列进行排序 ,加入传入table1、id 则语句为:select * from table1 order by id
如果是使用#{} 则变成了select * from 'table1' order by 'id' 我们知道这样就不对了。
另,在使用以下的配置时,必须使用#{}
<select id="selectMessageByIdI" parameterType="int" resultType="Message">
select * from message where id=#{id};
</select>
问:了解过SQL的注入攻击?解决方案?
答:
SQL注入攻击的简单示例:
这里我们举一个比较常见的例子来简要说明一下sql注入的原理。假如我们有一个users表,里面有两个字段username和password。在我们的java代码中我们初学者都习惯用sql拼接的方式进行用户验证。比如:"select id from users where username = '"+username +"' and password = '" + password +"'" 这里的username和password都是我们存取从web表单获得的数据。下面我们来看一下一种简单的注入,如果我们在表单中username的输入框中输入' or 1=1-- ,password的表单中随便输入一些东西,假如这里输入123。此时我们所要执行的sql语句就变成了select id from users where username = '' or 1=1-- and password = '123',我们来看一下这个sql,因为1=1是true,后面 and password = '123'被注释掉了。所以这里完全跳过了sql验证。
问:对于将来的规划?你会怎么做?你的亮点?
答: