常见的编程题
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(); } }