java面试四

来源:互联网 发布:mac不安装flash 编辑:程序博客网 时间:2024/06/13 05:40

一.String的”+”为什么是字符串拼接而不是运算

  String类型本身是不能直接做加减法的,需要将string中的每一位转化为对应的数字(**通常是将字符串转化为数组**)

二.连接池原理和实例

1.原理:    问题的根源就在于对数据库连接资源的低效管理。我们知道,对于共享资源,有一个很著名的设计模式:资源池(resource pool)。该模式正是为了解决资源的频繁分配﹑释放所造成的问题。为解决上述问题,可以采用数据库连接池技术。数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。我们可以通过设定连接池最大连接数来防止系统无尽的与数据库连接。更为重要的是我们可以通过连接池的管理机制监视数据库的连接的数量﹑使用情况,为系统开发﹑测试及性能调整提供依据。2.实例:public class MyDataSource implements DataSource {            //链表 --- 实现栈结构      privateLinkedList<Connection> dataSources = new LinkedList<Connection>();            //初始化连接数量      publicMyDataSource() {           //一次性创建10个连接          for(int i = 0; i < 10; i++) {               try {       //1、装载sqlserver驱动对象                          DriverManager.registerDriver(new SQLServerDriver());      //2、通过JDBC建立数据库连接      Connection con =DriverManager.getConnection(                                "jdbc:sqlserver://192.168.2.6:1433;DatabaseName=customer", "sa", "123");     //3、将连接加入连接池中     dataSources.add(con);        } catch (Exception e) {           e.printStackTrace();       }      }   }    @Override    publicConnection getConnection() throws SQLException {                   //取出连接池中一个连接                   finalConnection conn = dataSources.removeFirst(); // 删除第一个连接返回                   returnconn;            }            //将连接放回连接池    public void releaseConnection(Connection conn){                   dataSources.add(conn);         }     } 

三.多态

    为什么要用 List list = new ArrayList() ,而不用 ArrayList alist = new ArrayList()呢? 问题就在于List有多个实现类,现在你用的是ArrayList,也许哪一天你需要换成其它的实现类,如 LinkedList或者Vector等等,这时你只要改变这一行就行了: List list = new LinkedList(); 其它使用了list地方的代码根本不需要改动。      假设你开始用 ArrayList alist = new ArrayList(), 这下你有的改了,特别是如果你使用了 ArrayList特有的方法和属性。实现多态三要素:1.要有继承2.重写父类方法3.父类引用指向子类对象多态的作用:   把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。

四.实现多线程的几种方式:

Java多线程实现方式主要有四种:继承Thread类、实现Runnable接口、实现Callable接口通过FutureTask包装器来创建Thread线程、使用ExecutorService、Callable、Future实现有返回结果的多线程。其中前两种方式线程执行完后都没有返回值,后两种是带返回值的。1、继承Thread类创建线程Thread类本质上是实现了Runnable接口的一个实例,代表一个线程的实例。启动线程的唯一方法就是通过Thread类的start()实例方法。start()方法是一个native方法,它将启动一个新线程,并执行run()方法。这种方式实现多线程很简单,通过自己的类直接extend Thread,并复写run()方法,就可以启动新线程并执行自己定义的run()方法。例如:复制代码public class MyThread extends Thread {    public void run() {     System.out.println("MyThread.run()");    }  }  MyThread myThread1 = new MyThread();  MyThread myThread2 = new MyThread();  myThread1.start();  myThread2.start();  复制代码2、实现Runnable接口创建线程如果自己的类已经extends另一个类,就无法直接extends Thread,此时,可以实现一个Runnable接口,如下:为了启动MyThread,需要首先实例化一个Thread,并传入自己的MyThread实例:事实上,当传入一个Runnable target参数给Thread后,Thread的run()方法就会调用target.run(),参考JDK源代码:3、实现Callable接口通过FutureTask包装器来创建Thread线程Callable接口(也只有一个方法)定义如下:   public interface Callable<V>   {   V call() throws Exception;   } 复制代码public class SomeCallable<V> extends OtherClass implements Callable<V> {    @Override    public V call() throws Exception {        // TODO Auto-generated method stub        return null;    }}复制代码复制代码Callable<V> oneCallable = new SomeCallable<V>();   //由Callable<Integer>创建一个FutureTask<Integer>对象:   FutureTask<V> oneTask = new FutureTask<V>(oneCallable);   //注释:FutureTask<Integer>是一个包装器,它通过接受Callable<Integer>来创建,它同时实现了Future和Runnable接口。   //由FutureTask<Integer>创建一个Thread对象:   Thread oneThread = new Thread(oneTask);   oneThread.start();   //至此,一个线程就创建完成了。复制代码4、使用ExecutorService、Callable、Future实现有返回结果的线程ExecutorService、Callable、Future三个接口实际上都是属于Executor框架。返回结果的线程是在JDK1.5中引入的新特征,有了这种特征就不需要再为了得到返回值而大费周折了。而且自己实现了也可能漏洞百出。可返回值的任务必须实现Callable接口。类似的,无返回值的任务必须实现Runnable接口。执行Callable任务后,可以获取一个Future的对象,在该对象上调用get就可以获取到Callable任务返回的Object了。注意:get方法是阻塞的,即:线程无返回结果,get方法会一直等待。再结合线程池接口ExecutorService就可以实现传说中有返回结果的多线程了。下面提供了一个完整的有返回结果的多线程测试例子,在JDK1.5下验证过没问题可以直接使用。代码如下:复制代码import java.util.concurrent.*;  import java.util.Date;  import java.util.List;  import java.util.ArrayList;  /** * 有返回值的线程 */  @SuppressWarnings("unchecked")  public class Test {  public static void main(String[] args) throws ExecutionException,      InterruptedException {     System.out.println("----程序开始运行----");     Date date1 = new Date();     int taskSize = 5;     // 创建一个线程池     ExecutorService pool = Executors.newFixedThreadPool(taskSize);     // 创建多个有返回值的任务     List<Future> list = new ArrayList<Future>();     for (int i = 0; i < taskSize; i++) {      Callable c = new MyCallable(i + " ");      // 执行任务并获取Future对象      Future f = pool.submit(c);      // System.out.println(">>>" + f.get().toString());      list.add(f);     }     // 关闭线程池     pool.shutdown();     // 获取所有并发任务的运行结果     for (Future f : list) {      // 从Future对象上获取任务的返回值,并输出到控制台      System.out.println(">>>" + f.get().toString());     }     Date date2 = new Date();     System.out.println("----程序结束运行----,程序运行时间【"       + (date2.getTime() - date1.getTime()) + "毫秒】");  }  }  class MyCallable implements Callable<Object> {  private String taskNum;  MyCallable(String taskNum) {     this.taskNum = taskNum;  }  public Object call() throws Exception {     System.out.println(">>>" + taskNum + "任务启动");     Date dateTmp1 = new Date();     Thread.sleep(1000);     Date dateTmp2 = new Date();     long time = dateTmp2.getTime() - dateTmp1.getTime();     System.out.println(">>>" + taskNum + "任务终止");     return taskNum + "任务返回运行结果,当前任务时间【" + time + "毫秒】";  }  }  复制代码代码说明:上述代码中Executors类,提供了一系列工厂方法用于创建线程池,返回的线程池都实现了ExecutorService接口。public static ExecutorService newFixedThreadPool(int nThreads) 创建固定数目线程的线程池。public static ExecutorService newCachedThreadPool() 创建一个可缓存的线程池,调用execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。public static ExecutorService newSingleThreadExecutor() 创建一个单线程化的Executor。public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) 创建一个支持定时及周期性的任务执行的线程池,多数情况下可用来替代Timer类。ExecutoreService提供了submit()方法,传递一个Callable,或Runnable,返回Future。如果Executor后台线程池还没有完成Callable的计算,这调用返回Future对象的get()方法,会阻塞直到计算完成。

五.linux配置日志

一、Linux系统日志作用日志对任何一个OS、应用软件、服务进程而言都是必不可少的模块。日志文件对于系统和网络安全起到中大作用,同时具有审计、跟踪、排错功能。可以通过日志文件监测系统与网络安全隐患,以及监测黑客入侵攻击路线。二、日志分类1. 连接时间的日志连接时间日志一般由/var/log/wtmp和/var/run/utmp这两个文件记录,不过这两个文件无法直接cat查看,并且该文件由系统自动更新,可以通过如下:w/who/finger/id/last/lastlog/ac 进行查看[root@51cto ~]# whoroot     tty1         2010-10-06 22:56root     pts/0        2010-10-06 22:26 (218.192.87.4)root     pts/1        2010-10-06 23:41 (218.192.87.4)root     pts/3        2010-10-06 23:18 (218.192.87.4)[root@51cto ~]# w01:01:02 up  2:36,  4 users,  load average: 0.15, 0.03, 0.01USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHATroot     tty1     -                            22:56    1:20m  0.16s  0.16s -bashroot     pts/0    218.192.87.4     22:26    2:05m  0.18s  0.18s -bashroot     pts/1    218.192.87.4     23:41    0.00s     0.41s  0.00s wroot     pts/3    218.192.87.4     23:18    1:38m  0.03s  0.03s -bash[root@51cto ~]# ac -p    //查看每个用户的连接时间        u51                                  1.23        u55                                  0.04        root                                95.21    //可以看到root连接时间最长吧        51cto                                0.06        user1                                3.93        total      100.48[root@51cto ~]# ac -a     //查看所有用户的连接时间        total      100.49[root@51cto ~]# ac -d     //查看用户每天的连接时间Sep 24  total        0.14Sep 25  total       14.60Sep 26  total       13.71Sep 27  total       21.47Sep 28  total       11.74Sep 29  total        6.60Sep 30  total        8.81Oct  1   total        9.04Oct  2   total        0.47       //可以看到我国庆345号出去玩了Oct  6   total        8.62Today   total        5.29其他几个命令不做具体介绍了2. 进程监控日志进程统计监控日志在监控用户的操作指令是非常有效的。当服务器最近发现经常无故关机或者无故被人删除文件等现象时,可以通过使用进程统计日志查看:[root@51cto ~]# accton /var/account/pacct      //开启进程统计日志监控[root@51cto ~]# lastcomm     //查看进程统计日志情况accton            S     root     pts/1      0.00 secs Thu Oct  7 01:20accton                   root     pts/1      0.00 secs Thu Oct  7 01:20ac                           root     pts/1      0.00 secs Thu Oct  7 01:14ac                           root     pts/1      0.00 secs Thu Oct  7 01:14free                        root     pts/1      0.00 secs Thu Oct  7 01:10lastcomm              root     pts/1      0.00 secs Thu Oct  7 01:09bash               F     root     pts/1      0.00 secs Thu Oct  7 01:09lastcomm              root     pts/1      0.00 secs Thu Oct  7 01:09ifconfig                 root     pts/1      0.00 secs Thu Oct  7 01:09lastcomm             root     pts/1      0.00 secs Thu Oct  7 01:09lastcomm             root     pts/1      0.00 secs Thu Oct  7 01:09lastcomm             root     pts/1      0.00 secs Thu Oct  7 01:09accton           S     root     pts/1      0.00 secs Thu Oct  7 01:09[root@51cto ~]# accton     //关闭进程统计日志监控3. 系统和服务日志系统日志服务是由一个名为syslog的服务管理的,如一下日志文件都是由syslog日志服务驱动的:/var/log/lastlog    :记录最后一次用户成功登陆的时间、登陆IP等信息/var/log/messages   :记录Linux操作系统常见的系统和服务错误信息/var/log/secure  :Linux系统安全日志,记录用户和工作组变坏情况、用户登陆认证情况/var/log/btmp :记录Linux登陆失败的用户、时间以及远程IP地址/var/log/cron :记录crond计划任务服务执行情况…...[root@51cto ~]# cat /var/log/lastlogLpts/0218.192.87.4Lpts/1218.192.87.4Lpts/1218.192.87.4Lpts/0218.192.87.46Lpts/0218.192.87.4…...三、Linux日志服务介绍1. 在Linux系统,大部分日志都是由syslog日志服务驱动和管理的,syslog服务由两个重要的配置文件控制管理,分别是/etc/syslog.conf主配置文件和/etc/sysconfig/syslog辅助配置文件, /etc/init.d/syslog是启动脚本,这里主讲主配置文件/etc/syslog.conf:/etc/syslog.conf 语句结构:[root@51cto ~]# grep -v "#" /etc/syslog.conf     //列出非#打头的每一行*.info;mail.none;authpriv.none;cron.none                /var/log/messagesauthpriv.*                                                                        /var/log/securemail.*                                                                             -/var/log/maillogcron.*                                                                               /var/log/cron*.emerg                                                                            *uucp,news.crit                                                              /var/log/spoolerlocal7.*                                                                           /var/log/boot.log选择域(消息类型.错误级别)                          动作域2. 消息类型:auth,authpriv,security;cron,daemon,kern,lpr,mail,       mark,news,syslog,user,uucp,local0~local7.错误级别:(8级)debug,info,notice,warning|warn;err|error;crit,alert,emerg|panic动作域:file,user,console,@remote_ip举如上的/etc/syslog.conf文件三个例子:*.info;mail.none;authpriv.none;cron.none           /var/log/messages   表示info级别的任何消息都发送到/var/log/messages日志文件,但邮件系统、验证系统和计划任务的错误级别信息就除外,不发送(none表示禁止)cron.*             /var/log/cron        表示所有级别的cron信息发到/var/log/cron文件*.emerg           *            表示emerg错误级别(危险状态)的所有消息类型发给所有用户四、Linux日志服务器配置此服务器的配置非常简单,只是修改一个文件的一个地方,然后重启服务即可:[root@51cto ~]# grep -v "#" /etc/sysconfig/syslogSYSLOGD_OPTIONS="-m 0 -r"    //只要在这里添加“-r”就行咯KLOGD_OPTIONS="-x"SYSLOG_UMASK=077[root@51cto ~]# service syslog restart关闭内核日志记录器:                                       [确定]关闭系统日志记录器:                                       [确定]启动系统日志记录器:                                       [确定]启动内核日志记录器:                                       [确定]对于发送消息到服务器的OS,只要在写/etc/syslog.conf主配置文件的时候,作用域为@server-ip就行了,比如针对218.192.87.24这台日志服务器,把一台ubuntu系统的所有info级别的auth信息发给日志服务器,那么对于ubuntu系统的/etc/syslog.conf文件最后一行添加  auth.info           @218.192.87.24  就OK了五、日志转储服务系统工作到了一定时间后,日志文件的内容随着时间和访问量的增加而越来越多,日志文件也越来越大。而且当日志文件超过系统控制范围时候,还会对系统性能造成影响。转储方式可以设为每年转储、每月转储、每周转储、达到一定大小转储。在Linux系统,经常使用“logrotate”工具进行日志转储,结合cron计划任务,可以轻松实现日志文件的转储。转储方式的设置由“/etc/logrotate.conf”配置文件控制:[root@51cto ~]# cat /etc/logrotate.conf# see "man logrotate" for details              //可以查看帮助文档# rotate log files weeklyweekly                  //设置每周转储# keep 4 weeks worth of backlogsrotate 4               //最多转储4# create new (empty) log files after rotating old onescreate                  //当转储后文件不存储时创建它# uncomment this if you want your log files compressed#compress                   //以压缩方式转储# RPM packages drop log rotation information into this directoryinclude /etc/logrotate.d             //其他日志文件的转储方式,包含在该目录下# no packages own wtmp -- we'll rotate them here/var/log/wtmp {                       //设置/var/log/wtmp日志文件的转储参数    monthly                              //每月转储    create 0664 root utmp        //转储后文件不存在时创建它,文件所有者为root,                                                                所属组为utmp,对应的权限为0664    rotate 1                                 //转储一次}# system-specific logs may be also be configured here.2个例子:为/var/log/news/目录下的所有文件设置转储参数,每周转储,转储2次,转储时将老的日志文件放到/var/log/news/old目录下,若日志文件不存在,则跳过。完成后重启news新闻组服务,转储时不压缩。那么可以在/etc/logrotate.conf文件的最后添加如下:/var/log/news/*{    monthly    rotate  2    olddir   /var/log/news/old     missingok    postrotate        kill   -HUP `cat   /var/run/inn.pid`     endscript     nocompress}另一个例子:为/var/log/httpd/access.log和/var/log/httpd/error.log日志设置转储参数。转储5次,转储时发送邮件给[email=root@localhost]root@localhost[/email]用户,当日志文件达到100KB时才转储,转储后重启httpd服务,那么可以直接在/etc/logrotate.conf文件的最后添加如下:/var/log/httpd/access.log   /var/log/http/error.log{    rotate  5    mail   [email=root@localhost]root@localhost[/email]    size=100k    sharedscripts         /sbin/killall   -HUP  httpd    endscript}六、自定义日志转储(/etc/logrotate.d/*)通过下面一个例子将所有类型错误级别为info的日志转储到/var/log/test.log日志文件中,并设置/var/log/test.log达到50KB后进行转储,转储10次,转储时压缩,转储后重启syslog服务:1、修改/etc/syslog.conf文件使得如下:[root@51cto ~]# tail -1 /etc/syslog.conf       //查看该文件的最后一行*.info                  /var/log/test.log2、重启syslog服务:[root@51cto ~]# /sbin/service syslog restart关闭内核日志记录器:                                       [确定]关闭系统日志记录器:                                       [确定]启动系统日志记录器:                                       [确定]启动内核日志记录器:                                       [确定]3、创建/etc/logrotate.d/test.log日志转储参数配置文件,添加如下:[root@51cto ~]# vim /etc/logrotate.d/test.log[root@51cto ~]# cat /etc/logrotate.d/test.log/var/log/test.log{    rotate  10    size = 50k    compress    postrotate     killall -HUP  syslog    endscript}4、查看文件/etc/cron.daily/logrotate确保如下:[root@51cto ~]# cat /etc/cron.daily/logrotate#!/bin/sh/usr/sbin/logrotate /etc/logrotate.confEXITVALUE=$?if [ $EXITVALUE != 0 ]; then    /usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"fiexit 05、查看转储后的文件[root@51cto log]# pwd/var/log[root@51cto log]# ls test.log*……       //结果等要转储的时候会发现压缩文件和原本的test.log文件

六.接口与实现类

1.两个接口方法和参数列表,返回值均相同实现类只实现相同的方法

1.接口Apackage com.lrq.test;public interface A {    public void test(String a);}2.接口Bpackage com.lrq.test;public interface B {    public void test(Integer a);}3.实现类package com.lrq.test;public class TestInterface implements A,B {    public static void main(String[] args) {        new TestInterface().test("123");    }    @Override    public void test(String a) {        System.out.println(a);    }}

2.两个接口方法,返回值均相同但参数列表不同实现类会要求实现两个接口的方法(会认为是不同的方法,参数列表不一致)

接口Apackage com.lrq.test;public interface A {    public void test(String a);}接口Bpackage com.lrq.test;public interface B {    public void test(Integer a);}实现类package com.lrq.test;public class TestInterface implements A,B {    public static void main(String[] args) {        new TestInterface().test("123");    }    @Override    public void test(String a) {        System.out.println(a);    }    @Override    public void test(Integer a) {        System.out.println(a);    }}

3.两个接口方法,参数列表均相同但返回值不同实现类会要求实现两个接口的方法(会认为是不同的方法,返回值不一致)

接口Apackage com.lrq.test;public interface A {    public void test(String a);}接口Bpackage com.lrq.test;public interface B {    public int test(Integer a);}实现类package com.lrq.test;public class TestInterface implements A,B {    public static void main(String[] args) {        new TestInterface().test("123");    }    @Override    public void test(String a) {        System.out.println(a);    }    @Override    public int test(Integer a) {        // TODO Auto-generated method stub        return 0;    }}

七.cookie和session的区别

cookie 和session 的区别:1、cookie数据存放在客户的浏览器上,session数据放在服务器上。2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗   考虑到安全应当使用session。3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能   考虑到减轻服务器性能方面,应当使用COOKIE。4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。5、所以个人建议:   将登陆信息等重要信息存放为SESSION   其他信息如果需要保留,可以放在COOKIE中
1 0
原创粉丝点击