java2017面试题新手看绝佳!!

前段时间浏览java吧,遇到一个新人面试,坐标上海,面试了四五家的面试题贴在贴吧里,但是没有给出答案,很是无语,于是自己总结了一份记录在这里,以便需要的人查看。

第一题:Spring是什么

答:Spring是一个开源的轻量级Java SE(Java 标准版本)/Java EE(Java 企业版本)开发应用框架,其目的是用于简化企业级应用程序开发。Spring框架除了帮我们管理对象及其依赖关系,还提供像通用日志记录、性能统计、安全控制、异常处理等面向切面的能力,还能帮我管理最头疼的数据库事务,本身提供了一套简单的JDBC访问实现,提供与第三方数据访问框架集成(如Hibernate、JPA),与各种Java EE技术整合(如Java Mail、任务调度等等),提供一套自己的web层框架Spring MVC、而且还能非常简单的与第三方web框架集成

Spring能帮我们做什么?Spring除了不能帮我们写业务逻辑,其余的几乎什么都能帮助我们简化开发!

http://blog.csdn.net/lp1052843207/article/details/51253071

第二题:什么是IOC

答:IOC就是依赖、依赖倒置、依赖注入、控制反转

依赖:就是有联系,有地方使用到它就是有依赖它,一个系统不可能完全避免依赖。如果你的一个类或者模块在项目中没有用到它,恭喜你,可以从项目中剔除它或者排除它了,因为没有一个地方会依赖它。两个类之间的调用就是一种依赖

依赖倒置:就是通过增加接口来降低耦合度,进行优化,因为接口是稳定的

依赖反转:就是讲控制层的控制权交给配置文件,而不是代码,我们只需要修改配置文件就可以控制功能

依赖注入:就是由IoC容器在运行期间,动态地将某种依赖关系注入到对象之中。

http://www.cnblogs.com/fuchongjundream/p/3873073.html
第三题:什么是Spering aop  有几种实现方式
答:Aop也就是面向切面编程思想,实现由以下四种

         1、基于代理的AOP

         2、纯简单java对象切面

         3@Aspect注解形式的

         4、注入形式的Aspcet切面

我认为的主要思想就是找到切点,切面,实现aop  我接触的一般都是在配置文件中通过全局匹配定义切点,然后通过id 增强切面。
  1. <!-- 创建一个增强 advice -->  
  2.     <bean id ="sleepHelper" class="com.tgb.springaop.aspect.SleepHelper"/>  
  3.   
  4.     <bean id="lina" class="com.tgb.springaop.service.impl.ChenLliNa"/>  
  5.     <!-- 定义切点   匹配所有的sleep方法-->  
  6.     <bean id ="sleepPointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">  
  7.            <property name="pattern" value=".*sleep"></property>  
  8.     </bean>  
  9.       
  10.     <!-- 切面    增强+切点结合 -->  
  11.     <bean id="sleepHelperAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">  
  12.          <property name="advice" ref="sleepHelper"/>  
  13.          <property name="pointcut" ref="sleepPointcut"/>  
  14.     </bean>  
  15.       
  16.     <!-- 定义代理对象 -->  
  17.     <bean id="linaProxy" class="org.springframework.aop.framework.ProxyFactoryBean">  
  18.             <property name="target" ref="lina"/>  
  19.             <property name="interceptorNames" value="sleepHelperAdvisor"/>  
  20.             <!-- <property name="proxyInterfaces" value="com.tgb.springaop.service.Sleepable"/> -->  
  21.     </bean>  

http://blog.csdn.net/jly4758/article/details/46290035
第四题:MyBatis中#{}和${}的区别详解
答:

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 动态参数时需要注意,用$而不是#

字符串替换

默认情况下,使用#{}格式的语法会导致MyBatis创建预处理语句属性并以它为背景设置安全的值(比如?)。这样做很安全,很迅速也是首选做法,有时你只是想直接在SQL语句中插入一个不改变的字符串。比如,像ORDER BY,你可以这样来使用:
ORDER BY ${columnName}

这里MyBatis不会修改或转义字符串。

重要:接受从用户输出的内容并提供给语句中不变的字符串,这样做是不安全的。这会导致潜在的SQL注入攻击,因此你不应该允许用户输入这些字段,或者通常自行转义并检查。

第五题:什么是redis,它能做什么

答:Redis简单来说就是一个key-value存储系统,通过键值对将数据存储到内存中,注意这里是内存,而不是数据库,所以存储效率非常高,缺点就是占用内存很大,比如网站首页一天有100万人访问,其中有一个板块为推荐新闻。要是直接从数据库查询,那么一天就要多消耗100万次数据库请求。上面已经说过,Redis支持丰富的数据类型,所以这完全可以用Redis来完成,将这种热点数据存到Redis(内存)中,要用的时候,直接从内存取,极大的提高了速度和节约了服务器的开销。

使用方法:在服务器下载安装好redis,然后通过代码写入读取方式就可以直接使用,是在服务器上安装使用,而不是在客户端做操作,存取代码的逻辑后台实现,只是存取的位置不是在数据库而是在内存!,,这是思想误区,便于理解。

第六题:用Quartz处理定时任务

答:比如每天凌晨恢复疲劳值,这就是一种定时任务

第一步:引包,下面是必要的四个包

 1、log4j-1.2.16

 2、quartz-2.1.7

 3、slf4j-api-1.6.1.jar

 4、slf4j-log4j12-1.6.1.jar

第二步:创建要被执行的任务类,实现org.quartz.job接口的类并实现相应方法

第三步:创建任务调度,并执行,直接上代码

  1. public class Test { 
  2.     public void go() throws Exception { 
  3.         // 首先,必需要取得一个Scheduler的引用 
  4.       SchedulerFactory sf = new StdSchedulerFactory(); 
  5.         Scheduler sched = sf.getScheduler(); 
  6.         //jobs可以在scheduled的sched.start()方法前被调用 
  7.          
  8.         //job 1将每隔20秒执行一次 
  9.         JobDetail job = newJob(myJob.class).withIdentity("job1", "group1").build(); 
  10.         CronTrigger trigger = newTrigger().withIdentity("trigger1", "group1").withSchedule(cronSchedule("0/20 * * * * ?")).build(); 
  11.         Date ft = sched.scheduleJob(job, trigger); 
  12.         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS"); 
  13.         System.out.println(job.getKey() + " 已被安排执行于: " + sdf.format(ft) + ",并且以如下重复规则重复执行: " + trigger.getCronExpression()); 
  14.  
  15.         // job 2将每2分钟执行一次(在该分钟的第15秒) 
  16.         job = newJob(myJob.class).withIdentity("job2", "group1").build(); 
  17.         trigger = newTrigger().withIdentity("trigger2", "group1").withSchedule(cronSchedule("15 0/2 * * * ?")).build(); 
  18.         ft = sched.scheduleJob(job, trigger); 
  19.        System.out.println(job.getKey() + " 已被安排执行于: " + sdf.format(ft) + ",并且以如下重复规则重复执行: "+ trigger.getCronExpression()); 
  20.         
  21.         // 开始执行,start()方法被调用后,计时器就开始工作,计时调度中允许放入N个Job 
  22.       sched.start(); 
  23.         try { 
  24.             //主线程等待一分钟 
  25.             Thread.sleep(60L * 1000L); 
  26.         } catch (Exception e) {}     
  27.        //关闭定时调度,定时器不再工作 
  28.        sched.shutdown(true); 
  29.  
  30.     public static void main(String[] args) throws Exception { 
  31.  
  32.         Test test = new Test(); 
  33.         test.go(); 
  34.     } 
  35.  

 OK了,Job1和Job2就会被安排为定时执行了。此时程序是可以执行的了,但是可能会输出WARN级别日志,这是因为没有加log4j的配置文件,加上配置文件,就OK了。这里需要说明的地方只有一个,其它的可以直接Copy到您的项目里面。看代码:

Java代码 复制代码 收藏代码
  1. CronTrigger trigger = newTrigger().withIdentity("trigger1", "group1").withSchedule(cronSchedule("0/20 * * * * ?")).build(); 
CronTrigger trigger = newTrigger().withIdentity("trigger1", "group1").withSchedule(cronSchedule("0/20 * * * * ?")).build();

  "0/20 * * * * ?"代表什么?这是关键,搞明白这个,Quartz就能帮助你解决大部分的定时执行任务的功能。详细解释请看下面转载见容

常用示例:

0 0 12 * * ? 每天12点触发
0 15 10 ? * * 每天10点15分触发
0 15 10 * * ? 每天10点15分触发
0 15 10 * * ? * 每天10点15分触发
0 15 10 * * ? 2005 2005年每天10点15分触发
0 * 14 * * ? 每天下午的 2点到2点59分每分触发
0 0/5 14 * * ? 每天下午的 2点到2点59分(整点开始,每隔5分触发)
0 0/5 14,18 * * ? 每天下午的 2点到2点59分(整点开始,每隔5分触发) 每天下午的 18点到18点59分(整点开始,每隔5分触发)
0 0-5 14 * * ? 每天下午的 2点到2点05分每分触发
0 10,44 14 ? 3 WED 3月分每周三下午的 2点10分和2点44分触发
0 15 10 ? * MON-FRI 从周一到周五每天上午的10点15分触发
0 15 10 15 * ? 每月15号上午10点15分触发
0 15 10 L * ? 每月最后一天的10点15分触发
0 15 10 ? * 6L 每月最后一周的星期五的10点15分触发
0 15 10 ? * 6L 2002-2005 从2002年到2005年每月最后一周的星期五的10点15分触发
0 15 10 ? * 6#3 每月的第三周的星期五开始触发
0 0 12 1/5 * ? 每月的第一个中午开始每隔5天触发一次
0 11 11 11 11 ? 每年的11月11号 11点11分触发(光棍节)
http://www.blogjava.net/xmatthew/archive/2009/02/15/253864.html
第七题:如何快速读取properties文件内容
答:我自己理解就是通过application文件中的 content:property-placeholder加载配置文件
这里讲到五种方法,感兴趣的可以移驾看下http://www.cnblogs.com/hafiz/p/5876243.html

第八题:单点登录的实现,为什么session没有token应用广泛
答:通过cookie缓存,最简单的单点登录实现方式,是使用cookie作为媒介,存放用户凭证。用户登录父应用之后,应用返回一个加密的cookie,当用户访问子应用的时候,携带上这个cookie,授权应用解密cookie并进行校验,校验通过则登录当前用户。不过这种方式 不安全,不能跨域免登。2通过jsonp实现,对于跨域问题,可以使用JSONP实现。用户在父应用中登录后,跟Session匹配的Cookie会存到客户端中,当用户需要登录子应用的时候,授权应用访问父应用提供的JSONP接口,并在请求中带上父应用域名下的Cookie,父应用接收到请求,验证用户的登录状态,返回加密的信息,子应用通过解析返回来的加密信息来验证用户,如果通过验证则登录用户。不过依然存在安全问题。第三种通过页面重定向的方式,最后一种介绍的方式,是通过父应用和子应用来回重定向中进行通信,实现信息的安全传递。父应用提供一个GET方式的登录接口,用户通过子应用重定向连接的方式访问这个接口,如果用户还没有登录,则返回一个的登录页面,用户输入账号密码进行登录。如果用户已经登录了,则生成加密的Token,并且重定向到子应用提供的验证Token的接口,通过解密和校验之后,子应用登录当前用户。就是麻烦点,但是安全性高
http://cnodejs.org/topic/55f6e69904556da7553d20dd
最后打个广告,个人公众号《行走的java》,不定时推出java学习心得,都是精华中的精华,感兴趣的同学帮忙关注推广下


猜你喜欢

转载自blog.csdn.net/ss_aa_aa/article/details/78466027
今日推荐