《去哪儿》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语言类的东西,本人实在太菜未系统学过,所以基本答的很乱,最后妥妥的跪了。欢迎大家来拍砖和补充。

转载于:https://www.cnblogs.com/Qingfeng-0203/p/4409073.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值