- Algorithm。主要是为了编程训练和学习。每周至少做一个 leetcode 的算法题(先从Easy开始,然后再Medium,最后才Hard)。进行编程训练,如果不训练你看再多的算法书,你依然不会做算法题,看完书后,你需要训练。关于做Leetcode的的优势,你可以看一下我在coolshell上的文章 Leetcode 编程训练 - 酷 壳 - CoolShell。
- Review:主要是为了学习英文,如果你的英文不行,你基本上无缘技术高手。所以,需要你阅读并点评至少一篇英文技术文章,我个人最喜欢去的地方是http://Medium.com(需要梯子)以及各个公司的技术blog,如Netflix的。
- Tip:主要是为了总结和归纳你在是常工作中所遇到的知识点。学习至少一个技术技巧。你在工作中遇到的问题,踩过的坑,学习的点滴知识。
- Share:主要是为了建立你的影响力,能够输出价值观。分享一篇有观点和思考的技术文章
打卡地址
88. 合并两个有序数组
给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。
说明:
初始化 nums1 和 nums2 的元素数量分别为 m 和 n。
你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
示例:输入:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3输出: [1,2,2,3,5,6]
public static void merge(int[] nums1, int m, int[] nums2, int n) {
int n1Start = 0;
int n2Start = 0;
while (n2Start < n) {
if (nums1[n1Start] >= nums2[n2Start] || m <= n1Start ) {
System.arraycopy(nums1, n1Start, nums1,n1Start + 1,nums1.length - n1Start - 1);
nums1[n1Start] = nums2[n2Start];
n2Start++;
m++;
}
n1Start++;
}
}
1.首先返回的就是原数组nums1,所以没办法用一个新的数组接收返回(当然可以通过把新数组copy到nums1数组)。
2.有些情况,到了最后nums2的元素要和nums1中最后的0进行替换,但不能通过对0这个数值进行比较来替换,要应用m,这个nums1规定的有效数值长度来控制比较。
3.将nums2中的数据插入到nums1中,循环的时候只要判断nums2中的数据都放入就可以了。
首先的第一个难点其实就是想到用System.arraycopy来进行数组的拷贝,我第一个想到的是拿一个新的数组来接收,然后将新数组的内容拷贝到nums1。当然新数组需要开辟新的空间。
public static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length)
src:源数组;
srcPos:源数组要复制的起始位置;
dest:目的数组;
destPos:目的数组放置的起始位置;
length:复制的长度。
注意:src 和 dest都必须是同类型或者可以进行转换类型的数组.
暂无
既然IN 和 EXIST 都可以得到相同的结果,那么我们该使用IN 还是 EXIST 呢?
SELECT * FROM A WHERE cc IN (SELECT cc FROM B)
SELECT * FROM A WHERE EXIST (SELECT cc FROM B WHERE B.cc=A.cc)
实际上在查询过程中,在我们对cc列建立索引的情况下,我们还需要判断表A和表B的大小。在这里例子当中,表A指的是player表,表B指的是player_ score表。
如果表A比表B大,那么IN子查询的效率要比EXIST子查询效率高,因为这时B表中如果对cc列进行了索引,那么IN子查询的效率就会比较高。
如果表A比表B小,那么使用EXIST子查询效率会更高,因为我们可以使用到A表中对cc列的索引,而不用从B中进行cc列的查询。
HashMap在jdk1.8中加入了红黑树,在满足一定条件时,将链表转化为红黑树
扩容的条件有两个:
1)数组的长度达到了扩容阀值
2)桶中的链表长度达到了8,并且数组的长度小于64
树化的条件是:
桶中单链表的长度达到了8,并且数组的长度大于等于64。
当然在条件不满足的情况下,红黑树也会转化为链表
链表虽然实现简单,但是在查找的效率上只有O(n),而且我们大部分的操作都是在进行查找,在hashCode()设计的不是非常良好的情况下,碰撞冲突可能会频繁发生,链表也会变得越来越长,这个效率是非常差的。Java 8对其实现了优化,链表的节点数量在到达阈值时会转化为红黑树,这样查找所需的时间就只有O(log n)了
主要是为了避免哈希碰撞拒绝服务攻击。
从性能角度来看:解决哈希冲突时使用链表,插入和删除的效率很高,只需O(1)的时间复杂度,但对于查询而言,则需要O(n)的时间负责度。但红黑树的插入,删除,查询的最差时间复杂度为O(logn)。恶意代码可以利用大量数据与服务器交互,比如String的hashcode函数的强度很弱,有人可以很容易的构造出大量hashcode相同的String对象。如果向服务器一次提交数万个hashcode相同的字符串,服务器的查询时间过长,让服务器的CPU被大量占用,当有其他更多的请求时服务器会拒绝服务。而使用红黑树可以将查询时间降低到一定的数量级,可以有效避免哈希碰撞拒绝服务攻击。
HashMap为什么树化
HashMap源码浅析(一):树化