- 博客(148)
- 收藏
- 关注
原创 虚引用实现资源回收
资源回收GC是Java平台的一个重要特性,大大减轻了开发人员对内存管理的痛苦,帮助他们不受内存相关的问题影响。然而,当在java代码中使用了外部资源(例如文件和套接字),内存管理将变得棘手,因为单独的GC不足以管理这样的资源。问题假设我们有如下场景,我们需要在Resource实例被销毁前,调用到dispose()方法:public interface ResourceFacade { ...
2019-01-06 17:24:00
751
1
原创 Elasticsearch加入集群流程
简介es节点启动时,做的最重要的一件事就是加入集群,今天分析下es节点加入集群的源码。主要知识点es基础基于lucene的分布式搜索引擎,不在累述,可以自行查阅资料。Bully算法提到分布式选举算法,大家都知道Paxos算法,但是这个算法比较复杂,es选取的是一个很简单的Bully算法,算法描述如下:某个进程通过广播,获取所有能够连接到的进程的ID。如果发现自己是ID最大的进程,...
2018-11-04 21:45:21
2696
原创 lucene倒排索引的内存结构
简介lucene索引格式是个老生常谈的问题,网上也有一些资料,但是由于年代比较古老(大都是基于3.x或者4.x的版本),和现有代码较难对上,这里基于lucene6.6重新讲解下,也帮助自己理解和记忆。基本概念 这些信息很容易理解,看代码的时候也很清晰。lucene在进行索引时,为了加速索引进程,会同时多线程同时进行索引,每一个线程在flush后都是一个完整的索引段。对...
2018-09-02 16:25:59
2190
原创 ClassLoader和热加载
classloader 任何一本java相关的书都有介绍classloader相关的知识,最近工作中确实用到了一些classloader相关的东西,做个总结以免自己忘记。定义classloader负责将应用中用到的==所有class==加载到虚拟机中供应用使用,并且确保类能够被==正确的以符合开发者想法的方式加载,保证所有类能够被正确的使用==。这里对应的是类加载的第一阶段。...
2018-03-12 21:06:10
458
原创 HashMap死循环问题追踪
HashMap死循环问题追踪简介HashMap在设计之初并没有考虑多线程并发的情况,多线程并发的情况下理论上应该使用ConcurrentHashMap,但是程序中经常会无意中在多并发的情况下使用了HashMap,如果是jdk1.8以下的版本,有可能会导致死循环,打满cpu占用,下面基于jdk1.7源码分析下原因。HashMap的原理我们从put看起 public V put(K key, V
2018-02-26 14:17:17
360
原创 java类文件格式和类加载机制
Class文件解析java虚拟机设计之初,就考虑到语言扩展的问题,因此java虚拟机并不是专门为java服务的。确切的说,java虚拟机是为class文件服务的,一切合法的class文件都可以被虚拟机接受执行,而java编译器将java代码编译成对应的class文件,从而被虚拟机执行。类似的,如今groovy和scala文件都可以被各自的编译器编译成class文件运行在java虚拟机中。为了保证cl
2018-01-06 16:00:23
1061
原创 AtomicInteger源码解析
AtomicInteger源码非常简单,仅仅使用了一个volatile类型的值和一个static类型的偏移量完成整个原子int操作。其中,valueoffset用来记录value字段相对于整个类对象起始位置的偏移量,这个在class被加载到内存的时候就已经确定了,因此使用static类型的值,final保证了数据的可见性。value使用volatile,通过volatile内存屏障保证value类型
2018-01-03 22:27:36
302
原创 内存屏障与volatile
内存屏障由于现代操作系统都是多处理器操作系统,每个处理器都会有自己的缓存,可能存再不同处理器缓存不一致的问题,而且由于操作系统可能存在重排序,导致读取到错误的数据,因此,操作系统提供了一些内存屏障以解决这种问题:LoadLoad屏障对于Load1; LoadLoad; Load2 ,操作系统保证在Load2及后续的读操作读取之前,Load1已经读取。StoreStore屏障对于Store1;
2018-01-03 20:11:46
3845
1
原创 spark学习记录
最近公司要开发一个spark项目,学习下spark使用,由于公司原因必须使用java,以下代码全部基于java实现。spark基础基于内存实现,效率高于hadoop,内存不足的时候也会将中间结果写入磁盘,效率会降低。操作容易,hadoop只提供了map和reduce两个操作,对于某些复杂任务,会写很多map和reduce,操作非常复杂,而且由于map阶段完全完成后才会进行reduce,效率会降低
2017-09-23 14:48:10
275
原创 python爬取豆瓣图书
最近突然想学下爬虫爬取一下豆瓣的图书,按类别来爬取并分别存储,然后就用正则写了一份初级爬虫。# -*- coding:utf-8 -*-import urllib2import reimport systags = [u'小说', u'散文', u'历史', u'爱情', u'管理', u'编程', u'生活', u'心理']haveBooked = set()class B
2017-04-10 15:50:06
2599
原创 C++中多线程编程之volatile分析
volatile是c++的关键字之一,其修饰的变量表示容易被修改,要求编译器不要对其读写进行优化。volatile主要有以下特点:1:对其修饰的变量,每次读取必须去内存中读取数据,而不相信寄存器或者cache中的数据准确性。2:vs中,在同一个线程中,volatile修饰的变量的,对于其读操作,在其之后的所有写操作都会在读之前完成,不会被编译器优化乱序执行影响到,对于其写操作,所有
2016-10-27 15:50:04
1771
原创 腾讯面试题
总共有20个球,A和B轮流拿,每次只可以拿1,2,4个,可选先手或者后手,问必胜策略。剩1个或者4个时,先拿的必败。那么只需要先拿走一个球,剩19个。然后保证每次两个人拿的总和是3或6,即保证最后自己拿完剩的球数一定为1或者4,此时必胜。可以列表:用1表示此时先手胜,0表示负剩余球数胜负1021314051(拿一个到4)6
2015-09-15 11:36:41
519
原创 二叉树的非递归遍历
腾讯面试题,没写出来挺可惜的,基础忘的太多了。#include #include #include #include #include #include #include #include #include #define ll long long int#define ull unsigned long long int#define MAX(a,b) ((a)>(b)
2015-09-15 10:35:52
434
原创 蓄水池采样法
看到一个非常有趣的题目,学会了一个非常巧妙的算法:如何从n个数中随机的选择k个数?如果采用直接产生随机数的方法,当n和m都很大时,随机数产生重复的概率会很大,算法性能会大大降低。这里采用蓄水池算法,算法代码很简答,假设从n个数中选择k个数: for (int i=k+1;i<=n;i++) { int p=rand(1,i); if (
2015-09-10 22:16:14
1099
原创 miller_robin判断大素数
用到了windows的多线程,一千多位的整数需要二十秒左右一个,多个的话四线程时间除四#include #include #include #include #define ull unsigned long long intDWORD WINAPI Fun1Proc(LPVOID lpParameter);DWORD WINAPI Fun2Proc(LPVOID lpParam
2015-08-25 08:55:56
1773
原创 阿里算法附加题
想着应该能二分,试着写了一个代码,没有完全数据,也不知道对不对。思路是:二分较长的一个数列,因为较长的那个中肯定有数字是中位数或者一部分,二分之后,判断另一个数列需要多少个数,要求的位置就是不小于另一个数列t且不大于t+1,输出即可。代码:#include #include #include #include #include #include #include #def
2015-04-03 21:23:53
626
原创 hdu5192 树状数组
具体解法bestcoder上都有,这里就不详细写了。主要用到一个树状数组区间更新单点求和的问题,以前这类问题都是用线段树做的,这次研究了一下树状数组。大概就是,记录的值为每一个点和之前一个点的差值,这样的话,以前的函数依然可以用,但是求和函数的意义发生变化。之前求和求得的是区间和,但是现在的记录方式,求得的是最后一个节点相对于0节点的变化量总和,如果0节点值恒为0,那么这样求的便是最后一个
2015-03-24 15:17:47
523
原创 hdu5188 二分 or 背包
题目关键在于,对于时间最少的方法的方法,一定按照题目最早可以开始做的时间的顺序做,即按照l-t的从小到大顺序来做。不妨假设1的开始时间小于2,那么一旦先做2,很明显从做完上件题目后的等待时间加长,因此可以得出最优解一定按照l-t的顺序做。然后就是两种方法了,一种背包,一种二分,背包是求出了每个时间的最优值,而二分加dfs只是不断验证是否可行再二分的过程,事实证明,后者省去很多时间。附代
2015-03-16 15:51:00
581
原创 快排,堆排序,基数排序手写记录
闲来无事,手写一遍三种排序。#include #include #include #include using namespace std;//快排void quick_sort(int v[],int s,int e){ if (s>=e) return ; int key = v[s]; int i=s; int t=e;
2015-03-04 21:51:39
659
原创 关于堆排序建堆时间复杂度的证明
建堆的过程,看起来外面一层循环O(n),里面是个logn的调整函数,时间复杂度貌似是nlogn的,但是仔细分析,其实质是O(n)的。证明如下:首先,对于高度为h的完全二叉树,其第i层的元素个数为2^(i-1),对于堆的每一层,调整的深度都不一样,每层的元素的调整深度小于等于h-i,假设每层调整的深度是h-i,欲构建的堆是个完全二叉树,那么对于每层来说:最后一层不用调整;倒数第二层的
2015-03-04 21:17:08
3484
原创 hdu5156 LCA
具体解法就是bc首页的解法了,排个颜色序和dfs序,然后按照解法一路解下去就行了。注意一定要pai排dfs序,不然会更新错误的公共祖先节点。代码:#include #include #include #include #include #include #include #include #define ll long long int#define lson l,m,r
2015-01-04 16:17:24
865
原创 hdu5115 区间dp
和北京的那道题好像,可惜还是没能在比赛中做出来。这个题目可以这样,将n个人分配到座位上,就是求1~n的全排列中符合题意的个数,其中1~n的编号就是他们坐的顺序,先枚举最后一个坐的人的座位编号,然后剩余的人(即编号)分成两部分,一部分在第一个人的左边,一个人在第一个人的右边,这样对于左右两边又是一次全新的分配(左右两边分配到的的编号可能不连续,但是他们有先后顺序即可确定坐的次序,无非是左边坐完右
2014-12-28 17:39:39
767
原创 hdu5144 三分
三分裸题,看在第三百题的份上贴一下~#include #include #include #include using namespace std;const double pi=acos(-1.0);const double g=9.8;double v,h;double ans(double a){ double a1=v*v*sin(a)*sin(a);
2014-12-22 22:21:02
814
原创 vijos 1193 dp
每一行的状态由之前两行决定,dp[i][t][k]表示第i行状态为k,下一行状态为t时的种数,然后dp一遍即可。代码:#include #include #include using namespace std;int a[10010];int dp[10010][2][2]; //1下一行还需要一个1,0下一行不需要1int main(){ int n;
2014-12-15 20:22:29
704
原创 NOIP2014 子矩阵
状压dp水题。#include #include #include using namespace std;int mp[20][20];int dp[20000][20][20];int n,m,r,c;int sta[20000];int v[20000][20][20];int vv[20000][20];int sc;int abs(int a){
2014-12-15 17:02:44
1815
原创 hdu5125 dp+树状数组
最朴素的dp是n^3的,肯定会超时,那么借鉴nlogn的LIS算法,先对每个球的值离散化,对于每个消耗值建一棵树状数组,,第t棵树状数组的叶子的值v表示消耗为t且以v结尾的最大长度,那么每次更新的时候,如果不交换,对每个消耗值t,求消耗值为t以1~a[i]结尾的最大长度,如果交换,对每个消耗值t,求消耗值为t-1以1~a[i]的最大长度,更新树状数组即可。代码:#include #inc
2014-11-30 10:33:30
1131
原创 hdu5109 构造
答案肯定是xSy形式,枚举x,枚举y的长度,求出y即可,x至多枚举至a,大于a的取余结果和小于a的一一对应,得出的结果肯定不如小于a的那个小,y也至多到a,否则取余直接取掉,肯定不是最优解。代码:#include #include #include #include #include #include #include #include #include #define
2014-11-29 22:19:14
788
原创 hdu5115 北京现场赛D
比赛时一直想贪心,其实就是个弱到爆的区间dp。#include #include #include using namespace std;int dp[222][222];int a[222];int n;int min(int a,int b){ return a<b?a:b;}int solve(int l,int r){ if (dp[l]
2014-11-29 14:45:21
1100
原创 hdu5107 线段树
代码:#include #include #include #include #include #define ll long long int#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define delf int m=(l+r)>>1using namespace std;int num[66666*4][11
2014-11-19 20:02:52
772
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人