0%

顺时针打印矩阵

题目链接

牛客网(opens new window)

题目描述

按顺时针的方向,从外到里打印矩阵的值。下图的矩阵打印结果为:1, 2, 3, 4, 8, 12, 16, 15, 14, 13, 9, 5, 6, 7, 11, 10

img

阅读全文 »

数组中重复的数字

题目链接

牛客网(opens new window)

题目描述

在一个长度为 n 的数组里的所有数字都在 0 到 n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字是重复的,也不知道每个数字重复几次。请找出数组中任意一个重复的数字。

1
2
3
4
5
Input:
{2, 3, 1, 0, 2, 5}

Output:
2
阅读全文 »

字符串相关

kmp算法

1、制作部分匹配值表:

如对于ABCDABD

搜索词为从左往右的每个字母,匹配值计算方法如下:

如对于第2个A,划到该字符的字符串为ABCDA,前缀为A、AB、ABC、ABCD,后缀为BCDA、CDA、DA、A,共有元素为A,字符串长度为1,所以部分匹配值即为1

2、使用字符串逐个匹配,若出现不同的清况下,向后跳n格(非1格),其中n=已匹配的字符数-最后一个匹配成功字符的部分匹配值

Java相关

引用拷贝、深拷贝、浅拷贝

  • 引用拷贝:不会生成新的对象,只会在原对象上增加了一个新的对象引用,两个引用指向的对象还是同一个

  • 浅拷贝:会生成新的对象,但是对象中的引用类型并不会重新生成(修改该类属性仍然会连环修改)

    • 实现方式:对象实现cloneable接口,在直接调用clone方法
  • 深拷贝:会生成新的对象,且对象中的引用类型也会重新生成对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    package JavaGuide;

    public class Teacher implements Cloneable{
    public int num;
    public Student s;

    @Override
    protected Object clone() throws CloneNotSupportedException {
    Teacher teacher = (Teacher) super.clone();
    teacher.s = (Student) this.s.clone();
    return teacher;
    }

    public static void main(String[] args) throws CloneNotSupportedException {
    Student stu = new Student();
    stu.num = 1111;
    Teacher t1 = new Teacher();
    t1.num = 1;
    t1.s = stu;

    // Teacher t2 = t1;
    Teacher t2 = (Teacher) t1.clone();
    t2.s.num = 2222;
    System.out.println(t1.s.num);
    }
    }

    class Student implements Cloneable{
    public int num;

    @Override
    public Object clone() throws CloneNotSupportedException {
    return super.clone();
    }
    }

JDK和JRE

  • JDK 是 Java Development Kit 缩写,它是功能齐全的 Java SDK。它拥有 JRE 所拥有的一切,还有编译器(javac)和工具(如 javadoc 和 jdb)。它能够创建和编译程序。

  • JRE 是 Java 运行时环境。它是运行已编译 Java 程序所需的所有内容的集合,包括 Java 虚拟机(JVM),Java 类库,java 命令和其他的一些基础构件。但是,它不能用于创建新程序。

  • 如果你只是为了运行一下 Java 程序的话,那么你只需要安装 JRE 就可以了。如果你需要进行一些 Java 编程方面的工作,那么你就需要安装 JDK 了。

有哪些集合是线程不安全的?怎么解决呢?

我们常用的 Arraylist ,LinkedList,Hashmap,HashSet,TreeSet,TreeMapPriorityQueue 都不是线程安全的。解决办法很简单,可以使用线程安全的集合来代替。

如果你要使用线程安全的集合的话, java.util.concurrent 包中提供了很多并发容器供你使用:

  1. ConcurrentHashMap: 可以看作是线程安全的 HashMap
  2. CopyOnWriteArrayList:可以看作是线程安全的 ArrayList,在读多写少的场合性能非常好,远远好于 Vector.
  3. ConcurrentLinkedQueue:高效的并发队列,使用链表实现。可以看做一个线程安全的 LinkedList,这是一个非阻塞队列。
  4. BlockingQueue: 这是一个接口,JDK 内部通过链表、数组等方式实现了这个接口。表示阻塞队列,非常适合用于作为数据共享的通道。
  5. ConcurrentSkipListMap :跳表的实现。这是一个Map,使用跳表的数据结构进行快速查找。

Arraylist 与 LinkedList 区别?

  1. 是否保证线程安全: ArrayListLinkedList 都是不同步的,也就是不保证线程安全;
  2. 底层数据结构: Arraylist 底层使用的是 Object 数组LinkedList 底层使用的是 双向链表 数据结构(JDK1.6 之前为循环链表,JDK1.7 取消了循环。注意双向链表和双向循环链表的区别,下面有介绍到!)
  3. 插入和删除是否受元素位置的影响:ArrayList 采用数组存储,所以插入和删除元素的时间复杂度受元素位置的影响。 比如:执行add(E e)方法的时候, ArrayList 会默认在将指定的元素追加到此列表的末尾,这种情况时间复杂度就是 O(1)。但是如果要在指定位置 i 插入和删除元素的话(add(int index, E element))时间复杂度就为 O(n-i)。因为在进行上述操作的时候集合中第 i 和第 i 个元素之后的(n-i)个元素都要执行向后位/向前移一位的操作。 ② LinkedList 采用链表存储,所以对于add(E e)方法的插入,删除元素时间复杂度不受元素位置的影响,近似 O(1),如果是要在指定位置i插入和删除元素的话((add(int index, E element)) 时间复杂度近似为o(n))因为需要先移动到指定位置再插入。
  4. 是否支持快速随机访问: LinkedList 不支持高效的随机元素访问,而 ArrayList 支持。快速随机访问就是通过元素的序号快速获取元素对象(对应于get(int index)方法)。
  5. 内存空间占用: ArrayList 的空 间浪费主要体现在在 list 列表的结尾会预留一定的容量空间,而 LinkedList 的空间花费则体现在它的每一个元素都需要消耗比 ArrayList 更多的空间(因为要存放直接后继和直接前驱以及数据)。

多线程相关

什么是线程和进程? 线程与进程的关系,区别及优缺点?

  • 进程是具有一定独立功能的程序,关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位
  • 进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。

使用多线程可能带来什么问题?

内存泄漏、死锁、线程不安全等等

创建线程有哪几种方式?

a.继承 Thread 类;b.实现 Runnable 接口;c. 使用 Executor 框架;d.使用 FutureTask

线程的生命周期和状态?

什么是上下文切换

CPU通过时间片分配算法来循环执行任务,当前任务执行一个时间片后会切换到下一个任务。但是,在切换前会保存上一个任务的状态,以便下次切换回这个任务时,可以再次加载这个任务的状态,从任务保存到再加载的过程就是一次上下文切换

synchronized加锁方式

1、修饰一个代码块,作用的范围是大括号括起来的对象,作用的对象是调用这个代码块的对象

2、修饰一个方法,被修饰的方法称为同步方法,作用的范围是整个方法,作用的对象是调用这个 方法的对象

3、修饰一个静态的方法,其作用的范围是整个静态方法,租用的对象是这个类的所有对象

4、修饰一个类,起作用的范围是synchronized后面括号括起来的部分,作用的对象是这个类的所有对象

什么是线程死锁?如何避免死锁?

当线程A持有独占锁a,并尝试去获取独占锁b的同时,线程B持有独占锁b,并尝试获取独占锁a的情况下,就会发生AB两个线程由于互相持有对方需要的锁,而发生的阻塞现象,我们称为死锁

破坏死锁的四个必要条件:互斥条件、请求与保持条件、不剥夺条件、循环等待条件。其中前三个称为独占锁。

synchronized 关键字和 volatile 关键字的区别

volatile能够保证可见性和有序性,但无法保证原子性;synchronized则都能保证

准备内容:网络、数据结构、算法、Linux、flask(?)

ArrayList

数组的长度声明即固定,存在局限性,为了解决该局限性,引入了容器

  • 容器:其容量capacity会随着对象的增加自动增长,无须担心数组的边界问题
  • 常用方法
    • add():增加一个元素
    • contains():判断是否存在某个元素
    • get():获取指定位置的对象
    • indexOf():获取对象所处的位置
    • remove():删除指定元素(下标或具体对象)
    • set():替换元素
    • size():获取大小
    • toArray():转换为数组
    • addAll():把另一个容器的所有对象都加进来
    • clear():清空
阅读全文 »

I/O文件对象

  • 使用绝对路径或相对路径创建File对象File file = new File("path")
  • File类的常用方法
    • exists():是否存在
    • isDirectory():是否为目录
    • isFile():是否为文件
    • length():获取文件长度
    • lastModified():文件的最后修改时间
    • renameTo():文件重命名
    • list():以String[]返回当前文件夹下的所有文件(不包括子文件及子文件夹)
    • listFiles():以Files[]返回当前文件夹下的所有文件(不包括子文件及子文件夹)
    • getParent():以String返回所在文件夹
    • getParentFile():以File返回所在文件夹
    • mkdir():创建单级目录
    • mkdirs():创建多级目录
    • createNewFile():创建空文件
    • delete():删除文件
    • deleteOnExit():JVM结束的时候删除文件,用于临时文件的删除
阅读全文 »

异常处理

  • 使用try catch捕捉异常

    • 直接catch异常的类 如catch(FileNotFoundException e){}

    • catch父类 如catch(Exception e){}

    • 分别catch多个异常

      • catch(FileNotFoundException | ParseException e){}

      • catch(FileNotFoundException e){}

        catch(ParseException e){}

  • finally:无论是否出现异常,finally中的代码都会被执行

阅读全文 »

Date类

  • java.util.Date和java.sql.Date区别

    java.sql.Date是java.util.Date的子类

    java.util.Date的格式为 “Fri May 01 00.00.00.00MT”,java.sql.Date的格式为“2016-02-01”

    它们都有getTime()方法返回毫秒数,可以直接使用构造函数转换

  • 时间原点:1970年1月1日 8点0分0秒,即UNIX的第一个版本发布

阅读全文 »

封装类

  • 所有的基本类型,都有对应的类类型,如int->Integer,这种类就叫做封装类

  • 转换如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class TestNumber {
    public static void main(String[] args) {
    int i = 5;
    //把一个基本类型的变量,转换为Integer对象
    Integer it = new Integer(i);
    //把一个Integer对象,转换为一个基本类型的int
    int i2 = it.intValue();
    }
    }
阅读全文 »