人人网2017暑假实习生招聘-一面

本文分享了一次具体的在线面试经历,包括字符串比较、SQL操作及集合类相关问题的解答过程与反思,强调了对API熟悉度的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  上周面试结束以后接到通知,今天中午11点开始面试,早上没有去上课在等着,11点10分面试官才面试完上个人开始面试。
  自我介绍完了之后,说我说的太简单了,然后让说了说我做了什么项目,自己语无伦次的,估计印象分十分不好。然后就让做题了。

字符串

  写一个函数,输入两个字符串分别代表版本1和版本2,输出比较的结果

输入版本号version1和version2,如1.0.0和1.0.1,版本1小于版本2,输出-1
测试用例
1.0.0 1.0.1 -1
1.0.1 1.0.0 1
1.0.0 1.0.0 0

思路

  开始毫无思路,然后想了两分钟才想出来,因为对String不够熟悉,所以问面试官有没有分割函数,面试官说有split,然后参数是一个字符串,返回一个String[]的数组,于是就开始写代码。思路是用“.”分割字符串,分割后的字符串数组依次比较,两个字符串数组,选取长度小的那个数组的长度作为num,然后写一个循环,从0到num,依次比较字符串数组中每个字符串数组的大小,如果strs1[i] < strs2[i],那么返回-1,如果大于,那么返回1,如果都相等,那么就需要根据字符串的长度判断了,比如1.0小于1.0.1,判断前两个数相等之后,for循环结束,判断长度即可。
  当时想不起来字符串的比较,问了面试官,面试官说有,然后我写成了compare,而不是compareTo,写完之后面试官说可以让我看一下自己的IDE,然后看了源码发现是compareTo,而且返回值不是-1或者1或者0,而是不同的那一个字符的ASCII码的差或者两个字符串长度的差。

代码

  写完之后如下:

public int compare(String version1, String version2) {
    // 这里省略输入合法性判断
    // 分割字符串
    String[] strs1 = version1.split(".");
    String[] strs2 = version2.split(".");
    int num1 = strs1.length;
    int num2 = strs2.length;
    // 找出短的字符串数组的长度
    int num = num1 < num2 ? num1 : num2;
    for (int i = 0 ; i < num ; i++) {
        if (strs1[i].compareTo(strs2[i]) < 0) {
            return -1;
        } else if (strs1[i].compareTo(strs2[i]) > 0) {
            return 1;
        }
    }
    // 如果0到num之间的字符都相等那么根据长度进行判断
    if (num1 < num2) {
        return -1;
    } else if (num1 > num2) {
        return 1;
    }
    return 0;
}

  运行发现有错误,提示String[]这里有错,我以为是String数组不能这么声明,然后面试官说程序就到这里吧,而且你这个改过来以后还是有很多问题的。特别挫败的感觉,然后进行了下一题。
  面试完了之后立马再写了一遍,发现分割过后字符串数组大小为0,查了查split的用法,发现如果是“|”或者“.”这种特殊字符,需要用“\\.”进行转义才行,修改之后如下:

public int compare(String version1, String version2) {
    // 这里省略输入合法性判断
    // 分割字符串
    String[] strs1 = version1.split("\\.");
    String[] strs2 = version2.split("\\.");
    int num1 = strs1.length;
    int num2 = strs2.length;
    // 找出短的字符串数组的长度
    int num = num1 < num2 ? num1 : num2;
    for (int i = 0 ; i < num ; i++) {
        if (strs1[i].compareTo(strs2[i]) < 0) {
            return -1;
        } else if (strs1[i].compareTo(strs2[i]) > 0) {
            return 1;
        }
    }
    // 如果0到num之间的字符都相等那么根据长度进行判断
    if (num1 < num2) {
        return -1;
    } else if (num1 > num2) {
        return 1;
    }
    return 0;
}

  然后感觉面试官说代码问题很大,但是明明只有这一个问题。。。其实在面试过程中就想到了是不是用compareTo直接进行比较就行了,但是当时这个念头只是一闪而过,面试完以后发现,就是直接调用这个方法就行了!而且,我写的这个方法和String.compareTo()的思想一样。好坑。

public int compare(String version1, String version2) {
    if (version1.compareTo(version2) < 0) {
        return -1;
    } else if (version1.compareTo(version2) > 0) {
        return 1;
    } else {
        return 0;
    }
}

SQL语句

第一题

  题目大概意思如下:

  1. 创建一个表,主键id自增,列ip表示ip地址,ctime表示创建时间
  2. 插入一条数据
  3. 删除所有数据
  4. 查询出某个ip地址一共有多少条

  当时写的很烂,第一个忘了怎么写自增主键,其他三个没问题,面试完重新写一次如下:

1. create table if not exists ip_table(
    -> id int not null AUTO_INCREMENT,
    -> ip varchar(15) not null,
    -> ctime bigint(20) not null,
    -> Primary Key(id)
    -> );
2. insert into ip_table(ip,ctime) values('127.0.0.1',646541616516);
3. delete from ip_table;
4. select count(ip) from ip_table where ip = '127.0.0.1';
   # 面试时写成了 select count(*) from (select * from ip_table where ip='127.0.0.1');
   # 会提示错误 ERROR 1248 (42000): Every derived table must have its own alias
   # 需要给from指定一个名字才可以,下面是正确的写法
   # select count(*) from (select * from ip_table where ip='127.0.0.1') a;

第二题

在第一题的基础上,有个ip_addr表,属性为ip和对应的ip所在的地址addr,一个addr可能对应着许多ip
查出一个地址包含了多少个ip,即结果为addr,count(ip)

  由于网络原因,语音和视频卡顿,没有太听清楚要求,我写出了如下SQL语句:

select addr, count(ip) as nums from ip_addr group by addr;

  但是面试官是让联合两个表进行查询,面试官又说了一遍要求,可是我还是没有听清楚,然后告诉他网络不稳定,希望能重复一下,面试官说那这部分就这样结束吧。
  结束以后再次进去面试网页发现之前的东西还在,于是再次看了题目要求,如下:

统计上个表中出现的地理位置的个数

  当时由于紧张,加上听不清楚面试官的语音,没有理解什么意思,重新写的SQL语句如下:

select b.addr,count(a.ip) as ipnums  from ip_table a, ip_addr b where a.ip=b.ip group by a.ip;

HashMap和ConcurrentHashmap

  由于我之前说了平时都是用集合的,字符串数组几乎没有怎么用过,然后面试官让我说一下熟悉的集合类,然后说了有ArrayListLinkedListHashMapHashTableVector等,面试官就问了HashMapConcurrentHashmap的区别(当时心想,果然问了这个),我说主要是是否实现了线程安全的区别,然后问ConcurrentHashmap怎么实现的线程安全,我说在JDK1.7中把哈希表分成一个一个的Segment,每次进行操作的时候查找出要操作的元素在哪个Segment中,只对这个块进行加锁,这样效率比较高,在JDK1.8中,每个Segment中存的都是一个HashMap,具体源码看的太吃力没有看仔细。然后面试官就说今天面试到这里结束了,等以后通知。

总结

  相对于阿里的简单很多,但是用的牛客网的面试系统,让在线写代码,对面可以看到,但是没有API的提示,所以有些常用的在Eclipse中直接自动补全或者能查看源码的方法,很容易想不起来,所以第一题花费了大量的时间,就是因为不是特别熟悉String类的方法。
  SQL语句明白了自己的不足,对增删查改的语句很熟悉,但是对创表或者索引这些就一脸懵逼了,需要多加锻炼。
  再有就是HashMapConcurrentHashmap估计八成的面试官都会问吧,就算现在看不懂源码,还是要看一些别人的文章,明白原理是怎么样的。

  每一次面试都是对自己的一次考察,了解自己的不足,继续加油!
  


  2017年4月28日21:21:24 更新
  早挂了,是自己当时想当然了,API不熟悉,而且字符串那个自己写的确实有问题,ConcurrentHashmap说的也有问题(是CAS+synchronized实现的)。
  多学多练,继续努力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值