2015年面试的总结

最近几天正在忙于各处奔走,参加各个邀约的公司的面试。在面试的过程中,发现了自己在之前的工作中有很多的不足,在这里做一个小总结。另外,不论这些公司最后是否要我,我要对这几天面试我的同行和 HR 们表示感谢,他们当中有的人我还不知道姓名,和他们的交流中,我也收获了许多,在此衷心表示感谢。

这一周的面试是一件很辛苦,但是又很有收获的一周。与日常工作的开发不一样,我会见到很多人,接触、了解到他们对于职业生涯,软件开发的想法和建议。对于我自己选择公司、职位来说都是很有帮助的。而且通过面试的这一周,我也反思、总结了很多。

这里也写一些对自己的提醒:

(1)一定要准时,即使对方也不在乎你是不是准时到。因为刚去的时候可能是填表,虽然差个一两分钟,甚至五六分钟都无所谓,但这样毕竟不好,也会滋长自己的堕性和懒散的意识,所以比较好的办法就是把手表的时间提前;

(2)看面试的情况要一个对方的电话,咨询面试结果。这一条虽然我写在这里,但我想其实除非面试的过程非常愉快,否则要电话可能面试官会比较反感;

 

1、写一个线程安全的单例;

以下是基于内部类的一个单例类的写法:

package com.liwei.danli;

public class Singleton {
    private Singleton() {
    }

    private static class SingletonHolder {
        private final static Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }

    public static void main(String[] args) {
        Singleton instance1 = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance1.hashCode());
        System.out.println(instance2.hashCode());
    }
}

 

2、说说 Object 的 hashCode() 方法和 equals() 方法:

这个问题原文引用下面这篇文章的解答:

Java面试题全集(上) - 骆昊的技术专栏 - 博客频道 - CSDN.NET
http://blog.csdn.net/jackfrued/article/details/44921941

两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?
答:不对。事实上,如果两个对象x和y满足x.equals(y) == true,它们的哈希码(hash code)应当相同。

Java 对于 eqauls() 方法和 hashCode() 方法是这样规定的:

(1)如果两个对象相同( equals() 方法返回 true ),那么它们的 hashCode 值一定要相同;

(2)如果两个对象的 hashCode 相同,它们并不一定相同。

当然,你未必要按照要求去做,但是如果你违背了上述原则就会发现在使用容器时,相同的对象可以出现在 Set 集合中,同时增加新元素的效率会大大下降(对于使用哈希存储的系统,如果哈希码频繁的冲突将会造成存取性能急剧下降)。

笔者:我对这段话的理解,在使用集合存储对象的时候,就会出现问题。因为 hash 算法认为 ,进来一个对象,先通过 hashCode 计算它应该在哪一个位置上,如果这个位置上没有对象,就把这个对象放在这个位置上,如果这个位置上有对象,就通过 equals() 方法去比较,如果为 true ,就不放入这个对象,如果为 false 就放入这个对象,在该位置上形成一个链表结构。(个人理解,正确性有待检验)。

补充:关于 equals() 和 hashCode() 方法,很多 Java 程序员都知道,但很多人也就是仅仅知道而已,在 Joshua Bloch 的大作《Effective Java》(很多软件公司,《Effective Java》、《Java编程思想》以及《重构:改善既有代码质量》是 Java 程序员必看书籍,如果你还没看过,那就赶紧去亚马逊买一本吧)中是这样介绍 equals() 方法的:

首先 equals() 方法必须满足自反性( x.equals(x) 必须返回 true )、对称性( x.equals(y) 返回 true 时, y.equals(x) 也必须返回 true )、传递性( x.equals(y) 和 y.equals(z) 都返回 true 时, x.equals(z) 也必须返回 true )和一致性(当 x 和 y 引用的对象信息没有被修改时,多次调用 x.equals(y) 应该得到同样的返回值),而且对于任何非null值的引用x, x.equals(null) 必须返回 false 。

实现高质量的 equals() 方法的诀窍包括:

1、使用 == 操作符检查"参数是否为这个对象的引用";

2、使用instanceof操作符检查"参数是否为正确的类型";

3、对于类中的关键属性,检查参数传入对象的属性是否与之相匹配;

4、编写完equals方法后,问自己它是否满足对称性、传递性、一致性;

5、重写 equals() 方法时总是要重写 hashCode() 方法;

6、不要将equals方法参数中的Object对象替换为其他的类型,在重写时不要忘掉 @Override 注解。

 

3、写一段代码,对自定义的对象实现 List 的排序功能。

思路:使用 Collections 工具类的方法 sort() 方法来完成。我们可以查看 Java 的 API 文档。

Collections工具类的sort方法有两种重载的形式,第一种要求传入的待排序容器中存放的对象比较实现Comparable接口以实现元素的比较;第二种不强制性的要求容器中的元素必须可比较,但是要求传入第二个参数,参数是Comparator接口的子类型(需要重写compare方法实现元素的比较),相当于一个临时定义的排序规则,其实就是通过接口注入比较元素大小的算法,也是对回调模式的应用(Java中对函数式编程的支持)。 

 

我暂时忘记了面试的问题是什么了,直接上代码:

先是一个实体类 Student :

package com.liwei.list;

public class Student {
    private String name; // 姓名
    private int age; // 年龄

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Student(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student [name=" + name + ", age=" + age + "]";
    }

}

然后是我们的测试代码:

package com.liwei.list;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        List<Student> list = new ArrayList<>(); // Java 7 的钻石语法(构造器后面的尖括号中不需要写类型)
        list.add(new Student("Hao LUO", 33));
        list.add(new Student("XJ WANG", 32));
        list.add(new Student("Bruce LEE", 60));
        list.add(new Student("Bob YANG", 22));
        Collections.sort(list, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                // return o1.getAge() - o2.getAge();// 按照年龄升序排序
                // 按照 name 字段升序排序 ( SUN 公司已经帮我们实现了 String 的比较方法)
                return o1.getName().compareTo(o2.getName()); 
            }
        });
        for(Student s:list){
            System.out.println(s.getName());
        }
        
    }
}

4、写一个函数将一个字符串转换为数值。

我回来之后总结了两种方法,分别如下:

遍历字符串的每个字符

(1)使用正则表达式进行判断;(2)利用字符 0- 9 的 ASCII 码是连续的特点。

package com.liwei.mainshi;

public class Test01 {
    
    public static void main(String[] args) {
        int num1 = transform1("687124a456ssdffs90");
        System.out.println(num1);
        System.out.println("------愉快的分割线------");
        int num2 = transform2("687124a456ssdffs90");
        System.out.println(num2);
    }
    
    public static int transform1(String str) {
        String return_str = "";
        for (int i = 0; i < str.length(); i++) {
            String temp = str.substring(i, i + 1);
            // char char_str = str.charAt(i);
            // System.out.println(char_str);
            if (temp.matches("\\d")) {
                return_str += temp;
            }else{
                break;
            }
        }
        return return_str == "" ? 0: Integer.valueOf(return_str);
    }
    
    
    public static int transform2(String str){
        int result_num = 0;
        for (int i = 0; i < str.length(); i++) {
            char charAt = str.charAt(i);
            int diff =  charAt - '0';
            if(diff>9){
                break;
            }
            result_num = result_num*10 +diff;
        }
        return result_num;
    }
}

知识点复习:

(1)如何得到一个字符的 ASCII 码?

方法一:转化为 byte 类型,再打印:

  @Test
    public void test04(){
        char c = 'A';
        byte b = (byte) c;
        System.out.println(b); // 65
    }

方法二:直接使用 int 类型赋值给单个的字符变量:

    @Test
    public void test04(){
        char c = 'A';
        byte b = (byte) c;
        System.out.println(b); // 65
        
        // 愉快的分割线
        
        int a = 'A';
        System.out.println(a); // 65
    }

 

5、请简单介绍 Java 中的定时器:

可以参考下面的文章进行准备:

java中的几种定时器 - 小崔的博客 - 博客频道 - CSDN.NET
http://blog.csdn.net/cuiran/article/details/5929833

Java Timer 定时器的使用_张一角_新浪博客
http://blog.sina.com.cn/s/blog_5e8782250100l20s.html

 

 

 

6、简单介绍一下 Memcached 。

这里可以参考下面的这篇文章:

memcached简介及java使用方法 - seelye的专栏 - 博客频道 - CSDN.NET
http://blog.csdn.net/seelye/article/details/8511073

 

关于多线程,可以参考下面的文章。

Java多线程面试题归纳 - 曹海成的专栏 - 博客频道 - CSDN.NET
http://blog.csdn.net/caohaicheng/article/details/38071097

 

 

 

SpringMVC的每个方法都是线程安全的吗?

什么是中间件?这些概念我听都没有听说过。

http 协议和 https 协议有什么不同。

MySQL 的索引类型

MySQL 的约束类型

 

对于自己的职业生涯要有一个明确的定位,不能太模糊;

学习自己工作中用到的;

 

posted @ 2015-04-28 08:03  李威威  阅读(151)  评论(0编辑  收藏  举报