在一家创业性的互联网公司面试经历(包含面试题)

 

主要问你简历上使用的项目和技术。另外,个人感觉互联网是一个很讲究效率和性能的,所以在代码和算法sql等上很讲究 

 

servlet是不是线程安全的?应该注意什么?

      答:首先说说什么是线程安全。如果你当前的当前进程中,有多个线程在同时进行,而多个线程可能运行同一段代码,如果运行结果和单线程运行结果一样,而且其他变量的值也是和预期一样就应该是线程安全的,反之,则线程不安全。线程安全的问题都是由全局变量和静态变量引起的,如果线程只对全局变量和静态变量进行读操作,不进行写操作,一般都是安全的。

           servlet本身就是设计在多线程的基础上的,所以多线程的类,一般都是线程不安全的。说到这里,先说说servlet的生命周期:init---service--destroied  .

       init有两种情况,如果在web.xml中,没有设置自启动servlet,那么,在用户第一次访问这个servlet的时候,会创建这个servlet实例,再根据请求类型(get/post)去调用相应的service,逻辑处理,再返回view层,当这个web服务器停止的时候,会调用destroied方法,销毁servlet实例,否则,当前servlet实例就一直存在。

      说一下servlet的线程安全性和怎么处理:

            servlet是多线程访问的,如果我们当前servlet中有全局变量或者静态变量,在service中又对这个变量进行写操作,就可能导致这个变量值不是我们预期效果,举一个例子,假如我们申明一个全局变量userName,每个请求用户名赋值给userName,并将其输出到页面,不完整代码:

public String userName="";//申明全局变量

userName=request.getUserName("userName");
response.write(userName);

如果用户A,访问的时候,我们已经得到了用户名A并赋值给了userName,还没有输出到页面,就是用户的请求还没有来得及响应,用户B发来了请求,cpu的资源就被B抢占,将userName写成了B,此时A夺回cpu资源,响应页面,结果是什么?结果A响应的就是用户B的用户名:B。

这就造成了多线程访问的时候,线程不安全。

  怎么办?一般是三个方法:实现SingleThreadModel接口,保证同时只能有一个请求访问service方法,但是性能开销大,以被servlet规范废弃;加同步锁,同样同一时刻只能有一个线程访问,其他排队等候,开销大,性能低下;避免使用全局变量,摘录网友的描述(人家描述详细点,嘿嘿。。):

          如何开发线程安全的Servlet                                                                                                                
 1,变量的线程安全:这里的变量指字段和共享数据(如表单参数值)。

  a,将 参数变量 本地化。多线程并不共享局部变量.所以我们要尽可能的在servlet中使用局部变量。
   例如:String user = "";
         user = request.getParameter("user");

  b,使用同步块Synchronized,防止可能异步调用的代码块。这意味着线程需要排队处理。
  在使用同板块的时候要尽可能的缩小同步代码的范围,不要直接在sevice方法和响应方法上使用同步,这样会严重影响性能。

 

 2,属性的线程安全:ServletContext,HttpSession,ServletRequest对象中属性
  ServletContext:(线程是不安全的)
   ServletContext是可以多线程同时读/写属性的,线程是不安全的。要对属性的读写进行同步处理或者进行深度Clone()。
   所以在Servlet上下文中尽可能少量保存会被修改(写)的数据,可以采取其他方式在多个Servlet中共享,比方我们可以使用单例模式来处理共享数据。
  HttpSession:(线程是不安全的)
   HttpSession对象在用户会话期间存在,只能在处理属于同一个Session的请求的线程中被访问,因此Session对象的属性访问理论上是线程安全的。
   当用户打开多个同属于一个进程的浏览器窗口,在这些窗口的访问属于同一个Session,会出现多次请求,需要多个工作线程来处理请求,可能造成同时多线程读写属性。
   这时我们需要对属性的读写进行同步处理:使用同步块Synchronized和使用读/写器来解决。

  ServletRequest:(线程是安全的)
   对于每一个请求,由一个工作线程来执行,都会创建有一个新的ServletRequest对象,所以ServletRequest对象只能在一个线程中被访问。ServletRequest是线程安全的。
   注意:ServletRequest对象在service方法的范围内是有效的,不要试图在service方法结束后仍然保存请求对象的引用。

 3,使用同步的集合类:
  使用Vector代替ArrayList,使用Hashtable代替HashMap。

 4,不要在Servlet中创建自己的线程来完成某个功能。
  Servlet本身就是多线程的,在Servlet中再创建线程,将导致执行情况复杂化,出现多线程安全问题。

 5,在多个servlet中对外部对象(比方文件)进行修改操作一定要加锁,做到互斥的访问。

 

说说Java中的集合主要结构:
    我们大概知道:collection是顶层接口,下有set和list,set分hashset和treeSet,list分arrayList和linkedList,Map分hashMap和treeMap这个结构就行了
   。 Map中能不能用java对象做为key值呢?这个是可以的,具体相关问题,本人也很少用到,具体了解请自行查询。


   hashcode:
   http://blog.csdn.net/chinayuan/article/details/3345559
   hashcode是一种算法,hashcode想到,equals不一定相等,equals相等,hashcode一定相等。创建一个对象,肯定创建一个hashcode,当时hashcode
   也有重复的时候,重复的话,就放在同一个hashcode链上,所以不能用hashcode简单比较两个对象,还要用equals比较。那么直接比较equals不就行了,
   为什么还要比较hashcode呢?hashcode是一个链式key/value的形式存在的,给定一个hashcode,就相当于给定了一个key就能找到快速定位找到value,
   由于hashcode有相同的情况存在,所以还需要比较equals方法,比较两个对象的内存地址。两个对象是这样比较的:先比较hashcode,如果不等,equals肯定
   不等,这对象就不等(因为hashcode是链式的,可以快速定位找到hashcode这个key对应的value,所以提高了效率),hashcode相等,再比较equals两个对象
   的内存地址,所以在覆写hashcode方法的时候,尽量保证写的算法得到的的值不一样的

   序列化和反序列化:
      实现Serializable接口,只是做一个标示,没有方法,作用:将类转换成字节流,方便存储和传输,反序列化,就是对序列化的方向操作,
      从字节流重构成一个对象,java对象在序列化的时候,会把他的所有属性和关联对象都序列化,但是static修饰的不能,因为static修饰的是
      代表类了

   数据库索引:
      create index  索引名 on 表名(列名)
      索引是放在某个列上的,索引可以增加查询速度,增加分页和排序速度,但是索引需要存储空间,在增删改的时候需要去维护索引,所以索引不是
      越多越好,应该在经常查询的字段上创建,经常where或者排序分组的字段上创建
    索引失效的情况:在直接使用导入方法导入数据库的时候,可能会使索引失效,在sql左边做了运算的时候,可能会失效,比如:
    select  * from table where id-1=9,应该使用 select * from table where id=10

    hibernate的脏数据,事物行,spring的aop和ioc

 

string和stringbuffer怎么选择使用,有什么区别:

String是final类,不可变的,所以每拼一个都是在创建一个对象

    String str="select * from table_name" ;

   str=str+" where id>10 "//这时候会再创建一个str对象,意思这个sql就用了两个string对象了

但是StringBuffer  sb=new StringBuffer( " select * from table_name" ); sb.append(" where id>10"); 这就是只有一个对象,stringbuffer是可变字符串

所以,最好选用stringBuffer,减少系统消耗,提高性能

 

jdk1.5后,引入了stringBuilder,这个是单线程,速度更快,但是线程不安全,所以单从速度上将:stringbuilder>stringBuffer>string 也要考虑线程安全性

 


         

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值