顺时针打印矩阵
题目链接
题目描述
按顺时针的方向,从外到里打印矩阵的值。下图的矩阵打印结果为:1, 2, 3, 4, 8, 12, 16, 15, 14, 13, 9, 5, 6, 7, 11, 10
引用拷贝:不会生成新的对象,只会在原对象上增加了一个新的对象引用,两个引用指向的对象还是同一个
浅拷贝:会生成新的对象,但是对象中的引用类型并不会重新生成(修改该类属性仍然会连环修改)
深拷贝:会生成新的对象,且对象中的引用类型也会重新生成对象
1 | package JavaGuide; |
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
,TreeMap
,PriorityQueue
都不是线程安全的。解决办法很简单,可以使用线程安全的集合来代替。
如果你要使用线程安全的集合的话, java.util.concurrent
包中提供了很多并发容器供你使用:
ConcurrentHashMap
: 可以看作是线程安全的 HashMap
CopyOnWriteArrayList
:可以看作是线程安全的 ArrayList
,在读多写少的场合性能非常好,远远好于 Vector
.ConcurrentLinkedQueue
:高效的并发队列,使用链表实现。可以看做一个线程安全的 LinkedList
,这是一个非阻塞队列。BlockingQueue
: 这是一个接口,JDK 内部通过链表、数组等方式实现了这个接口。表示阻塞队列,非常适合用于作为数据共享的通道。ConcurrentSkipListMap
:跳表的实现。这是一个Map
,使用跳表的数据结构进行快速查找。ArrayList
和 LinkedList
都是不同步的,也就是不保证线程安全;Arraylist
底层使用的是 Object
数组;LinkedList
底层使用的是 双向链表 数据结构(JDK1.6 之前为循环链表,JDK1.7 取消了循环。注意双向链表和双向循环链表的区别,下面有介绍到!)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))
因为需要先移动到指定位置再插入。LinkedList
不支持高效的随机元素访问,而 ArrayList
支持。快速随机访问就是通过元素的序号快速获取元素对象(对应于get(int index)
方法)。内存泄漏、死锁、线程不安全等等
a.继承 Thread 类;b.实现 Runnable 接口;c. 使用 Executor 框架;d.使用 FutureTask
CPU通过时间片分配算法来循环执行任务,当前任务执行一个时间片后会切换到下一个任务。但是,在切换前会保存上一个任务的状态,以便下次切换回这个任务时,可以再次加载这个任务的状态,从任务保存到再加载的过程就是一次上下文切换。
1、修饰一个代码块,作用的范围是大括号括起来的对象,作用的对象是调用这个代码块的对象
2、修饰一个方法,被修饰的方法称为同步方法,作用的范围是整个方法,作用的对象是调用这个 方法的对象
3、修饰一个静态的方法,其作用的范围是整个静态方法,租用的对象是这个类的所有对象
4、修饰一个类,起作用的范围是synchronized后面括号括起来的部分,作用的对象是这个类的所有对象
当线程A持有独占锁a,并尝试去获取独占锁b的同时,线程B持有独占锁b,并尝试获取独占锁a的情况下,就会发生AB两个线程由于互相持有对方需要的锁,而发生的阻塞现象,我们称为死锁
破坏死锁的四个必要条件:互斥条件、请求与保持条件、不剥夺条件、循环等待条件。其中前三个称为独占锁。
volatile能够保证可见性和有序性,但无法保证原子性;synchronized则都能保证
准备内容:网络、数据结构、算法、Linux、flask(?)
File file = new File("path")