一些面试常见问题

  有时候在想,对于一个Java程序员来说(也是在找工作的时候,才给自己贴上了标签,其实一直觉得语言都是没有什么大的区别,只是应用场景不同而已,重要的是算法与思想以及业务规则等),是一些基础的知识重要,还是各种框架的掌握与使用,特别是一些开源的框架的使用重要的问题,大家可以讨论此问题……,由于以前公司用的框架都是自己开发与封装的,因此对于很多开源的框架用的较为少,但是,混了这么长时间,大多的东西直接拿过来是就能上手用的,出现问题一般也能快速定位与解决,但是,在面试的时候,往往还是显得捉襟见肘,而这也阻碍了我表现出能够快速在工作中解决问题与实现方法的能力,似乎是个很大的弊端,所以,最近几天还是想恶补一些这个方面的知识。另外,由于各个公司的应用场景不同,因此,对于问题的侧重点也自然是不同,这一点对于一个找工作的人来说就是很头疼的,因此找工作的时候就不得不不断的总结知识,扩展知识面。

  还是先说说一些基本的问题:

一、java中字符串相等判断问题:写出如下代码的输出结果

        Object s1=new String("Hello");
        Object s2=new String("Hello");
        if(s1==s2){
            System.out.println("s1 = s2");
        }else if(s1.equals(s2)){
            System.out.println("s1 equals s2");
        }            

这个问题很简单,对于稍有java基础的人,应该都不是问题,给出代码中s1与s2是两个对象,要用equals表示比较他们的内容是否相同,另外还有一种是如下情况:

     String s1="abc";
        String s2="abc";

这种写法,上边两种方法都是可以进行比较的。==表示指向字符串的引用是否相同,这里s1与s2是指向同一对象。关于String常见问题推荐大家看这里

二、java关于函数参数传递,与对象传递,改变值得问题。写出如下代码的输出结果:

/**
* @FileName Test.java
* @Package com.util.test
* @Description TODO[what the file to do]
* @Author ali blog:http://www.cnblogs.com/accipiter
* @Date 2016年1月27日下午8:26:40
* @Version V1.0.1
*/
package com.util.test;

/**
 * @ClassName Test
 * @Description TODO
 * @Date 下午8:26:40
 */
public class Test {

    public static void main(String[] args) {
        String s=new String("xxx");
        Test ts=new Test();
        Module m = ts.new Module();
        m.str="yyy";
        changeValue(s,m);
        System.out.println(s+m.str);
    }
    
    public static void changeValue(String str,Module m){
        str="aaa";
        m.str="bbb";
    }
    class Module{
        public String str;
    };
}

这个要写出结果不太难,结果为:xxxbbb。关于传值和传递引用的区别,可以参考这篇文章这篇可能论及的更加深入。这里重点还会涉及到java的内存分配模型,这是一个很深的问题,这里只稍微提一下,以后细论。

三、java中常见的Collection与map实现类,以及类图。

 这个问题,对于不同的JDK有不同的回答,因此问的算是有些宽泛吧,但是常用的话还是就那几种,collection全部的话jdk8可以参照官方给出的文档是34种实现类,比jdk7要多出一种concurrentHashMap.KeySite类。

关于map,可以参考官方文档。这里着重注意HashMap与TreeMap.关于二者使用效率的比较参考此文。还有HashMap是不同步的,而HashTable是同步的。

这里有如下一点总结:

  如果涉及到堆栈,队列等操作,应该考虑用List,对于需要快速插入,删除元素,应该使用LinkedList,如果需要快速随机访问元素,应该使用ArrayList。
    如果程序在单线程环境中,或者访问仅仅在一个线程中进行,考虑非同步的类,其效率较高,如果多个线程可能同时操作一个类,应该使用同步的类。
    在除需要排序时使用TreeSet,TreeMap外,都应使用HashSet,HashMap,因为他们 的效率更高。
    要特别注意对哈希表的操作,作为key的对象要正确复写equals和hashCode方法。
    容器类仅能持有对象引用(指向对象的指针),而不是将对象信息copy一份至数列某位置。一旦将对象置入容器内,便损失了该对象的型别信息。
    尽量返回接口而非实际的类型,如返回List而非ArrayList,这样如果以后需要将ArrayList换成LinkedList时,客户端代码不用改变。这就是针对抽象编程。

四、MySql子查询与关联查询的效率问题

  实际上这个问题,在数据量小的时候是没有区别的,在数据量大的时候,关联查询是明显优于子查询的。但是,这个也看具体的业务应用场景,对于数据库的好多优化多是在实践中产生出来的,单纯的拿出来作为问题,回答起来似乎有些没有着力点。。

五、用shell语句实现统计500w条Nginx日志文件IP访问情况

  如下,是我测试写的,第二条语句要优于第一条。
cat access.log |awk '{print $1}'| sort |uniq -c|sort -nr|less
awk '{print $1}' access.log-20160130| sort |uniq -c|sort -nr>ip.txt

另外也可以采用如下的python实现:

#定义ip访问流量和ip访问次数字典
ipflow = {}
ipnum = {}

#读取日志
f = open("access.log","r")
logs = f.readlines()
f.close()
#统计ip访问次数和流量
for line in logs:
    ip = line.split()[0]
    flow = line.split()[9]
    if ip in set(k.lower() for k in ipflow):
        ipnum[ip] += 1
        ipflow[ip] = int(ipflow[ip]) + int(flow)
    else:
        ipnum[ip] = 1
        ipflow[ip] = int(flow)

#显示单个ip访问的次数和流量
for k in ipnum:
    print "访问IP:%s 访问次数:%d 访问流量:%.3fM" % (k,int(ipnum[k]),float(ipflow[k])/float(1000))

还有关于网络,框架,jvm内存机制,平衡二叉树等,改日再写吧。。。

 

 

posted @ 2016-01-31 02:07  alexander.bruce.lee  阅读(1103)  评论(2编辑  收藏  举报