A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© psuugdufnm 中级黑马   /  2016-4-11 13:08  /  2206 人查看  /  37 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

昨天有个HR跟我说,有三道题,都做出来就给安排面试,但本宝宝表示不会,求大神解答。
第一题:给定一个数组,里面是一些数字,请只用一个for循环,找出其中第二大的数字。
所谓第二大的数字是:相当于这个数组逆序排序后,取下标为1的那个数字。
要求:只用1个for循环,配合if/else判断。不要对数组排序。
例如:对于数组 [2, 5, 1, 3, 2], 输出:3

第二题:2、现在有如下通信协议,请实现相关函数模块。
此协议是一个二进制协议,每个协议报文由如下数据流构成,数值都以Big-endian大端方式存储:
    { TotalSize[2], Crc32[4], Ver[1], Cmd[1], Data[len] }
方括号中是占用的字节数。具体解释:
    TotalSize: 2字节,表示整个报文的长度,这个值应该等于: 2 + 4 + 1 + 1 + len
    Crc32: 4字节,表示对 {Ver, Cmd, Data} 内容的 crc32 的校验值
    Ver: 1字节,协议版本,目前约定为 0x05
    Cmd: 1字节,用户指定的操作命令,0x00 ~ 0xff
    Data: len个字节,具体的数据内容
要求:实现一个函数 pack(cmd, data, len)
输入:cmd: 用户指定的操作命令;  data: 用户指定的数据;  len: 数据长度
输出:打包好的协议报文

第三题:有两个函数,funcA 会输出 "A" , funcB 会输出 "B"
请启动两个线程,用线程同步的机制,实现如下效果:
严格按照顺序轮流输出 A B A B A B ...

37 个回复

倒序浏览
我滴乖  ,这是啥面试
回复 使用道具 举报
木子小四 发表于 2016-4-11 14:10
我滴乖  ,这是啥面试

android 的面试{:2_30:}
回复 使用道具 举报
本帖最后由 z332406259 于 2016-4-13 00:39 编辑

package com.lzm;

/**
*
* 第一题:给定一个数组,里面是一些数字,请只用一个for循环,找出其中第二大的数字。
* 所谓第二大的数字是:相当于这个数组逆序排序后,取下标为1的那个数字。
* 要求:只用1个for循环,配合if/else判断。不要对数组排序。
*  例如:对于数组 [2, 5, 1, 3, 2], 输出:3
*
*/
public class NO_2 {
        public static void main(String[] args) {
                int[] arr = { 6,6,5,4,3 };         // 定义数组
                int first = arr[0];                         // 将数组第一个数字标记为NO1大的数字
                int second = arr[1];                 // 将数组第二个数字标记为NO2大的数字
                if (first < second) {                 // 如果NO1大的数字>NO2的数字,就交换它们的位置
                        int temp = first;
                        first = second;
                        second = temp;
                }
                for (int i = 2; i < arr.length; i++) {                 // 对数组遍历从第三个开始
                        if (first == second) {                         // 如果NO1数字和NO2数字相等,就判断数组遍历的数字和NO1的大小.
                                if (first < arr[ i ]) {                        // 遍历的数字若比NO1大,则把遍历的数字赋值给NO1,否则赋值给NO2.
                                        first = arr[ i ];
                                } else {
                                        second = arr[ i ];
                                }
                        } else {                                                         // 如果NO1和NO2不相等,则比较遍历的数字和NO1的大小.
                                if (first < arr[ i ]) {                 // 若该数字比NO1大,就将NO1赋值给NO2,该数字赋值给NO1.
                                        second = first;
                                        first = arr[ i ];
                                } else if (first > arr[ i ]) {         // 若该数字比NO1小,就比较该数字和NO2的大小.
                                        if (second < arr[ i ]) {         // 若该数字比NO2大,就将该数字赋值给NO2.
                                                second = arr[ i ];
                                        }
                                }
                        }
                }
                System.out.println(second);                 // 输出NO2
        }
}

回复 使用道具 举报 1 0
z332406259 发表于 2016-4-11 17:11
package com.heima.lzm33;

/**

给力!!谢谢。
回复 使用道具 举报
本帖最后由 z332406259 于 2016-4-11 18:29 编辑

package com.heima.lzm33;

public class Test_3 {

        /**
         * 第三题:有两个函数,funcA 会输出 "A" , funcB 会输出 "B" 请启动两个线程,用线程同步的机制,实现如下效果:
         * 严格按照顺序轮流输出 A B A B A B ...
         */
        public static void main(String[] args) {
                final Hello h = new Hello();                                        //创建Hello对象

                new Thread() {                                                                                //匿名线程1
                        public void run() {
                                while (true) {                                                                //不停调用funcA()方法输出A
                                        try {                                                                                        //异常判断
                                                h.funcA();
                                        } catch (InterruptedException e1) {
                                                e1.printStackTrace();
                                        }
                                }
                        }
                }.start();                                                                                                        //线程开启

                new Thread() {                                               //匿名线程2
                        public void run() {
                                while (true) {                                                                //不停调用funcB()方法输出B
                                        try {                                                                                        //异常判断
                                                h.funcB();
                                        } catch (InterruptedException e1) {
                                                e1.printStackTrace();
                                        }
                                }
                        }
                }.start();                                                                                                        //线程开启
        }
}

class Hello {
        private int flag = 1;                                                                        //标记 默认为1

        public void funcA() throws InterruptedException {
                synchronized (this) {   //锁对象this                                                               
                        if (flag != 1) {                                                                        //当标记不为1时,该线程1等待
                                this.wait();
                        }
                        System.out.println("A");
                        flag = 2;                                                                                        //标记赋值为2
                        this.notify();                                                                                //唤醒线程2(其他线程)
                }
        }

        public void funcB() throws InterruptedException {
                synchronized (this) {   //锁对象this  
                        if (flag != 2) {                                                                        //当标记不为2时,该线程2等待
                                this.wait();
                        }
                        System.out.println("B");
                        flag = 1;                                                                                        //标记赋值为2
                        this.notify();                                                                                //唤醒线程1(其他线程)
                }
        }
}
回复 使用道具 举报
等待进城唤醒机制.由于控制台不能横着输出A B A B A B.....我就换成
A
B
A
B
A
B
.
.
.

回复 使用道具 举报
本帖最后由 z332406259 于 2016-4-11 18:54 编辑

根据楼上改了一下.JDK1.5的新特性,互斥锁,个人感觉没什么区别.就是锁对象的问题.
package com.heima.lzm33;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class Test_3 {

        /**
         * 第三题:有两个函数,funcA 会输出 "A" , funcB 会输出 "B" 请启动两个线程,用线程同步的机制,实现如下效果:
         * 严格按照顺序轮流输出 A B A B A B ...
         */
        public static void main(String[] args) {
                final Hello h = new Hello(); // 创建Hello对象

                new Thread() { // 匿名线程1
                        public void run() {
                                while (true) { // 不停调用funcA()方法输出A
                                        try { // 异常判断
                                                h.funcA();
                                        } catch (InterruptedException e1) {
                                                e1.printStackTrace();
                                        }
                                }
                        }
                }.start(); // 线程开启

                new Thread() { // 匿名线程2
                        public void run() {
                                while (true) { // 不停调用funcB()方法输出B
                                        try { // 异常判断
                                                h.funcB();
                                        } catch (InterruptedException e1) {
                                                e1.printStackTrace();
                                        }
                                }
                        }
                }.start(); // 线程开启
        }
}

class Hello {
        private int flag = 1;                                                                                                // 标记 默认为1
        private ReentrantLock r = new ReentrantLock();        //互斥锁
        private Condition c1 = r.newCondition();                               
        private Condition c2 = r.newCondition();

        public void funcA() throws InterruptedException {
                r.lock();                        //获取锁
                if (flag != 1) { // 当标记不为1时,该线程1等待
                        c1.await();                        //c1等待
                }
                System.out.println("A");
                flag = 2; // 标记赋值为2
                c2.signal();                //唤醒c2线程
                r.unlock();                        //释放锁
        }

        public void funcB() throws InterruptedException {
                r.lock();                        //获取锁
                if (flag != 2) { // 当标记不为1时,该线程1等待
                        c2.await();                //c2等待
                }
                System.out.println("B");
                flag = 1; // 标记赋值为2
                c1.signal();                //唤醒c1线程
                r.unlock();                        //释放锁
        }
}

回复 使用道具 举报
第三个题直接用互斥锁,
回复 使用道具 举报
第一题不是只用一个for/if吗?
回复 使用道具 举报
不明觉厉   楼主加油
回复 使用道具 举报
只会第一题
class Test_002 {
        public static void main(String[] args) {
                int [] arr = {2, 2, 3, 43, 32, 8, 23, 35};
                int first = arr[0];
                int second = arr[1];
                if (first<second) {
                        int temp = second;
                        second = first;
                        first= temp;      //获取max和max2
                }
                for (int i = 2;i<arr.length ;i++ ) {  //数组第三个开始遍历比较
                        if (first<=arr[i]) {        //比max还大的  
                                second = first;   // 先把max记录给 max2
                                first = arr[i];      // 再把遍历出的最大赋给max
                    }else if (arr[i]>second) {  //如果遍历出来都比max小
                                 second = arr[i];  // 那就只需要和max2 比较即可
                         }       
                }
                System.out.println(second);       
        }
}
回复 使用道具 举报
感觉好难啊
回复 使用道具 举报
本帖最后由 z332406259 于 2016-4-12 00:24 编辑

package com.heima.lzm33;

import java.util.zip.CRC32;

public class Test_4 {

        /**
         * 第二题:2、现在有如下通信协议,请实现相关函数模块。
         * 此协议是一个二进制协议,每个协议报文由如下数据流构成,数值都以Big-endian大端方式存储:
         * { TotalSize[2],Crc32[4], Ver[1], Cmd[1], Data[len] } 方括号中是占用的字节数。具体解释:
         * TotalSize:2字节,表示整个报文的长度,这个值应该等于: 2 + 4 + 1 + 1 + len
         * Crc32: 4字节,表示对 {Ver, Cmd,Data} 内容的 crc32 的校验值
         * Ver: 1字节,协议版本,目前约定为 0x05
         * Cmd: 1字节,用户指定的操作命令,0x00 ~0xff
         * Data: len个字节,具体的数据内容
         * 要求:实现一个函数 pack(cmd, data, len) 输入:cmd:
         * 用户指定的操作命令; data: 用户指定的数据; len: 数据长度 输出:打包好的协议报文
         */
        public static void main(String[] args) {
                pack(0x0A, "35566",5 );
                //报文打包方法(这边也可以不自己输入数值,设置键盘录入)
        }

        public static void pack(int cmd, String data, int len) {//方法:参数:int String int(用键盘录入可以全定义为String,然后转换)
                CRC32 crc32 = new CRC32();                                    //建立CRC32对象
                short TotalSize = (short) (2 + 4 + 1 + 1 + len);//定义变量TotalSize
                byte Ver = 0x05;                                                   //定义Ver
                byte Cmd = (byte) cmd;                                          //定义Cmd
                byte[] Data = new byte[len];                                 //建立字节数组来接收数据,因为数据是一个一个接收的.
                Data = data.getBytes();                                        //将字符串转换为字节数组
                byte[] b = new byte[len + 2];                               //新建一个比数据长度+2的字节数组
                for (int i = 0; i < Data.length - 1; i++) {              //遍历该数组将数据数组放入新数组中
                        b = Data;
                }
                b[len - 1] = Ver;                                             //将Ver和Cmd也放入新数组中
                b[len - 2] = Cmd;

                crc32.update(b);                                           //调用CRC32的方法传入字节数组更新校检值
                int Crc32 = (int) crc32.getValue();                 //取出校检值赋给Crc32
                System.out.print("{" + Integer.toHexString(TotalSize) + ","+ Integer.toHexString(Crc32) + ","
                + Integer.toHexString(Ver)+ "," + Integer.toHexString(Cmd) + ",");
               //输出{ TotalSize[2],Crc32[4], Ver[1], Cmd[1], Data[len] } 的十六进制表示
               //因为Big-endian大端方式是低地址存储最高有效字节,和正常习惯一样,直接打印十六进制.
                for (byte c : Data) {
                        System.out.print(Integer.toHexString(c));
                }
                System.out.println("}");
        }
}

回复 使用道具 举报
本帖最后由 z332406259 于 2016-4-12 00:12 编辑
Yoyoqiu 发表于 2016-4-11 21:05
只会第一题
class Test_002 {
        public static void main(String[] args) {

赞一个.你的程序还是有bug的,当第一个数字和第二个数字都是一样的并且接下来的数字全部小于这2个数字,最后会输出最大的数字的.
回复 使用道具 举报
本帖最后由 z332406259 于 2016-4-12 00:11 编辑

12楼的程序还是存在问题,我看看程序能不能再优化一下.
回复 使用道具 举报
多看看多学,没准自己以后会用到.谢谢分享
回复 使用道具 举报
感觉有点难
回复 使用道具 举报
才学到数组,第一题还是有点意思的,学到了
回复 使用道具 举报
只会写第一题 看看这样写可以不        public static void main(String[] args) {
                //定义数组
                int[] arr = {40,12,23,35,45,60,45,15,76};
                //定义变量max记住数组中最大数字为arr[0];
                int max = arr[0];
                //定义变量max2记住数组中第二大的数字为arr[1];
                int max2 = arr[1];
               
                //如果max2 大于max,就进行交换
                if(max<max2) {
                        int temp = max;
                        max = max2;
                        max2 = temp;
                }
               
                //从第三个元素开始遍历
                for (int i = 2; i < arr.length; i++) {
               
                        //用最大的数字max与遍历出的其他元素arr[i]一一比较,如果max <arr[i],
                        //就把arr[i]赋值给max,得出最大值;然后把原来max的值赋值给max2;
                        if (max < arr[i]) {     
                                max2= max;
                                max = arr[i];
                        //再用赋值后的max2与数组中除了最大元素进行比较,如果max小于其他元素arr[i],就把arr[i]赋值给max2;       
                        }else if(max2 < arr[i]){
                                max2 = arr[i];
                        }
                }
                //输出第二大的值
                System.out.println(max2);
        }

}
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马