-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
586 lines (400 loc) · 75.5 KB
/
index.html
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
<!DOCTYPE html>
<html>
<head><meta name="generator" content="Hexo 3.8.0">
<meta charset="utf-8">
<title>ddmonk's blog</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="description" content="一个会白日做梦的和尚">
<meta property="og:type" content="website">
<meta property="og:title" content="ddmonk's blog">
<meta property="og:url" content="http://yoursite.com/index.html">
<meta property="og:site_name" content="ddmonk's blog">
<meta property="og:description" content="一个会白日做梦的和尚">
<meta property="og:locale" content="zh-CN">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="ddmonk's blog">
<meta name="twitter:description" content="一个会白日做梦的和尚">
<link rel="alternative" href="/atom.xml" title="ddmonk's blog" type="application/atom+xml">
<link rel="icon" href="/favicon.png">
<link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="/css/style.css">
</head></html>
<body>
<div id="container">
<div id="wrap">
<header id="header">
<div id="banner"></div>
<div id="header-outer" class="outer">
<div id="header-title" class="inner">
<h1 id="logo-wrap">
<a href="/" id="logo">ddmonk's blog</a>
</h1>
<h2 id="subtitle-wrap">
<a href="/" id="subtitle">技术积累</a>
</h2>
</div>
<div id="header-inner" class="inner">
<nav id="main-nav">
<a id="main-nav-toggle" class="nav-icon"></a>
<a class="main-nav-link" href="/">Home</a>
<a class="main-nav-link" href="/archives">Archives</a>
</nav>
<nav id="sub-nav">
<a id="nav-rss-link" class="nav-icon" href="/atom.xml" title="RSS Feed"></a>
<a id="nav-search-btn" class="nav-icon" title="Search"></a>
</nav>
<div id="search-form-wrap">
<form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit"></button><input type="hidden" name="sitesearch" value="http://yoursite.com"></form>
</div>
</div>
</div>
</header>
<div class="outer">
<section id="main">
<article id="post-Linux-mv" class="article article-type-post" itemscope itemprop="blogPost">
<div class="article-meta">
<a href="/2019/04/02/Linux-mv/" class="article-date">
<time datetime="2019-04-02T07:14:47.534Z" itemprop="datePublished">2019-04-02</time>
</a>
</div>
<div class="article-inner">
<div class="article-entry" itemprop="articleBody">
<p>title: Linux mv 操作是否新创建空间<br>date: 2017-02-24 17:36:53</p>
<h2 id="tags-编程开发"><a href="#tags-编程开发" class="headerlink" title="tags:编程开发"></a>tags:编程开发</h2><h1 id="Linux-mv-操作的探讨"><a href="#Linux-mv-操作的探讨" class="headerlink" title="Linux mv 操作的探讨"></a>Linux mv 操作的探讨</h1><h2 id="前期内容"><a href="#前期内容" class="headerlink" title="前期内容"></a>前期内容</h2><p>Linux 操作过程中,可以通过 <code>ll -i</code> 查看inode</p>
<blockquote>
<p>inode详解<br>linux上的inode编号是索引节点的编号。理解inode,要从文件储存说起。<br> 文件储存在硬盘上,硬盘的最小存储单位叫做”扇区”(Sector)。每个扇区储存512字节(相当于0.5KB)。<br> 操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个”块”(block)。这种由多个扇区组成的”块”,是文件存取的最小单位。”块”的大小,最常见的是4KB,即连续八个 sector组成一个 block。<br> 文件数据都储存在”块”中,那么很显然,还必须找到一个地方储存文件的元信息,比如文件的创建者、文件的创建日期、文件的大小等等。这种储存文件元信息的区域就叫做inode,中文译名为”索引节点”。<br> 每个inode都有一个号码,操作系统用inode号码来识别不同的文件。这里值得重复一遍,Unix/Linux系统内部不使用文件名,而使用inode号码来识别文件。对于系统来说,文件名只是inode号码便于识别的别称或者绰号。表面上,用户通过文件名,打开文件。实际上,系统内部这个过程分成三步:首先,系统找到这个文件名对应的inode号码;其次,通过inode号码,获取inode信息;最后,根据inode信息,找到文件数据所在的block,读出数据。</p>
</blockquote>
<h2 id="结论"><a href="#结论" class="headerlink" title="结论"></a>结论</h2><p>mv 在操作过程中不会改变文件在磁盘上的位置。</p>
<h2 id="测试"><a href="#测试" class="headerlink" title="测试"></a>测试</h2><blockquote>
<p>1 查看当前Linux中磁盘情况<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">df</span><br></pre></td></tr></table></figure></p>
</blockquote>
<p>显示如图:<br><img src="/2019/04/02/Linux-mv/1.png" alt="1"></p>
<blockquote>
<p>2 查看需要<code>mv</code>的文件的inode<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ll -i</span><br></pre></td></tr></table></figure></p>
</blockquote>
<p>显示如图:<br><img src="/2019/04/02/Linux-mv/2.png" alt="2"></p>
<blockquote>
<p>3 移动并查看移动后的文件的inode<br>显示如图<br><img src="/2019/04/02/Linux-mv/3.png" alt="3"></p>
</blockquote>
</div>
<footer class="article-footer">
<a data-url="http://yoursite.com/2019/04/02/Linux-mv/" data-id="cjtzk001f0009jejx4iid4081" class="article-share-link">Share</a>
</footer>
</div>
</article>
<article id="post-hello-world" class="article article-type-post" itemscope itemprop="blogPost">
<div class="article-meta">
<a href="/2019/04/02/hello-world/" class="article-date">
<time datetime="2019-04-02T07:14:47.534Z" itemprop="datePublished">2019-04-02</time>
</a>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2019/04/02/hello-world/">Hello World</a>
</h1>
</header>
<div class="article-entry" itemprop="articleBody">
<p>Welcome to <a href="http://hexo.io/" target="_blank" rel="noopener">Hexo</a>! This is your very first post. Check <a href="http://hexo.io/docs/" target="_blank" rel="noopener">documentation</a> for more info. If you get any problems when using Hexo, you can find the answer in <a href="http://hexo.io/docs/troubleshooting.html" target="_blank" rel="noopener">troubleshooting</a> or you can ask me on <a href="https://github.com/hexojs/hexo/issues" target="_blank" rel="noopener">GitHub</a>.</p>
<h2 id="Quick-Start"><a href="#Quick-Start" class="headerlink" title="Quick Start"></a>Quick Start</h2><h3 id="Create-a-new-post"><a href="#Create-a-new-post" class="headerlink" title="Create a new post"></a>Create a new post</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo new <span class="string">"My New Post"</span></span><br></pre></td></tr></table></figure>
<p>More info: <a href="http://hexo.io/docs/writing.html" target="_blank" rel="noopener">Writing</a></p>
<h3 id="Run-server"><a href="#Run-server" class="headerlink" title="Run server"></a>Run server</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo server</span><br></pre></td></tr></table></figure>
<p>More info: <a href="http://hexo.io/docs/server.html" target="_blank" rel="noopener">Server</a></p>
<h3 id="Generate-static-files"><a href="#Generate-static-files" class="headerlink" title="Generate static files"></a>Generate static files</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo generate</span><br></pre></td></tr></table></figure>
<p>More info: <a href="http://hexo.io/docs/generating.html" target="_blank" rel="noopener">Generating</a></p>
<h3 id="Deploy-to-remote-sites"><a href="#Deploy-to-remote-sites" class="headerlink" title="Deploy to remote sites"></a>Deploy to remote sites</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo deploy</span><br></pre></td></tr></table></figure>
<p>More info: <a href="http://hexo.io/docs/deployment.html" target="_blank" rel="noopener">Deployment</a></p>
</div>
<footer class="article-footer">
<a data-url="http://yoursite.com/2019/04/02/hello-world/" data-id="cjtzk001h000ajejx3arhpe9i" class="article-share-link">Share</a>
</footer>
</div>
</article>
<article id="post-test" class="article article-type-post" itemscope itemprop="blogPost">
<div class="article-meta">
<a href="/2019/04/01/test/" class="article-date">
<time datetime="2019-04-01T17:28:49.000Z" itemprop="datePublished">2019-04-02</time>
</a>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2019/04/01/test/">test</a>
</h1>
</header>
<div class="article-entry" itemprop="articleBody">
</div>
<footer class="article-footer">
<a data-url="http://yoursite.com/2019/04/01/test/" data-id="cjtzk001l000bjejx6jkujv2f" class="article-share-link">Share</a>
</footer>
</div>
</article>
<article id="post-JAVA-Integer" class="article article-type-post" itemscope itemprop="blogPost">
<div class="article-meta">
<a href="/2019/04/01/JAVA-Integer/" class="article-date">
<time datetime="2019-04-01T17:11:46.000Z" itemprop="datePublished">2019-04-02</time>
</a>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2019/04/01/JAVA-Integer/">JAVA Integer</a>
</h1>
</header>
<div class="article-entry" itemprop="articleBody">
<h1 id="Java-Integer小实验"><a href="#Java-Integer小实验" class="headerlink" title="Java Integer小实验"></a>Java Integer小实验</h1><h2 id="背景"><a href="#背景" class="headerlink" title="背景"></a>背景</h2><p>在项目过程中,有同事在Integer之间使用的<code>==</code>进行比较,导致现网上面一直无法匹配,但是在测试过程中并没有发现类似的问题,所以有必要对Integer之间的比较进行一个调研。</p>
<h2 id="实验"><a href="#实验" class="headerlink" title="实验"></a>实验</h2><p>在比较过程中我书写了如下代码进行比较:<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Main</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>{</span><br><span class="line"> Integer integer127 = <span class="number">127</span>;</span><br><span class="line"> Integer integer128 = <span class="number">128</span>;</span><br><span class="line"> Integer newInteger127 = <span class="keyword">new</span> Integer(<span class="number">127</span>);</span><br><span class="line"> <span class="keyword">int</span> int127 = <span class="number">127</span>;</span><br><span class="line"> <span class="keyword">int</span> int128 = <span class="number">128</span>;</span><br><span class="line"> Integer integer128copy = <span class="number">128</span>;</span><br><span class="line"> Integer integer127copy = <span class="number">127</span>;</span><br><span class="line"> <span class="keyword">boolean</span> compareA = integer127 == newInteger127;</span><br><span class="line"> <span class="keyword">boolean</span> compareB = integer127 == int127;</span><br><span class="line"> <span class="keyword">boolean</span> compareC = integer128 == int128;</span><br><span class="line"> <span class="keyword">boolean</span> compareD = integer128 == integer128copy;</span><br><span class="line"> <span class="keyword">boolean</span> compareE = integer127 == integer127copy;</span><br><span class="line"> System.out.println(<span class="string">"integer127 == newInteger127: "</span> + compareA);</span><br><span class="line"> System.out.println(<span class="string">"integer127 == int127: "</span> + compareB);</span><br><span class="line"> System.out.println(<span class="string">"integer128 == int128: "</span> + compareC);</span><br><span class="line"> System.out.println(<span class="string">"integer128 == integer128copy: "</span> + compareD);</span><br><span class="line"> System.out.println(<span class="string">"integer127 == integer127copy: "</span> + compareE);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line">``` </span><br><span class="line">输出结果如下:</span><br><span class="line">```JAVA</span><br><span class="line">integer127 == newInteger127: <span class="keyword">false</span></span><br><span class="line">integer127 == int127: <span class="keyword">true</span></span><br><span class="line">integer128 == int128: <span class="keyword">true</span></span><br><span class="line">integer128 == integer128copy: <span class="keyword">false</span></span><br><span class="line">integer127 == integer127copy: <span class="keyword">true</span></span><br></pre></td></tr></table></figure></p>
<h2 id="分析"><a href="#分析" class="headerlink" title="分析"></a>分析</h2><h3 id="Compile代码"><a href="#Compile代码" class="headerlink" title="Compile代码"></a>Compile代码</h3><p>首先使用<code>javac -p Main.claas</code>查看其编译过程。部分内容截图如下:<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Main</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">Main</span><span class="params">()</span></span>;</span><br><span class="line"> Code:</span><br><span class="line"> <span class="number">0</span>: aload_0</span><br><span class="line"> 1: invokespecial #1 // Method java/lang/Object."<init>":()V</span><br><span class="line"> <span class="number">4</span>: <span class="keyword">return</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(java.lang.String[])</span></span>;</span><br><span class="line"> Code:</span><br><span class="line"> <span class="number">0</span>: bipush <span class="number">127</span></span><br><span class="line"> 2: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;</span><br><span class="line"> <span class="number">5</span>: astore_1</span><br><span class="line"> <span class="number">6</span>: sipush <span class="number">128</span></span><br><span class="line"> 9: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;</span><br><span class="line"> <span class="number">12</span>: astore_2</span><br><span class="line"> 13: new #3 // class java/lang/Integer</span><br><span class="line"> <span class="number">16</span>: dup</span><br><span class="line"> <span class="number">17</span>: bipush <span class="number">127</span></span><br><span class="line"> 19: invokespecial #4 // Method java/lang/Integer."<init>":(I)V</span><br><span class="line"> <span class="number">22</span>: astore_3</span><br><span class="line"> <span class="number">23</span>: bipush <span class="number">127</span></span><br><span class="line"> <span class="number">25</span>: istore <span class="number">4</span></span><br><span class="line"> <span class="number">27</span>: sipush <span class="number">128</span></span><br><span class="line"> <span class="number">30</span>: istore <span class="number">5</span></span><br><span class="line"> <span class="number">32</span>: sipush <span class="number">128</span></span><br><span class="line"> 35: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;</span><br><span class="line"> <span class="number">38</span>: astore <span class="number">6</span></span><br><span class="line"> <span class="number">40</span>: bipush <span class="number">127</span></span><br><span class="line"> 42: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;</span><br><span class="line"> <span class="number">45</span>: astore <span class="number">7</span></span><br><span class="line"> <span class="number">47</span>: aload_1</span><br><span class="line"> <span class="number">48</span>: aload_3</span><br><span class="line"> <span class="number">49</span>: if_acmpne <span class="number">56</span></span><br><span class="line"> <span class="number">52</span>: iconst_1</span><br><span class="line"> <span class="number">53</span>: goto <span class="number">57</span></span><br><span class="line"> <span class="number">56</span>: iconst_0</span><br><span class="line"> <span class="number">57</span>: istore <span class="number">8</span></span><br><span class="line"> <span class="number">59</span>: aload_1</span><br><span class="line"> 60: invokevirtual #5 // Method java/lang/Integer.intValue:()I</span><br><span class="line"> <span class="number">63</span>: iload <span class="number">4</span></span><br><span class="line"> <span class="number">65</span>: if_icmpne <span class="number">72</span></span><br><span class="line"> <span class="number">68</span>: iconst_1</span><br><span class="line"> <span class="number">69</span>: goto <span class="number">73</span></span><br><span class="line"> <span class="number">72</span>: iconst_0</span><br><span class="line"> <span class="number">73</span>: istore <span class="number">9</span></span><br><span class="line"> <span class="number">75</span>: aload_2</span><br><span class="line"> 76: invokevirtual #5 // Method java/lang/Integer.intValue:()I</span><br><span class="line"> <span class="number">79</span>: iload <span class="number">5</span></span><br><span class="line"> <span class="number">81</span>: if_icmpne <span class="number">88</span></span><br><span class="line"> <span class="number">84</span>: iconst_1</span><br><span class="line"> <span class="number">85</span>: goto <span class="number">89</span></span><br><span class="line"> <span class="number">88</span>: iconst_0</span><br><span class="line"> <span class="number">89</span>: istore <span class="number">10</span></span><br><span class="line"> <span class="number">91</span>: aload_2</span><br><span class="line"> <span class="number">92</span>: aload <span class="number">6</span></span><br><span class="line"> <span class="number">94</span>: if_acmpne <span class="number">101</span></span><br><span class="line"> <span class="number">97</span>: iconst_1</span><br><span class="line"> <span class="number">98</span>: goto <span class="number">102</span></span><br><span class="line"> <span class="number">101</span>: iconst_0</span><br><span class="line"> <span class="number">102</span>: istore <span class="number">11</span></span><br><span class="line"> <span class="number">104</span>: aload_1</span><br><span class="line"> <span class="number">105</span>: aload <span class="number">7</span></span><br><span class="line"> <span class="number">107</span>: if_acmpne <span class="number">114</span></span><br><span class="line"> <span class="number">110</span>: iconst_1</span><br><span class="line"> <span class="number">111</span>: goto <span class="number">115</span></span><br><span class="line"> <span class="number">114</span>: iconst_0</span><br><span class="line"> <span class="number">115</span>: istore <span class="number">12</span></span><br></pre></td></tr></table></figure></p>
<p>查看编译初始化情况:<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Integer integer127 = <span class="number">127</span>;</span><br><span class="line">Integer integer128 = <span class="number">128</span>;</span><br></pre></td></tr></table></figure></p>
<p>其均是调用<code>java/lang/Integer.valueOf</code>方法构建,<code>valueOf</code>代码如下:<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Integer <span class="title">valueOf</span><span class="params">(<span class="keyword">int</span> i)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (i >= IntegerCache.low && i <= IntegerCache.high)</span><br><span class="line"> <span class="keyword">return</span> IntegerCache.cache[i + (-IntegerCache.low)];</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> Integer(i);</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p><code>IntegerCache</code>是什么东东,直接贴代码:<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">static</span> <span class="class"><span class="keyword">class</span> <span class="title">IntegerCache</span> </span>{</span><br><span class="line"> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> low = -<span class="number">128</span>;</span><br><span class="line"> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> high;</span><br><span class="line"> <span class="keyword">static</span> <span class="keyword">final</span> Integer cache[];</span><br><span class="line"></span><br><span class="line"> <span class="keyword">static</span> {</span><br><span class="line"> <span class="comment">// high value may be configured by property</span></span><br><span class="line"> <span class="keyword">int</span> h = <span class="number">127</span>;</span><br><span class="line"> String integerCacheHighPropValue =</span><br><span class="line"> sun.misc.VM.getSavedProperty(<span class="string">"java.lang.Integer.IntegerCache.high"</span>);</span><br><span class="line"> <span class="keyword">if</span> (integerCacheHighPropValue != <span class="keyword">null</span>) {</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="keyword">int</span> i = parseInt(integerCacheHighPropValue);</span><br><span class="line"> i = Math.max(i, <span class="number">127</span>);</span><br><span class="line"> <span class="comment">// Maximum array size is Integer.MAX_VALUE</span></span><br><span class="line"> h = Math.min(i, Integer.MAX_VALUE - (-low) -<span class="number">1</span>);</span><br><span class="line"> } <span class="keyword">catch</span>( NumberFormatException nfe) {</span><br><span class="line"> <span class="comment">// If the property cannot be parsed into an int, ignore it.</span></span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> high = h;</span><br><span class="line"></span><br><span class="line"> cache = <span class="keyword">new</span> Integer[(high - low) + <span class="number">1</span>];</span><br><span class="line"> <span class="keyword">int</span> j = low;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> k = <span class="number">0</span>; k < cache.length; k++)</span><br><span class="line"> cache[k] = <span class="keyword">new</span> Integer(j++);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// range [-128, 127] must be interned (JLS7 5.1.7)</span></span><br><span class="line"> <span class="keyword">assert</span> IntegerCache.high >= <span class="number">127</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">private</span> <span class="title">IntegerCache</span><span class="params">()</span> </span>{}</span><br><span class="line"> }</span><br></pre></td></tr></table></figure></p>
<p>概括来说就是在JVM初始化的时候会默认生成一个value值在[-128,127]之间的一个Integer对象Cache。<br>在调用<code>valueOf</code>的时候会先去<code>Cache</code>中查找,若存在,则直接返回对应对象,若不存在则重新new一个对象。<br>而<code>new Integer(127)</code>则是调用了Integer的构造函数进行初始化。 </p>
<h3 id="分析Compare值"><a href="#分析Compare值" class="headerlink" title="分析Compare值"></a>分析Compare值</h3><p>1、<code>compareA</code>查看比那一过程,其主要是通过使用<code>if_acmpne</code>进行比较,该指令主要是比较地址块是否相同。由于两个是不同的地址快,所以返回为<code>false</code>。<br>2、<code>cmopareB</code>,在比较之前<code>integer127</code>首先调用了<code>java/lang/Integer.valueOf</code>来获取对应int值,因为int是基本数据类型,所以在地址块比较中,两者是相同的。<br>3、<code>compareC</code>与 序号2相同<br>4、<code>compareD</code>由于初始化时,128超过了cache范围,所以使用<code>Integer xx = 128</code>均会生成一个新的Integer对象。比较他们的地址块,不相同,所以范围为<code>false</code><br>5、<code>compareE</code>初始化值为127时,每次都是会返回cache中的同一个对象,所以在比较地址时会返回<code>true</code>. </p>
<h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><ol>
<li>在对象比较中还是最好使用equal。 </li>
<li>Integer会初始化[-128,127]中的所有Integer对象,用于今后调用。 </li>
</ol>
</div>
<footer class="article-footer">
<a data-url="http://yoursite.com/2019/04/01/JAVA-Integer/" data-id="cjtzk000o0000jejxg4ea8zms" class="article-share-link">Share</a>
<ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Java-Foundation/">Java Foundation</a></li></ul>
</footer>
</div>
</article>
<article id="post-Jetty-Jersey-Guice-with-cross-origin" class="article article-type-post" itemscope itemprop="blogPost">
<div class="article-meta">
<a href="/2018/06/03/Jetty-Jersey-Guice-with-cross-origin/" class="article-date">
<time datetime="2018-06-04T03:04:51.000Z" itemprop="datePublished">2018-06-04</time>
</a>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2018/06/03/Jetty-Jersey-Guice-with-cross-origin/">Jetty Jersey Guice with cross origin</a>
</h1>
</header>
<div class="article-entry" itemprop="articleBody">
<h1 id="Jetty-Request-URL-跨域问题"><a href="#Jetty-Request-URL-跨域问题" class="headerlink" title="Jetty Request URL 跨域问题"></a>Jetty Request URL 跨域问题</h1><h2 id="跨域问题的原因"><a href="#跨域问题的原因" class="headerlink" title="跨域问题的原因"></a>跨域问题的原因</h2><p>跨域是指a页面想获取b页面资源,如果a、b页面的协议、域名、端口、子域名不同,或是a页面为ip地址,b页面为域名地址,所进行的访问行动都是跨域的,而浏览器为了安全问题一般都限制了跨域访问,也就是不允许跨域请求资源。<br>该部分内容可以参考 <a href="https://blog.csdn.net/qq_31617637/article/details/72955239" target="_blank" rel="noopener">连接</a></p>
<h2 id="跨域问题jetty静态资源解决办法"><a href="#跨域问题jetty静态资源解决办法" class="headerlink" title="跨域问题jetty静态资源解决办法"></a>跨域问题jetty静态资源解决办法</h2><p>使用jetty静态资源跨域主要是解决加载js、css等资源的跨越问题。<br>解决类似问题可以为servlet增加一个Filter。简单的filter代码如下:<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">CrossOriginFilter</span> <span class="keyword">implements</span> <span class="title">Filter</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">init</span><span class="params">(FilterConfig filterConfig)</span> <span class="keyword">throws</span> ServletException </span>{</span><br><span class="line"> }</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">doFilter</span><span class="params">(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)</span> <span class="keyword">throws</span> IOException, ServletException </span>{</span><br><span class="line"> <span class="comment">// 必须的</span></span><br><span class="line"> HttpServletResponse response = (HttpServletResponse) servletResponse;</span><br><span class="line"> response.setHeader(<span class="string">"Access-Control-Allow-Origin"</span>, <span class="string">"*"</span>);</span><br><span class="line"> filterChain.doFilter(servletRequest, response);</span><br><span class="line"> }</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">destroy</span><span class="params">()</span> </span>{</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>类似方法也可以使用jetty-servlets.jar中的CrossOriginFilter。<code>web.xml</code>配置文件如下:<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">web-app</span> <span class="attr">...</span>></span></span><br><span class="line"> ...</span><br><span class="line"> <span class="tag"><<span class="name">filter</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">filter-name</span>></span>cross-origin<span class="tag"></<span class="name">filter-name</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">filter-class</span>></span>org.eclipse.jetty.servlets.CrossOriginFilter<span class="tag"></<span class="name">filter-class</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">filter</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">filter-mapping</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">filter-name</span>></span>cross-origin<span class="tag"></<span class="name">filter-name</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">url-pattern</span>></span>/cometd/*<span class="tag"></<span class="name">url-pattern</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">filter-mapping</span>></span></span><br><span class="line"> ...</span><br><span class="line"> <span class="tag"></<span class="name">web-app</span>></span></span><br></pre></td></tr></table></figure></p>
<p>注意,maven使用的dependency为<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">dependency</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">groupId</span>></span>org.eclipse.jetty<span class="tag"></<span class="name">groupId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">artifactId</span>></span>jetty-servlets<span class="tag"></<span class="name">artifactId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">version</span>></span>${jetty.version}<span class="tag"></<span class="name">version</span>></span></span><br><span class="line"><span class="tag"></<span class="name">dependency</span>></span></span><br></pre></td></tr></table></figure></p>
<p>可以看到如图<br><img src="/2018/06/03/Jetty-Jersey-Guice-with-cross-origin/20180604113414.png" alt="response结果"></p>
<h2 id="跨域问题jersey请求解决办法"><a href="#跨域问题jersey请求解决办法" class="headerlink" title="跨域问题jersey请求解决办法"></a>跨域问题jersey请求解决办法</h2><p>我使用的Guice与jersey相结合,要使通过jersey的请求能够带上对应的Response内容,需要在JerseyServletModule中增加对应的Filter。<br>代码如下:<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">bind(CrossOriginFilter.class).in(Singleton.class);</span><br><span class="line">filter(<span class="string">"/*"</span>).through(CrossOriginFilter.class);</span><br></pre></td></tr></table></figure></p>
<p>访问后获取response即可获取。<br>亲测无问题。<br>附上github example地址<a href="https://github.com/ddmonk/jetty-jesery-guice" target="_blank" rel="noopener">jetty+jesery+guice example</a></p>
</div>
<footer class="article-footer">
<a data-url="http://yoursite.com/2018/06/03/Jetty-Jersey-Guice-with-cross-origin/" data-id="cjtzk00150003jejxlshpe2g9" class="article-share-link">Share</a>
<ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/jetty-web/">jetty web</a></li></ul>
</footer>
</div>
</article>
<article id="post-Kafka-producer-startup" class="article article-type-post" itemscope itemprop="blogPost">
<div class="article-meta">
<a href="/2017/04/04/Kafka-producer-startup/" class="article-date">
<time datetime="2017-04-05T03:52:11.000Z" itemprop="datePublished">2017-04-05</time>
</a>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2017/04/04/Kafka-producer-startup/">Kafka producer startup</a>
</h1>
</header>
<div class="article-entry" itemprop="articleBody">
<h1 id="KAFKA-producer-启动过程解释"><a href="#KAFKA-producer-启动过程解释" class="headerlink" title="KAFKA producer 启动过程解释"></a>KAFKA producer 启动过程解释</h1><p>kafka producer为kafka消息的生产者,主要</p>
</div>
<footer class="article-footer">
<a data-url="http://yoursite.com/2017/04/04/Kafka-producer-startup/" data-id="cjtzk00100001jejxn9nqvyhz" class="article-share-link">Share</a>
<ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/kafka学习/">kafka学习</a></li></ul>
</footer>
</div>
</article>
<article id="post-Kafka-topic-leader-1-or-leader-none" class="article article-type-post" itemscope itemprop="blogPost">
<div class="article-meta">
<a href="/2016/03/01/Kafka-topic-leader-1-or-leader-none/" class="article-date">
<time datetime="2016-03-01T14:08:55.000Z" itemprop="datePublished">2016-03-01</time>
</a>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2016/03/01/Kafka-topic-leader-1-or-leader-none/">Kafka topic leader = -1 or leader = none</a>
</h1>
</header>
<div class="article-entry" itemprop="articleBody">
<h1 id="Kafka-topic-查询leader为-1"><a href="#Kafka-topic-查询leader为-1" class="headerlink" title="Kafka topic 查询leader为-1"></a>Kafka topic 查询leader为-1</h1><h2 id="问题原因"><a href="#问题原因" class="headerlink" title="问题原因"></a>问题原因</h2><p>该问题的主要原因是在创建topic时,该partition的所有Replica都宕机了,Leader会自动设置为-1.</p>
<h2 id="解决方法"><a href="#解决方法" class="headerlink" title="解决方法"></a>解决方法</h2><ol>
<li>查看Kafka配置文件 <code>/config/server.properties</code><br>添加如下配置</li>
</ol>
<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">auto.leader.rebalance.enable=true</span></span><br></pre></td></tr></table></figure>
<ol start="2">
<li>重启kafka的broker:<br>进入kafka的bin目录</li>
</ol>
<pre><code class="SHELL"><span class="meta">></span><span class="bash"> nohup ./kafka-server-start.sh ../config/server.properties &</span>
</code></pre>
</div>
<footer class="article-footer">
<a data-url="http://yoursite.com/2016/03/01/Kafka-topic-leader-1-or-leader-none/" data-id="cjtzk001o000cjejxlhcf8jno" class="article-share-link">Share</a>
<ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Kafka学习/">Kafka学习</a></li></ul>
</footer>
</div>
</article>
<article id="post-JPA缓存类型" class="article article-type-post" itemscope itemprop="blogPost">
<div class="article-meta">
<a href="/2016/02/18/JPA缓存类型/" class="article-date">
<time datetime="2016-02-18T15:26:55.000Z" itemprop="datePublished">2016-02-18</time>
</a>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2016/02/18/JPA缓存类型/">JPA缓存类型</a>
</h1>
</header>
<div class="article-entry" itemprop="articleBody">
<h1 id="JPA缓存类型与原理"><a href="#JPA缓存类型与原理" class="headerlink" title="JPA缓存类型与原理"></a>JPA缓存类型与原理</h1><h2 id="JPA缓存简介"><a href="#JPA缓存简介" class="headerlink" title="JPA缓存简介"></a>JPA缓存简介</h2><p>缓存在一个对象的持久化过程中可以缓存对象或者它的数据。缓存同样影响着对象的一致性,如果你查找了一个对象,之后你查找了一个相同的对象,就会返回与刚才一致的对象(其指向的内存单元相同)<br>JPA 1.0 没有定义共享对象的缓存,其共享对象的缓存主要是有供应商自行提供。在JPA中,缓存主要存在于transaction或者扩展的持久化上下文来保护对象的一致性,但是JPA不必一定要在transaction或者持久化上下文中开启缓存。<br>JPA 2.0 定义了一个共享缓存。通过注解的形式 @Cacheable或者cacheable XML 属性的形式来开启或者停止缓存对象。<br>例如:</p>
<blockquote>
<p>Example JAP 2.0 :</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Entity</span></span><br><span class="line"><span class="meta">@Cacheable</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Employee</span></span>{</span><br><span class="line"> ...</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>同样的,你可以在jpa的persistence.xml文件中以添加属性的方式来配置全部持久化单元的缓存模式,<br>例如:</p>
<blockquote>
<p>Example JAP 2.0 SharedCacheMode XML</p>
</blockquote>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">prsistence-unit</span> <span class="attr">name</span>=<span class="string">"GG"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">shared-cache-mode</span>></span>NONE<span class="tag"></<span class="name">shared-cache-mode</span>></span></span><br><span class="line"><span class="tag"></<span class="name">prsistence-unit</span>></span></span><br></pre></td></tr></table></figure>
<h3 id="对象一致性"><a href="#对象一致性" class="headerlink" title="对象一致性"></a>对象一致性</h3><p>对象一直性在java中的含义是:如果两个值x,y他们指向同一个逻辑单元,那么x和y相等。及指正指向相同的内存单元。<br>在JPA中,对象的一致维持在一个<code>transaction</code>,相同的<code>EntityManager</code>中。在JEE中,对象一致性只在同一个<code>transaction</code>中维持。</p>
<blockquote>
<p>所以如下实例返回值为<code>true</code>:</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Employee employee1 = entityManager.find(Employee.class,<span class="number">123</span>);</span><br><span class="line">Employee employee2 = entityManager.find(Employee.class,<span class="number">123</span>);</span><br><span class="line"><span class="keyword">assert</span> (employee1 == employee2 );</span><br></pre></td></tr></table></figure>
<p>该值一直为<code>true</code>无论该值是如何获取的</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Employee employee1 = entityManager.find(Employee.class, <span class="number">123</span>);</span><br><span class="line">Employee employee2 = employee1.getManagedEmployees().get(<span class="number">0</span>).getManager();</span><br><span class="line"><span class="keyword">assert</span> (employee1 == employee2)</span><br></pre></td></tr></table></figure>
<p>在jpa中,对象一致性不会再不同的<code>EntityManager</code>中维持,每个<code>EntityManager</code>维持自己的持久化上下文和自己对象的transactional状态。<br>所以</p>
<blockquote>
<p>如下的代码返回值为<code>true</code></p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">EntityManager entityManager1 = factory.createEntityManager();</span><br><span class="line">EntityManager entityManager2 = factory.createEntityManager();</span><br><span class="line">Employee employee1 = entityManager1.find(Employee.class, <span class="number">123</span>);</span><br><span class="line">Employee employee2 = entityManager2.find(Enployee.class, <span class="number">123</span>);</span><br><span class="line"><span class="keyword">assert</span>(employee1 != employee2);</span><br></pre></td></tr></table></figure>
<p>对象一致性是jpa的有点,他可以避免在应用程序中管理多个对象副本,并且可以避免当一个对象改变后其他副本不变。由于不同的<code>EntityManager</code>或者<code>transactions</code>(在JEE中)不能维持对象的唯一性,所以,每个<code>transaction</code>在其他用户的系统中必须相互隔离。无论如何,我们必须知道应用程序是拷贝、分离或者是合并对象。<br>一些JPA产品可能含有只读对象的概念,对象的一致性通过共享对象缓存中的<code>EntityManager</code>维系。</p>
<h3 id="对象缓存"><a href="#对象缓存" class="headerlink" title="对象缓存"></a>对象缓存</h3><p>一个对象缓存就是缓存JAVA对象。对象缓存的优点是将对象按照其在java中的格式进行存储。所有属性都存放在对象层,当缓存命中后,无需做任何的转换。在<code>EntityManager</code>从cache拷贝或者塞入cache的时候,必须要保证他的<code>tarnsaction</code>的独立性。对象不需要被重新创建,他们之间的关联关系已经是有价值的了。<br>暂时数据可以通过对象缓存存储。他可以自动进行也可以指定。如果暂时数据是不需要的,你也必须在获取该对象的缓存时将其清除。<br>一些JPA提供商运行只读的查询来直接获取对象的缓存。一些提供商值运行对象缓存只读信息。如果只是查找,使用对象缓存可以大大的提高查找效率。<br>你也可以通过自制的缓存系统来缓存你的只读数据。<br>TopLink/EclipseLink:支持对象缓存。该对象缓存是默认的,但是可以设置全局或者有选择的开启或停止。在persisitenc unit属性中的<code>eclipselink.cache.shared.default</code>可以设置为<code>false</code>来停止缓存。只读查询语句可以通过在查询语句中使用提示<code>eclipselink.read-only</code>来标注。Entity中可以通过标注<code>@ReadOnly</code>来标注只读。</p>
<h3 id="数据缓存"><a href="#数据缓存" class="headerlink" title="数据缓存"></a>数据缓存</h3><p>数据缓存缓存对象的数据而非对象。该数据为该对象在数据库中的一行数据。数据缓存操作简单,并且你无需担心对象关系,数据一致性或者缓存管理。 数据缓存的缺点是当应用程序使用该数据时,其并不存储,且并不存放关联。这意味着,在内存中命中了对象,也需要从数据库中查找数据和其关联。一些提供商提供了数据缓存、关系缓存和查询缓存来满足缓存数据间的关系。</p>
<h4 id="缓存关联"><a href="#缓存关联" class="headerlink" title="缓存关联"></a>缓存关联</h4><p>一些提供商支持一些分离的缓存来存放关联关系,这些支持<code>OneToMany</code>和<code>ManyToMany</code>关联关系。由于<code>OneToOne</code>和 <code>ManyToOne</code>关联关系会涉及到对象的<code>Id</code>,通常是不需要被缓存的,但是一个反向的<code>OneToOne</code>由于它涉及到的不是主键而是外键,所以需要将该关联关系缓存起来。<br>关联缓存的缓存结果通常只缓存关联对象的<code>Id</code>而非对象或者数据。关联缓存主要存放资源对象的<code>Id</code>和关系的名称。有时,如果数据存储存放的数据结果而非数据行时,关联关系被作为数据缓存的一部分。当关联缓存被命中了,相关的对象将会在数据缓存中一个个的被查找出来。但是,如果相关对象不在数据缓存中,那么它将必须在所选的数据库中查找,这将会严重影响数据库的效率,因为它需要一个一个的读取数据。</p>
<h3 id="缓存类型"><a href="#缓存类型" class="headerlink" title="缓存类型"></a>缓存类型</h3><p>有很多不同的缓存类型。最常见的是LRU和MRU。<br>一些cache类型包括如下:</p>
<ul>
<li>LRU :在内存中保留N个最近使用的对象</li>
<li>FULL:永远存放所有读到的内容。</li>
<li>Soft:当内存很低时,使用JAVA垃圾收集机制来提示缓存释放对象</li>
<li>Weak:与对象缓存相关,在缓存中存放所有当前使用的对象</li>
<li>L1 :涉及到事务缓存(事务缓存是<code>EntityManager</code>的一部分,并非共享缓存)</li>
<li>L2 : 为共享缓存,概念上的存放在<code>EntityManagerFactory</code>,它控制所有的<code>EntityManager</code></li>
<li>数据缓存 : 数据行存储</li>
<li>对象缓存 : 直接缓存对象</li>
<li>关联关系缓存:缓存对象的关联关系</li>
<li>查询缓存: 缓存一个查询语句的结果集合</li>
<li>只读 :缓存只存放只读对象</li>
<li>读写 :缓存可以处理插入、更新和删除</li>
<li>事务 :缓存可以处理插入、更新和删除,并且满足事务的ACID</li>
<li>集群 :当一个对象更新或者删除后,使用JMS、JGroups或者其他的机制来向其他集群中的服务广播失效信息。</li>
<li>副本 :当一个对象读入任何一个服务缓存中时,使用JMS、JGroups或者其他的机制来通知所有服务器</li>
<li>分布式:通过集群,快速的传播缓存对象,并且可以在另外的服务器缓存中查到该对象。</li>
</ul>
<p>TopLink/EclipseLink:支持L1、L2、LRU、Soft、Full、Weak、查询缓存。对象缓存支持读写的和事务。同时通过JMS和RMI支持集群缓存。</p>
<h3 id="查询缓存"><a href="#查询缓存" class="headerlink" title="查询缓存"></a>查询缓存</h3><p>查询缓存缓存查询结果而非对象。对象缓存通过缓存对象的<code>Id</code>,所以对于查询不是用<code>Id</code>作为查询条件的查询操作并不有效。一些对象存储支持二级索引,但是即使如此对于一些返回大量对象的查询操作,这仍然不是很有效。你必须通过数据库来确保你获取了所有对象。这就是为什么查询缓存是非常有用的而不仅仅通过存放对象的<code>Id</code>,查询结果需要被缓存。缓存的key是基于查询名称和变量。所以如果你有<code>NamedQuery</code>一直执行,你可以缓存他的结果,而且你只要执行查询语句一次即可。<br>查询缓存的主要问题是,它会缓存旧数据。查询缓存通常会与对象缓存相互作用来确保对象在对象缓存中是否过时。查询缓存有一些无效选项,这个对象缓存很像。<br>TopLink / EclipseLink:通过在查询操作中暗示 <code>eclipselink.query-results-cache</code>来开启。</p>
<h3 id="旧数据"><a href="#旧数据" class="headerlink" title="旧数据"></a>旧数据</h3><p>!!缓存的主要问题是如何同步原始数据(The main issue with caching anything is the possibility of the cache version getting out of synch with the original. )!!。这涉及到作为旧数据或者不同步的数据。对于只读数据,这不存在问题,但是对于频繁进行数据改变的,这可能是一个主要问题。这里有很多方式来处理旧数据和未同步数据。</p>
<h4 id="一级缓存"><a href="#一级缓存" class="headerlink" title="一级缓存"></a>一级缓存</h4><p>在事务过程中或者请求中缓存对象的状态并不是一个问题。这通常称为一级缓存,或者说是<code>EntityManager</code>缓存,并且通过正确的JPA事务语义完成。如果你读同一对象两次,你必须获取同一对象,和相同的内存改变。问题仅仅发生在查询和DML过程中。</p>
<p>通过数据库查询,查询不会引入未写入的对象的状态。例如,你要持久化一个新的对象,但是JP还没有将该对象存入数据库,因为它只会在事务提交的时候才会写入数据库。所以你的查询将无法返回一个新的对象,因为他查找的是数据库而非一级缓存中。对于这个问题,用户可以调用<code>flush()</code>操作或者<code>flushMode</code>自动触发刷新操作。在<code>EntityManager</code>或者<code>Query</code>的<code>flushMode</code>的默认情况是要触发一个刷新操作,但是当一个写操作在查询操作还没有释放时,该操作会无法触发刷新。一些JPA提供商支持当对象在内存中更改了后,JPA确认数据库查询结果。这可以直接获取数据而不是要触发刷新操作。这可以对简单的查询操作起作用,但是对于复杂的查询,这将会大大提高查询的复杂程度。由于应用程序查询数据都是在更改数据之前,或者不需要查询已有对象,所有这并不是一个问题。<br>如果你绕过JPA执行DML直接操作数据库,或者通过原生的SQL查询,JDBC或者JPQL<code>UPDATE</code>或者<code>DELETE</code>查询,那么数据库可能会与一级缓存不同步。如果你在执行DML之前已经获取了对象,他们会有一个旧的状态并且不会包括改变的信息。确保你做的操作是正确的,否则你可能必须重新刷新受影响的数据。</p>
<p>一级缓存,或者<code>EntityManager</code>缓存在JPA中可以跨越事务的界限。一个JTA管理<code>EntityManager</code>将只要存在于该JTA事务在JEE中的整个过程。JEE服务将会将应用的代理注入进一个<code>EntityManager</code>,当开启一个JTA事务时,一个新的<code>EntityManager</code>将会被创建,或者被清楚。一级缓存在一个<code>EntityManager</code>创建使用过程中一直存在,如果一直长时间的维持它,它可能会含有旧数据,甚至是内存漏洞和低效。在每个请求时创建一个新的<code>EntityManager</code>是一个很好的主意。一级缓存同样可以用<code>EntityManager.clear()</code>方法或者调用<code>EntityManager.reflush()</code>方法来实现清空的操作。</p>
<h4 id="二级缓存"><a href="#二级缓存" class="headerlink" title="二级缓存"></a>二级缓存</h4><p>二级缓存包括了事务,<code>EntityManager</code>,他不是JPA必要的一部分。大多数JPA提供商支持二级缓存,但是实施和使用的语法上有一些不同。一些JPA提供商默认开启二级缓存。<br>如果系统只是一个提供访问数据库的应用程序或者服务,那么在使用二级缓存过程中问题不大。因为他应该经常会更新。但是主要的问题是在使用DML,如果应用直接通过原生SQL语句,JDBC,或者JPQL1的<code>UPDATE</code>或者<code>DELETE</code>语句。JPQL查询会自动使二级缓存数据无效,但是这可能需要基于JPA的提供商。如果你使用了原生的DML查询或者直接用JDBC,你需要通过刷新、清除或者其他方式使受影响的数据无效。<br>如果还有其他应用或者应用服务访问相同数据库,那么旧数据将会成为一个大问题。只读对象或者插入新对象不会发生问题。新对象一硬格从其他服务通过缓存数据来访问数据库而得到。这通常只使用<code>find()</code>操作和关联命中缓存。其他应用或者服务更新和删除对象会使数据成为旧数据。<br>由于更新对象,任何查询该对象的操作都可能返回旧的数据。在更新对象过程中或者由于一个用户在未使用锁的情况下,覆盖了另一个用户的更改信息这都会触发乐观锁。当然如果只有一个应用或者服务访问数据库,在不使用缓存的情况下也是可能发生的。这就是使用乐观锁的重要意义。当然,旧数据也肯能使用户获取到。</p>
<h4 id="刷新"><a href="#刷新" class="headerlink" title="刷新"></a>刷新</h4><p>刷新是最常用的更新旧数据的方法。大多数应用软件用户很数据缓存的概念,并且知道何时他们需要刷新数据,并且乐于点击刷新按钮。这个在浏览器非常常见,大多数浏览器有其访问网页的缓存,从而避免加载同一界面两次,除非用户点击刷新按钮。相同的理论也可以在构建JPA应用时使用。JPA提供商有很多刷新操作。<br>一些JPA提供商在二级缓存上支持刷新选项。一个选项是在任何查询数据操作后都刷新。这意味着<code>find()</code>操作将仍然通过缓存。但是如果查询数据库或者获取数据库数据,二级缓存将会刷新数据。这避免了查询旧数据。但是这也使缓存失去了意义。刷新的代价不光光是刷新对象还要刷新他们的关联关系。一些JPA提供商提供了该属性整合乐观锁。如果该数据在数据库行中的值比在缓存中的版本值新,那么他会刷新旧数据,否则缓存值将会被返回。这个属性提供了优化的缓存,从而避免查询到旧数据。然而通过<code>find()</code>或者通过关联获取的数据任然是旧值。一些JPA提供商也允许<code>find()</code>操作可配置成首先核对数据库,但是这违背了cache的目的。</p>
<h4 id="JPA-2-0-内存-API"><a href="#JPA-2-0-内存-API" class="headerlink" title="JPA 2.0 内存 API"></a>JPA 2.0 内存 API</h4><p>JPA 2.0提供了一组标准的查询提示来刷新或者忽略cache。这些查询提示在CacheRetrieveMode和CacheStoreMode定义。<br>Query hints:</p>
<ul>
<li><code>javax.persistence.cache.retrieveMode</code> : <code>CacheRetrieveMode</code> <ul>
<li><code>BYPASS</code> : 忽略缓存,直接从数据库中获取内容</li>
<li><code>USE</code> : 允许使用cache,如果对象/数据已经在cache中,则使用在cache中的数据</li>
</ul>
</li>
<li><code>javax.persistence.cache.storeMode</code> : <code>CacheStoreMode</code> <ul>
<li><code>BYPASS</code> : 不缓存数据库的查询结果</li>
<li><code>REFRESH</code> : 如果对象/数据已经存在于cache中,用数据库中查询结果刷新/代替这些数据。</li>
<li><code>USE</code> :缓存查询的结果</li>
</ul>
</li>
</ul>
<h5 id="缓存设置实例"><a href="#缓存设置实例" class="headerlink" title="缓存设置实例"></a>缓存设置实例</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">Query query = em.createQuery(<span class="string">"Select e from Employee e"</span>);</span><br><span class="line">query.setHint(<span class="string">"javax.persistence.cache.storeMode"</span>,CacheStoreMode.REFRESH);</span><br></pre></td></tr></table></figure>
<p>JPA2.0也提供了Cache接口,用户可以利用<code>EntityManagerFactory</code>的<code>getCache()</code>方法得到<code>Cache</code>接口。该<code>Cache</code>接口可以用来人工的删除在cache中的实例。<br>无论是一个特殊的实例、一个完整的类或者一个完整的缓存都可以被删除。该接口同时也可以判断该实例是否存在。<br>一些JPA生产厂商或扩展<code>getCache()</code>来提供额外的API。<br>TopLink / EclipseLink : 提供一个额外的缓存接口<code>JpaCache</code>。提供额外的API进行失效、查询缓存、删除缓存操作。</p>
<h5 id="缓存清除实例"><a href="#缓存清除实例" class="headerlink" title="缓存清除实例"></a>缓存清除实例</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Cache cache = factory.getCache();</span><br><span class="line">cache.evict(Employee.class, id);</span><br></pre></td></tr></table></figure>
<h4 id="缓存无效"><a href="#缓存无效" class="headerlink" title="缓存无效"></a>缓存无效</h4><p>常用的使缓存失效的方式是设置其缓存为无效状态。设置一定的时间,一天中特定的次数之后,删除或者是设置其无效。 超时失效保证了应用系统将不会再数据超时之后再从缓存中获取。这个时间可以在应用中设置。用户可以设置每天的失效时间,这可以确保一天的数据是新的。如果一个批处理在晚上更新,这时间可以设置为该作业之后。数据也可以人工的设置失效类似于使用JPA 2.0中的<code>evict()</code>API。<br>大多数内存的实现提供了一些失效的方式。JPA没有定义任何失效的配置参数,所有这些配置参数都是基于JPA和cache的提供商。<br>TopLink / EclipseLink :通过使用@Cache标注和orm.xml中的<code><cache></code>元素提供对失效时间的设置。失效时间也可以通过API来设置,也可用于集群中设置。</p>
<h4 id="集群中的缓存"><a href="#集群中的缓存" class="headerlink" title="集群中的缓存"></a>集群中的缓存</h4><p>在集群,各个机器将会直接更新数据库而不是更新其他机器的缓存,每个机器的cache很容易过期,所以在集群中缓存是很困难的。但是这并不意味这在集群中无法使用缓存,你必须认真的配置它的参数。<br>对于只读对象的缓存可以一直使用。对于查看大多数对象可以使用缓存,但是一些场景需要避免使用旧数据。如果旧数据只是在写操作过程中存在问题,可以使用乐观锁来避免发生旧数据的写入。当乐观锁的异常发生,一些JPA提供商会自动更新或者使当前数据在cache中失效。所有如果用户或者应用再次执行该事务时,写操作的时候将会成功。你的应用也可以捕获锁异常并且刷新或者使该对象失效,或者潜在的重试该事务(如果用户不需要关注锁错误)。缓存失效可以通过设置数据在缓存中的存活时间来减少旧数据的可能性。缓存的大小也影响旧数据。<br>虽然对于用户,返回旧数据是一个问题,但是当用户刚刚更新后,返回值为旧数据是一个更大的问题。这个可以通过设置session affinity来避免。但是必须确保用户在他们session过程中是和集群中的同一台机器做操作的。通常的操作是在页面上增加一个刷新按钮,这可以允许用户手动刷新。这些应用可以选择在更新重要数据之后进行刷新对象操作,类似的如在执行更新操作时使用只读的查询。<br>对于以写操作为主的对象,禁止那些对象的缓存是最好的解决方法。缓存对插入和更新是没有益处的。缓存操作将会增加很多额外的写操作,因为你必须要更新缓存,还要处理大量的缓存垃圾。所以如果cache没有提供帮助,你应该关闭它。如果对象含有一系列复杂的关系,只有很少一部分需要更新,那么缓存还是很有意义的。</p>
<h5 id="缓存一致性"><a href="#缓存一致性" class="headerlink" title="缓存一致性"></a>缓存一致性</h5><p>解决季军缓存的一个解决方法是通过消息框架在集群中各个机器之间协作。JMS或者JGroups可以与JPA或者应用时间结合,当一个更新发生时,利用广播通知其他机器。一些JPA提供商支持集群环境缓存的协作。<br>TopLink / EclipseLink : 利用JMS或者RMI 支持集群协作。通过使用<code>@Cache</code>注释或者在orm.xml中的<code><cache></code>并且使用持久化单元的属性<code>eclipselink.cache.coordination.protocol</code>完成集群缓存设置。</p>
<h5 id="分布式缓存"><a href="#分布式缓存" class="headerlink" title="分布式缓存"></a>分布式缓存</h5><p>一个分布式缓存是跨机器的缓存。每个对象将会存放在一个或者一批机器上。这可以避免旧数据,因为该缓存是从同一个地方获取更新数据的,所以它的数据始终是最新的。这个解决方法的重点是缓存需要网络通信。该解决方案当所有机器在集群中都相连并且有相同高速的网速,并且数据库服务器也有很好的链接和加载的情况下,该方法是很好的。分布式缓存环节了数据库访问,它可以使应用不受数据库的瓶颈扩展到一个大集群。一些分布式缓存提供商提供了本地缓存,提供缓存间的协调。<br>TopLink : 支持与Oracle Coherence的分布式缓存集成。</p>
<h3 id="缓存事务的独立性"><a href="#缓存事务的独立性" class="headerlink" title="缓存事务的独立性"></a>缓存事务的独立性</h3><p>当使用缓存后,缓存的一致性和独立性就与数据库的事务独立性一样重要。对于基本缓存独立性,缓存的必须在数据库事务已经提交后更新,否者未提交的数据不能被其他用户访问。<br>缓存也可以是透明或者非透明的。在一个透明缓存中,这些从一个事务提交到缓存的变化作为一个简单的原子单元。这就意味这对象/数据必须先在缓存中加锁。当更新缓存后解锁。理性情况下,在事务执行之前获取锁,来确保与数据库中的一致性。非透明缓存在非加锁情况下,一步一步更新对象/数据。这意味着会有短暂一段时间,数据库中的内容和缓存中是数据不一致。这些都需视情况而定。<br>乐观锁定在高速缓存中的隔离的另一个重要的考虑因素。如果使用乐观锁,该缓存应该避免用旧数据替换新数据。当在读取的时候,系统正在更新数据库这种情况下,乐观锁非常重要。<br>一些JPA提供少运行配置他们缓存隔离。或者不同的缓存制定不同的隔离级别。</p>
</div>
<footer class="article-footer">
<a data-url="http://yoursite.com/2016/02/18/JPA缓存类型/" data-id="cjtzk001u000fjejxymitnivb" class="article-share-link">Share</a>
<ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/编程开发/">编程开发</a></li></ul>
</footer>
</div>
</article>
</section>
<aside id="sidebar">
<div class="widget-wrap">
<h3 class="widget-title">Tags</h3>
<div class="widget">
<ul class="tag-list"><li class="tag-list-item"><a class="tag-list-link" href="/tags/Java-Foundation/">Java Foundation</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Kafka学习/">Kafka学习</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/jetty-web/">jetty web</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/kafka学习/">kafka学习</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/编程开发/">编程开发</a><span class="tag-list-count">1</span></li></ul>
</div>
</div>
<div class="widget-wrap">
<h3 class="widget-title">Tag Cloud</h3>
<div class="widget tagcloud">
<a href="/tags/Java-Foundation/" style="font-size: 10px;">Java Foundation</a> <a href="/tags/Kafka学习/" style="font-size: 10px;">Kafka学习</a> <a href="/tags/jetty-web/" style="font-size: 10px;">jetty web</a> <a href="/tags/kafka学习/" style="font-size: 10px;">kafka学习</a> <a href="/tags/编程开发/" style="font-size: 10px;">编程开发</a>
</div>
</div>
<div class="widget-wrap">
<h3 class="widget-title">Archives</h3>
<div class="widget">
<ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/04/">四月 2019</a><span class="archive-list-count">4</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/06/">六月 2018</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/04/">四月 2017</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/03/">三月 2016</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/02/">二月 2016</a><span class="archive-list-count">1</span></li></ul>
</div>
</div>
<div class="widget-wrap">
<h3 class="widget-title">Recents</h3>
<div class="widget">
<ul>
<li>
<a href="/2019/04/02/Linux-mv/">(no title)</a>
</li>
<li>
<a href="/2019/04/02/hello-world/">Hello World</a>
</li>
<li>
<a href="/2019/04/01/test/">test</a>
</li>
<li>
<a href="/2019/04/01/JAVA-Integer/">JAVA Integer</a>
</li>
<li>
<a href="/2018/06/03/Jetty-Jersey-Guice-with-cross-origin/">Jetty Jersey Guice with cross origin</a>
</li>
</ul>
</div>
</div>
</aside>
</div>
<footer id="footer">
<div class="outer">
<div id="footer-info" class="inner">
© 2019 ddmonk<br>
Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>
</div>
</div>
</footer>
</div>
<nav id="mobile-nav">
<a href="/" class="mobile-nav-link">Home</a>
<a href="/archives" class="mobile-nav-link">Archives</a>
</nav>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<link rel="stylesheet" href="/fancybox/jquery.fancybox.css">
<script src="/fancybox/jquery.fancybox.pack.js"></script>
<script src="/js/script.js"></script>
</div>
</body>
</html>