上周面试结束以后接到通知,今天中午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语句
第一题
题目大概意思如下:
- 创建一个表,主键id自增,列ip表示ip地址,ctime表示创建时间
- 插入一条数据
- 删除所有数据
- 查询出某个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
由于我之前说了平时都是用集合的,字符串数组几乎没有怎么用过,然后面试官让我说一下熟悉的集合类,然后说了有ArrayList
、LinkedList
、HashMap
、HashTable
、Vector
等,面试官就问了HashMap
和ConcurrentHashmap
的区别(当时心想,果然问了这个),我说主要是是否实现了线程安全的区别,然后问ConcurrentHashmap
怎么实现的线程安全,我说在JDK1.7
中把哈希表分成一个一个的Segment
,每次进行操作的时候查找出要操作的元素在哪个Segment
中,只对这个块进行加锁,这样效率比较高,在JDK1.8
中,每个Segment
中存的都是一个HashMap
,具体源码看的太吃力没有看仔细。然后面试官就说今天面试到这里结束了,等以后通知。
总结
相对于阿里的简单很多,但是用的牛客网的面试系统,让在线写代码,对面可以看到,但是没有API的提示,所以有些常用的在Eclipse中直接自动补全或者能查看源码的方法,很容易想不起来,所以第一题花费了大量的时间,就是因为不是特别熟悉String类的方法。
SQL语句明白了自己的不足,对增删查改的语句很熟悉,但是对创表或者索引这些就一脸懵逼了,需要多加锻炼。
再有就是HashMap
和ConcurrentHashmap
估计八成的面试官都会问吧,就算现在看不懂源码,还是要看一些别人的文章,明白原理是怎么样的。
每一次面试都是对自己的一次考察,了解自己的不足,继续加油!
2017年4月28日21:21:24 更新
早挂了,是自己当时想当然了,API不熟悉,而且字符串那个自己写的确实有问题,ConcurrentHashmap说的也有问题(是CAS+synchronized实现的)。
多学多练,继续努力。