随笔之java面试

问: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命令。

答:maven命令之博客1       

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与客户端(通常是浏览器)进行通信。

核心内容是ConnectorContainer组件

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验证。

SQL注入攻击推荐博客

注入攻击解决方案推荐博客


问:对于将来的规划?你会怎么做?你的亮点?

答:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值