常见的编程题

1、给定一个正整数n,怎么用一到两行代码判断n是否是2的某个次方的值

return (n & (n-1)) == 0 ? true : false;

2、Comparator 和 Comparable

1、利用Comparator 接口,重写compare()方法
    Person[] arr = new Person[5];
        arr[0] = new Person("张三", 23);
        arr[1] = new Person("李四", 24);
        arr[2] = new Person("王五", 13);
        arr[3] = new Person("赵六", 24);
        arr[4] = new Person("孙七", 13);
        System.out.println(Arrays.toString(arr));;        // 将数组转换成字符串后输出

        Arrays.sort(arr, new Comparator<Person>(){        // 先按年龄排序,如果年龄相同,按姓名排序
            public int compare(Person p1, Person p2){
                int num = p1.getAge() - p2.getAge();
                if(num != 0){
                    return num;
                }else{
                    return p1.getName().compareTo(p2.getName());
                }
            }
        });
        System.out.println(Arrays.toString(arr));    // 排序后的字符串输出
[Person{name='张三', age=23}, Person{name='李四', age=24}, Person{name='王五', age=13}, Person{name='赵六', age=24}, Person{name='孙七', age=13}]
[Person{name='孙七', age=13}, Person{name='王五', age=13}, Person{name='张三', age=23}, Person{name='李四', age=24}, Person{name='赵六', age=24}]
2、利用Comparable 接口,重写比较元素的CompareTo()方法
     Person[] arr = new Person[5];
        arr[0] = new Person("张三", 23);
        arr[1] = new Person("李四", 24);
        arr[2] = new Person("王五", 13);
        arr[3] = new Person("赵六", 24);
        arr[4] = new Person("孙七", 13);
        System.out.println(Arrays.toString(arr));;

        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));
Person 类必须是实现 Comparable接口且实现compareTo()方法
class Person implements Comparable<Person>{
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }


   public int compareTo(Person p){  // 先比较年龄,然后比较姓名
        int num = this.age - p.getAge();
        if(num != 0){
            return num;
        }else{
            return this.getName().compareTo(p.getName());
        }
   }
}
输出和第一种方式一样
[Person{name='张三', age=23}, Person{name='李四', age=24}, Person{name='王五', age=13}, Person{name='赵六', age=24}, Person{name='孙七', age=13}]
[Person{name='孙七', age=13}, Person{name='王五', age=13}, Person{name='张三', age=23}, Person{name='李四', age=24}, Person{name='赵六', age=24}]

3、利用泛型实现一个数组的最小值函数

    // 实参必须是Number的子类,且实参或者实参的父类必须实现了 Comparable接口
    private static <T extends Number & Comparable<T>> T min(T[] values){
        if(values == null || values.length == 0){
            return null;
        }
        T min = values[0];
        for(int i = 1; i < values.length; i++){
            if(min.compareTo(values[i]) > 0){
                min = values[i];
            }
        }
        return min;
    }

4、两个线程交替打印奇偶数,通过wait/notify实现

public class WaitNotify {
  // 状态锁
  private static Object lock = new Object();
  private static Integer i = 0;

  public void odd() {
    while (i < 10) {
      synchronized (lock) {
        if (i % 2 == 1) {
          System.out.println(Thread.currentThread().getName() + " - " + i);
          try {
            Thread.sleep(1000);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
          i++;
          lock.notify();
        } else {
          try {
            lock.wait();
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
      }
    }
  }

  public void even() {
    while (i < 10) {
      synchronized (lock) {
        if (i % 2 == 0) {
          System.out.println(Thread.currentThread().getName() + " - " + i);
          try {
            Thread.sleep(1000);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
          i++;
          lock.notify();
        } else {
          try {
            lock.wait();
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
      }
    }
  }

  public static void main(String[] args) {

    WaitNotify waitNotify = new WaitNotify();

    Thread t1 = new Thread(() -> waitNotify.odd(), "线程1");
    Thread t2 = new Thread(() -> waitNotify.even(), "线程2");

    t1.start();
    t2.start();
  }
}

5、CountDownLatch可以代替wait/notify的使用,并去掉synchronized,下面重写上面的那个例子:

import java.util.concurrent.CountDownLatch;

public class CountDown {
  private static Integer i = 0;
  final static CountDownLatch countDown = new CountDownLatch(1);

  public void odd() {
    while (i < 10) {
      if (i % 2 == 1) {
        System.out.println(Thread.currentThread().getName() + " - " + i);
        try {
          Thread.sleep(1000);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        i++;
        countDown.countDown();
      } else {
        try {
          countDown.await();
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }
  }

  public void even() {
    while (i < 10) {
      if (i % 2 == 0) {
        System.out.println(Thread.currentThread().getName() + " - " + i);
        try {
          Thread.sleep(1000);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        i++;
        countDown.countDown();
      } else {
        try {
          countDown.await();
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }
  }

  public static void main(String[] args) {

    CountDown countDown = new CountDown();

    Thread t1 = new Thread(() -> countDown.odd(), "线程1");
    Thread t2 = new Thread(() -> countDown.even(), "线程2");

    t1.start();
    t2.start();
  }
}

 

posted @ 2020-12-19 20:27  Lucky小黄人^_^  阅读(621)  评论(0编辑  收藏  举报