《去哪儿》JAVA研发笔试+一面
背景不多说了,入正题,先说下笔试吧,研发岗位总共三道编程题,总的来说不是特别难,但要求要纸上写代码,所以写代码前先三思下,可以在试卷上写伪代码思路(答卷分开),后在答卷上写题,切记:一定别忘记注释。
笔试题:
一、部分有序旋转数组查找问题。
有一递增数组可向右移动,如:{1,2,3,4,5}向右移动后可为:{3,4,5,1,2},现在类似的数组中想找一个固定值,若存在则返回对应下标,若不存在则返回-1。需要考虑算法效率。
题解:很容易的就想到二分查找,是不是?但问题来了:数组有可能是由两部分递增的数组组成的,这样子就不能用二分查找法了。等等,这两部分有特别发现了没?数组第一个元素和最后一个比较,如果第一个比最后一个大,那么数组就是旋转了,此时很容易就想到先将原数组分割成两个递增数组再分别二分查找。
public int indexInTurnedArray(int[] array, int index) {// find out where the target int is int tmp = -1; if(null == array || 0 == array.length) {//error input tmp = -1; } else{ int bound = findArrayBound(array);//get the boundary of the array, which means the bigest one in array if(index == array[bound]) {//the target int is the boundary tmp = bound + 1; } else { //the target int should in the left side of the boundary, or the right side //anyside should return the index of the array, else return -1 //so, if none exist in both sides, the result will be -1 //if the target is match to the first one of the array, the 0 should be the reslut tmp = 1 + binarySearch(array, 0, bound - 1, index) + binarySearch(array, bound + 1, array.length -1, index); } } return tmp; } /** * find the bigest element in the turned-array * @param array * @return */ public int findArrayBound(int[] array) { if(array[0] < array[array.length - 1]) {//the array is a sequnced array, small to big... return array.length - 1; } else { int tmp = 0; //begin is used for index the last one in the bigger side //end is the first one in the smaller side int begin = 0, end = array.length - 1; while(begin < end) {//when the begin = end ,the circle will exist, means find the boundary if(1 == end - begin) {//found the boundary tmp = end - 1; break; } tmp = (begin + end) / 2; if(array[tmp] >= array[begin]) {//the middle one is bigger than begin begin = tmp; } else if(array[tmp] <= array[end]) {//the middle one is small than end end = tmp; } } return tmp; } } public int binarySearch(int[] array, int begin, int end, int index) {//binary research function if(begin == end) { return index == array[begin] ? begin : -1; } else { int middle = (begin + end) / 2; if(index == array[middle]) { return middle; } else if(index < array[middle]){ return binarySearch(array, begin, middle - 1, index); } else { return binarySearch(array, middle + 1, end, index); } } }
二、字符串解释
对输入的字符串,如:a2b3c4解密,解密结果应该为aabbbcccc。
题解:比较简单的一题字符操作,考查ASCII码运用及,字符串的相关知识。
string stringDecode(tring s) { char* c = const_cast<char*>(s.c_str());//将输入字符串强制转换成字符 String tmp; while (*c != '\0') { char a = 0; int j = -1; if ((*c>='A' && *c <= 'Z') || (*c >= 'a'&&*c<='z'))//判定是否是字母 { a = *c; c++; } if (*c != '\0' && *c >= '0' && *c <= '9')//判定是否是数字 { while (*c != '\0' && *c >= '0' && *c <= '9')//将所有数字转换成int { if (-1 == j) { j = (int)*c-48; } else { j = j * 10 + ((int)*c-48); } c++; } } if (a != 0)//若第一个是字母,则输出 { if (-1 == j) { tmp += a; } else { for (int i = 0; i < j; i++) { tmp += a;//迭加之前的字母个数 } } } } return tmp; }
三、多维数组操作
有一酒店某段时间内价格是由三元组确定的,如:第一天至第30天的价格是300元,则三元组为:[1,30,300]。后来出现的三元组的价格可以覆盖之前三元组的价格,如再出现[20, 50, 100]则其价格为:[1,19, 300], [20, 50, 100]。
题解:题目即为输入是二维数组,每行第一个元素是起始日期,第二个元素是截至日期,第三个元素为此段时间内价格。我很容易的想到了上万数乱序查找哪个数不存在的问题,即:建立一个较目标大点的一维数组(此处大小为366,一年不超过366天),若输入的三元组中规定了日期的价格,则分别将对应下标的数组中的值改为价格,后来再有重复的话将之前的价格覆盖即可。最后在遍历数组,找出非0的部分,值相同的一段将起始下标、终止下标、价格作为新的三元组输出。
1 public void hotelPrice(int[][] array) { 2 int beginDay = 365, endDay = 0; //store the begin and end day of the input 3 int[] price = new int[366]; //the price must in a year 4 int tmp = 0; 5 for(int i = 0; i < array.length; i++) { //the 3-element-array number 6 if(beginDay > array[i][0]) { //price begin day 7 beginDay = array[i][0]; 8 } 9 if(endDay < array[i][1]) { //price end day 10 endDay = array[i][1]; 11 } 12 tmp = array[i][0]; 13 while(tmp <= array[i][1]) { 14 price[tmp++] = array[i][2]; //pice 15 } 16 } 17 int i = beginDay; 18 while(i <= endDay) {//print result 19 if(0 == price[i]) { 20 i++; 21 continue; 22 } else { 23 int begin = i; 24 int tmpV = price[i]; 25 while(i < 366 && price[++i] == tmpV) {//find the same price day 26 continue; 27 } 28 int end = i - 1; 29 System.out.println("[" + begin + " , " + end + " , " + tmpV + "]");//print 30 } 31 } 32 }
面试:
主要问了些关于简历和笔试中的细节问题。
一、由于之前我在锐捷实习过4个月,问了些关于锐捷实习过程中我做的一个用robotframework搭建的自动化测试平台的东西,这部分聊的比较HIGH,和面试官聊了半天算是科普了许多无线方面的知识吧,还说了一些我在项目中遇到的问题和相应的解决思路和过程。
二、socket和http的区别。
http是超文本传输协议,主要是用来在应用程序层面封装web数据的一个协议,封装完后再交由TCP封装,IP封装,最后由底层网络送出报文交付;
socket可以分为IP层的socket和TPC层的socket,其主要功能是为了方便程序员更好的调用协议栈完成相应工作,简单的说就是对协议栈封装提供一套API给开发者用。
故,一个是协议;另一个只是一系列的接口API。
三、什么是线程安全。
(从度娘搬运来的)线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其它线程不能进行访问直到该线程读取完。不会出现数据不一致或污染。线程不安全就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据。
四、Spring主要作用
(从CSDN上搬运过来,http://blog.csdn.net/dyllove98/article/details/8586312)
五、数据库外键
外键主要是用于两个或多个表关联时,关联的关键字即是外键。
由于当时问到锐捷项目后,问了许多python语言类的东西,本人实在太菜未系统学过,所以基本答的很乱,最后妥妥的跪了。欢迎大家来拍砖和补充。