|
2015年1月7日
1. java zip 多個(gè)文件時(shí),如果先添加了一個(gè)excel文件,然后再想添加其他的文件時(shí)會(huì)出現(xiàn) steam is closed的錯(cuò)誤。這是因?yàn)閣ork.write(outputSteam)后,出調(diào)用outputSteam.close(),關(guān)閉輸出流。 解決方法: 將原來(lái)的程序: ZipEntry entry = new ZipEntry( "file3.txt" ); zos.putNextEntry( entry ); workbook.write( zos ); zos.closeEntry(); 改為: ZipEntry entry = new ZipEntry( "file3.txt" ); zos.putNextEntry( entry ); workbook.write( new NonCloseableOutputStream( zos ) ); zos.closeEntry(); 其中 NonCloseableOutputStream 定義如下: public class NonCloseableOutputStream extends java.io.FilterOutputStream { public NonCloseableOutputStream(OutputStream out) { super(out); } @Override public void close() throws IOException { flush(); } } 2. 使用binary使得mysql區(qū)分大小寫(xiě) select * from table1 where binary field1 = 'abc';
https://notepad-plus-plus.org/community/topic/13661/plugin-manager-x64-available-submit-your-plugins
move Git Server to a new IP/URL:
you can just edit .git/config and change the URLs there
也可以在git視圖中,右鍵點(diǎn)擊項(xiàng)目,選擇屬性,然后修改url中的地址
autohotkey listary cmder可以split screen,在一個(gè)窗口中同時(shí)運(yùn)行數(shù)個(gè)cmd
官網(wǎng)地址:autohotkey.com ; fill password ^Numpad2:: Send, root{tab}root{enter} Return ^Numpad3:: IfWinExist, ahk_exe OUTLOOK.EXE { WinActivate ahk_exe OUTLOOK.EXE ; Automatically uses the window found above. ; WinMaximize ; same ;Send, Some text.{Enter} msgbox Outlook is running. } Return
<html> <head> <script src="https://unpkg.com/vue/dist/vue.js"></script> <script> window.onload = function () { var app = new Vue({ el: '#app', data: { message: 'Hello Vue!' } }); } </script> </head>
<body> <div id="app"> {{ message }} </div> </body> </html>
String[] splits=someString.split("a,b,c,d", ","); logger.debug( "array: {}", (Object) splits ); 這里要注意的就是要把數(shù)組的數(shù)據(jù)類(lèi)型強(qiáng)制轉(zhuǎn)換為Object
在windows環(huán)境中,可以用如下方法重置root密碼 1、先停止mysql數(shù)據(jù)庫(kù) 2、保存密碼重置sql文件 5.7.6(包括)以后的版本:ALTER USER 'root'@'localhost' IDENTIFIED BY 'MyNewPass'; 5.7.5(包括)以前的版本:SET PASSWORD FOR 'root'@'localhost' = PASSWORD('MyNewPass'); 假設(shè)保存到文件: c:\reset.txt 3、以管理員身份打開(kāi)命令行窗口,運(yùn)行 C:\> cd "C:\Program Files\MySQL\MySQL Server 5.5\bin" C:\> mysqld --init-file=C:\reset.txt
4、啟動(dòng)后,還不能馬上用新密碼連接數(shù)據(jù)庫(kù),需要重啟mysql數(shù)據(jù)庫(kù)
This is a general step that happens when m2e/m2eclipse (Maven integration for Eclipse) is installed, whether projects are actively using it or not. 這是因?yàn)閙2eclipse(maven插件)要在啟動(dòng)時(shí)需要進(jìn)行的一個(gè)步驟。 This step can be disabled through the Eclipse preferences: Window / Preferences / Maven / "Download repository index updates on startup". This option is on the main "Maven" preference page (not a child page). Just uncheck the box to prevent this from happening. 我們可以停止這個(gè)動(dòng)作。方法:Windows -> Preferences -> Maven 取消勾選 Download repository index updates on startup
有好幾個(gè)java library都可以實(shí)現(xiàn)這個(gè)功能,但是從pdf提取文本的一個(gè)問(wèn)題是,提取出來(lái)的文本沒(méi)有固定的順序,不容易比較好的還原其格式。
我的做法是使用pdfclown來(lái)進(jìn)行這項(xiàng)工作。官方網(wǎng)站是:https://pdfclown.org/ 先下載其最新版本。 參考其示例代碼:https://pdfclown.org/2010/01/02/upcoming-0-0-8-whats-going-to-be-new/#more-30
使用這段代碼,我們不僅可以得到文本的字符串,還能得到文本的頁(yè)數(shù)和相對(duì)坐標(biāo)。 我的思路是先把所有文本的字符串和坐標(biāo)提取出來(lái)。然后排序,排序的順序是縱坐標(biāo),然后橫坐標(biāo)。 這樣排序完畢后,就能比較好的解決文本格式問(wèn)題。
1, 先定義一個(gè)input, 做為datepicker的容器。 <input type='text' class="form-control" id="dateTo" name="dateTo" required/>
2, 在后面加上glyphicon, 注意關(guān)鍵是label 中的for的id需要是前面定義的容器的id, 這樣點(diǎn)擊glyphicon的時(shí)候就會(huì)觸發(fā)彈出日期選擇框。
<label for="dateTo" class="input-group-addon"><span class="glyphicon glyphicon-time"></span></label>
在日志文件中看到這個(gè)錯(cuò)誤信息 Cause: java.sql.SQLException: #HY000
后來(lái)才知道這是因?yàn)閿?shù)據(jù)庫(kù)中有個(gè)別字段要求不能為空, 但是insert語(yǔ)句中沒(méi)有提供數(shù)據(jù),造成了這個(gè)錯(cuò)誤。 關(guān)鍵是錯(cuò)誤信息不明確直觀,不容易知道是這個(gè)原因
public void afterJFinalStart(){ Configuration config = FreeMarkerRender.getConfiguration(); config.setTemplateUpdateDelayMilliseconds( 2 ); config.setAPIBuiltinEnabled( true ); }
中文版地址 https://angular.cn/
1, call ##002# to cancel "call diversion"
2, call 121600, choose option "2" to cancel "Active call catcher"
1. 格式化XML的插件 可以安裝“XML Tools", 安裝完畢后,選擇 插件->XML Tools->Pretty Print(XML Only - with line breaks)
2. 格式化JSON的插件 可以安裝”JSON Viewer", 安裝完畢后,選擇 插件->JSON Viewer->Format JSON
3. 格式化SQL的插件 可以安裝“Poor man's T-Sql Formatter", 選擇 插件->Poor man's T-Sql Formatter->Format T-Sql Code
使用的工具
1. Apache HttpClient 2. Firefox + FireBug 3. Burp Suite ( https://portswigger.net/burp ) + Firefox FoxyProxy
Firefox + FireBug 主要用于查看渲染出的頁(yè)面中的信息(比如:表單項(xiàng)的名稱,節(jié)點(diǎn)ID等等) Burp Suite 主要用于動(dòng)態(tài)攔截頁(yè)面的交互,查看Ajax的調(diào)用。 HttpClient 用于最后程序的編制。搞清楚了網(wǎng)頁(yè)交互的過(guò)程,就可以自主決定程序需要包含的內(nèi)容。 在實(shí)際網(wǎng)頁(yè)中,可能需要點(diǎn)開(kāi)數(shù)級(jí)菜單,才能最后看到需要的內(nèi)容。 但是在程序中,可以直接跳到最后一步。
1. 表格文字右對(duì)齊
<table>
<tr>
<td><p style="text-align:right;margin:0;padding:0">文字右對(duì)齊</p></td>
<td>文字左對(duì)齊</td>
</tr>
</table>
2. 表格邊緣的margin
需要在表格外再套一個(gè)div
<div style="margin:10px"> <table>
...... </table>
</div> 3. btn-toolbar class can put a margin between 2 "pull-right" buttons <div class="row"> <div class="col-md-2"></div> <div class="col-md-8 btn-toolbar"> <input type="submit" class="btn btn-warning pull-right" value="Submit"> <input type="button" id="profilePassBackBtn" class="btn btn-info pull-right" value="Back"> </div> <div class="col-md-2"> </div> </div>
AngularJS 2.0 已經(jīng)發(fā)布了Beta版本,相信正式版不久以后就會(huì)發(fā)布了。
下面是官網(wǎng)上的新功能介紹:
1. 更快更高效。AngularJS 2 將會(huì)比 AnuglarJS 1 快很多。因?yàn)樗鼤?huì)支持:從遠(yuǎn)程胳快速加載、離線編譯以便于更快啟動(dòng)、以及超快的變動(dòng)檢測(cè)和為使?jié)L動(dòng)更平滑的視圖緩存等等。
2. 更加簡(jiǎn)單清晰。語(yǔ)法將會(huì)顯得更加自然,易于編寫(xiě)
3. 跨越平臺(tái)。無(wú)論是臺(tái)式機(jī)、手機(jī)瀏覽器、安卓、IOS平臺(tái),AngularJS都能提供相應(yīng)的支持。
4. 無(wú)縫從 AngularJS 1 升級(jí)到 2
5. 簡(jiǎn)便的開(kāi)發(fā)。支持各種開(kāi)發(fā)語(yǔ)言,ES5, TypeScript, Dart
6. 全面完備的路由。 方便地映射URL到應(yīng)用組件,并提供多種高級(jí)功能,比如:嵌套和鄰接路由,支持卡片棧導(dǎo)航、動(dòng)畫(huà)過(guò)渡、手機(jī)用戶延遲加載等等
7. 依賴注入。
8. 舊瀏覽器的良好支持
9. 動(dòng)畫(huà)效果 (仍在開(kāi)發(fā)中)
10. 國(guó)際化支持(仍在開(kāi)發(fā)中)
- Go to web project properties.
- Deployment Assembly (Left).
- Add > Select project > Select your lib project > Check "Assemble projects into the WEB-INF/lib folder of the web application" if not checked > Finish.
使用酷狗就可以轉(zhuǎn)換。 右鍵點(diǎn)擊歌曲 ,工具,格式轉(zhuǎn)換。 唯一要注意的是要先登錄。
今天把commons dbcp 和 pool都升級(jí)到2.x, 結(jié)果發(fā)現(xiàn)不能正常的工作,卡在new BasicDataSource()上了. 后來(lái)才發(fā)現(xiàn)原因是因?yàn)闆](méi)有加入commons-logging的jar文件 幾個(gè)注意點(diǎn): 1. commons dbcp2.x 和 commons pool需要同時(shí)升到2.x 2. dbcp 2.x要運(yùn)行在java 7以上 3. mysql connector要5.1.11以上 4. 需要有commons-logging的包,我使用的是slf4j, 就需要加一個(gè)jcl-over-slf4j
Error com.jcraft.jsch.JSchException: The cipher 'aes256-cbc' is required, but it is not available. or
Caused by: java.security.InvalidKeyException: Illegal key size
我在網(wǎng)上搜索了一下如何使用Selenium下載文件,其中確實(shí)有幾篇文件介紹了實(shí)現(xiàn)的方法。 但是其主要思想都是使用httpClient或者URL獲得InputStream, 然后保存到文件中。 但是,其中的問(wèn)題是用戶登錄的Session不能維持。
我發(fā)現(xiàn)了一個(gè)簡(jiǎn)單的方法。 直接使用WebDriver.get, 示例如下:
webDriver.get("https://website.com/login"); WebElement element = driver.findElement( By.id( "userID" ) ); element.sendKeys( "user01" );
element = driver.findElement( By.id( "passwd" ) ); element.sendKeys( "password" );
element = driver.findElement( By.name( "Login" ) ); element.submit();
webDriver.get("https://website.cm/download.do?start=xx&end=yy"); String source = webDriver.getPageSource();
這個(gè)source就是我們想保存的要下載的內(nèi)容。 只要把這個(gè)String寫(xiě)到一個(gè)文件中,就實(shí)現(xiàn)了文件下載的目的
摘要: 在我的上一篇文章中介紹了如何進(jìn)行GPG加密解密。
加密解密的基本操作流程是,用戶使用公鑰對(duì)明文進(jìn)行加密,解密方使用私鑰對(duì)密文進(jìn)行解密。
在實(shí)際應(yīng)用中,除了加密保證文本內(nèi)容不泄露外,同時(shí)還要考慮能夠驗(yàn)證密文發(fā)送方的身份,比較普遍使用的方法就是簽名。
本文主要對(duì)具體的方法進(jìn)行介紹并附上源代碼。 閱讀全文
Java程序中訪問(wèn)擁有全部讀寫(xiě)權(quán)限的目錄相對(duì)比較簡(jiǎn)單,和普通的目錄沒(méi)有什么差別。 但是要訪問(wèn)一個(gè)需要用戶和密碼驗(yàn)證的目錄就需要一點(diǎn)點(diǎn)小技巧了。 這里介紹一個(gè)開(kāi)源的庫(kù)能夠比較容易的實(shí)現(xiàn)這一需求。 1。 下載庫(kù)文件: https://jcifs.samba.org/ 下載的zip文件中, 不僅包含了jar文件,還有文檔和示例。 2??截恓cif-1.3.18.jar到類(lèi)路徑中。 3。代碼示例: 1 String user = "your_user_name"; 2 String pass ="your_pass_word"; 3 4 String sharedFolder="shared"; 5 String path="smb://ip_address/"+sharedFolder+"/test.txt"; 6 NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("",user, pass); 7 SmbFile smbFile = new SmbFile(path,auth); 8 SmbFileOutputStream smbfos = new SmbFileOutputStream(smbFile); 9 smbfos.write("testing .and writing to a file".getBytes()); 10 System.out.println("completed nice !"); 說(shuō)明: 如果有一個(gè)共享目錄,比如: \\192.168.1.2\testdir\ 那么smb的路徑就是:smb://192.168.1.2/testdir/ NtlmPasswordAuthentication需要三個(gè)參數(shù), 第一個(gè)是域名,沒(méi)有的話,填null, 第二個(gè)是用戶名,第三個(gè)是密碼
得到SmbFile之后,操作就和java.io.File基本一樣了。 另外還有一些功能比如: SmbFile.copyTo SmbFile.renameTo 等等
先將my.default.ini改名為my.ini放到bin目錄
命令行執(zhí)行: mysqld --initialize --user=mysql --console
先執(zhí)行以上命令, 生成庫(kù). 注意有個(gè)臨時(shí)密碼, 要記下來(lái). 安裝服務(wù):mysqld.exe --install MySql5.7 --defaults-file=c:\mysql\mysql5.7\my.ini
然后啟動(dòng)服務(wù).
然后再命令行: mysql -uroot -p 輸入密碼, 再輸入: set password = password('root') 改密碼成功, 然后就可以操作了.
如果只是在beforeSubmit()中 調(diào)用$('#fieldname').val(2)是不能成功修改表單的值的。 因?yàn)榇藭r(shí)ajaxForm已經(jīng)把表單中所有的內(nèi)容存儲(chǔ)在arr之中了。 $('#form1').ajaxForm({ beforeSubmit: function(arr){ for ( var i = 0; i < arr.length; i ++ ) { if ( arr[i].name == "fieldName1" ) { arr[i].value = '新的值'; } } } }); 需要使用這種方式進(jìn)行修改。
今天在運(yùn)行myeclipse的時(shí)候,突然報(bào)nullPointerException. 具體的錯(cuò)誤信息如下: Message: Errors running builder ‘DeploymentBuilder’ on project XXX’. Exception Stack Trace java.lang.NullPointerException 解決方法: 1. Shut down the workspace. 2. Delete the file com.genuitec.eclipse.ast.deploy.core.prefs which is located at <workspace dir>/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.eclipse.ast.deploy.core.prefs 3. Start the IDE.
ipconfig /flushdns ipconfig /registerdns netsh winsock reset
重新啟動(dòng)電腦。
今天下載了Apache James 3.0 Beta 5, 文件名:james-server-app-3.0.0-beta5-20150627.102412-1076-app.zip 解壓,運(yùn)行run.bat 然后,注冊(cè)domain james-cli --host localhost adddomain example.com 添加用戶 james-cli.bat --host localhost adduser test@example.com password 然后測(cè)試發(fā)送郵件,客戶端顯示發(fā)送成功,但是james服務(wù)器報(bào)錯(cuò),找不到MimeConfig的無(wú)參數(shù)構(gòu)造函數(shù)。 解決方法: 使用舊的mime4j的jar包替換james 3.0 beta5中自帶的最新包。 beta5中自帶的是0.8.0版,apache網(wǎng)站中可以下載到0.7.2 下載apache-mime4j-0.7.2-bin.zip, 將其中的apache-mime4j-core-0.7.2.jar, apache-mime4j-dom-0.7.2.jar復(fù)制到j(luò)ames\lib目錄, 并將其更名覆蓋原有的 apache-mime4j-core-0.8.0-20150617.024907-738.jar apache-mime4j-dom-0.8.0-20150617.024927-735.jar 重新啟動(dòng)james, 發(fā)送郵件, 成功。
摘要: 解壓/生成有密碼保護(hù)的壓縮文件, 研發(fā)過(guò)程中,作者研究了壓縮文件格式文檔: http://www.pkware.com/documents/casestudies/APPNOTE.TXT,并且參考了7-zip的實(shí)現(xiàn)。
閱讀全文
摘要: 花了兩天時(shí)間終于把windows10安裝好了,以下是我的一些個(gè)人的體會(huì)
閱讀全文
在JfinalConfig的繼承類(lèi)中, configConstant() 需要設(shè)置me.setDevMode(true); 1. 只有在DevMode下,才能禁止freeMarker的緩存。 Configuration config = FreeMarkerRender.getConfiguration(); config.setTemplateUpdateDelayMilliseconds(0); 才會(huì)生效
2. 這時(shí)才會(huì)有JFinal Action Report日志輸出
本文將簡(jiǎn)單介紹如何使用PowerMock和Mockito來(lái)mock
1. 構(gòu)造函數(shù)
2. 靜態(tài)函數(shù)
3. 枚舉實(shí)現(xiàn)的單例
4. 選擇參數(shù)值做為函數(shù)的返回值
5. 在調(diào)用mock出來(lái)的方法中,改變方法參數(shù)的值
一點(diǎn)簡(jiǎn)要說(shuō)明:Mockito其實(shí)已經(jīng)可以滿足大部分的需求,但是它的實(shí)現(xiàn)機(jī)制是使用cglib來(lái)動(dòng)態(tài)創(chuàng)建接口的類(lèi)的實(shí)例。但是這種實(shí)現(xiàn)方式不能用于構(gòu)造函數(shù)和靜態(tài)函數(shù),因?yàn)槟切枰褂妙?lèi)的字節(jié)碼(比如使用javassist). 所以我們才需要結(jié)合使用PowerMock.
1. mock構(gòu)造函數(shù), 如果有代碼沒(méi)有使用DI注入依賴實(shí)例,在單元測(cè)試中可以使用PowerMock來(lái)模擬創(chuàng)建對(duì)象。
注意的開(kāi)始兩行的2個(gè)注解 @RunWith 和 @PrepareForTest
@RunWith比較簡(jiǎn)單,后面始終是PowerMockRunner.class
@PrepareForText后面需要加的是調(diào)用構(gòu)造函數(shù)的類(lèi)名,而不是有構(gòu)造函數(shù)的類(lèi)本身。
在下面的例子中,我們要測(cè)試的類(lèi)是:Helper, 在Helper類(lèi)中調(diào)用了Somthing類(lèi)的構(gòu)造函數(shù)來(lái)創(chuàng)建實(shí)例。
@RunWith(PowerMockRunner.class)
@PrepareForTest(Helper.class)
public class HelperTest {
@Mock
private Something mockSomething;
@InjectMocks
private Helper helper;
@Test
public void doSomething() throws Exception {
String argument = "arg";
PowerMockito.whenNew(Something.class).withArguments(argument).thenReturn(mockSomething);
// 調(diào)用需要測(cè)試方法
helper.doSomething(argument);
// 進(jìn)行驗(yàn)證
verify(mockSomething).doIt();
}
}
public class Helper {
public void doSomething(String arg) {
Something something = new Something(arg);
something.doit();
}
}
2,mock 靜態(tài)函數(shù), 單例模式就是一個(gè)典型的會(huì)調(diào)用靜態(tài)函數(shù)的例子。 注意要點(diǎn)與mock構(gòu)造函數(shù)相同。
class ClassWithStatics {
public static String getString() {
return "String";
}
public static int getInt() {
return 1;
}
}
@RunWith(PowerMockRunner.class)
@PrepareForTest(ClassWithStatics.class)
public class StubJustOneStatic {
@Test
public void test() {
PowerMockito.mockStatic(ClassWithStatics.class);
when(ClassWithStatics.getString()).thenReturn("Hello!");
System.out.println("String: " + ClassWithStatics.getString());
System.out.println("Int: " + ClassWithStatics.getInt());
}
}
3。mock枚舉實(shí)現(xiàn)的單例
SingletonObject.java
public enum SingletonObject { INSTANCE; private int num; protected void setNum(int num) { this.num = num; } public int getNum() { return num; } }
SingletonConsumer.java
public class SingletonConsumer {
public String consumeSingletonObject() {
return String.valueOf(SingletonObject.INSTANCE.getNum());
} }
SingletonConsumerTest.java
@RunWith(PowerMockRunner.class) @PrepareForTest({SingletonObject.class}) public class SingletonConsumerTest { @Test public void testConsumeSingletonObject() throws Exception { SingletonObject mockInstance = mock(SingletonObject.class); Whitebox.setInternalState(SingletonObject.class, "INSTANCE", mockInstance); when(mockInstance.getNum()).thenReturn(42); assertEquals("42", new SingletonConsumer().consumeSingletonObject()); } }
4。返回參數(shù)值做為函數(shù)返回值。
mockito 1.9.5之后,提供一個(gè)方便的方法來(lái)實(shí)現(xiàn)這個(gè)需要,在這之前可以使用一個(gè)匿名函數(shù)來(lái)返回一個(gè)answer來(lái)實(shí)現(xiàn)。
when(myMock.myFunction(anyString())).then(returnsFirstArg());
其中returnsFirstArg()是org.mockito.AdditionalAnswers中的一個(gè)靜態(tài)方法。
在這個(gè)類(lèi)中還有其他的一些類(lèi)似方法
returnsSecondArg()
returnsLastArg()
ReturnsArgumentAt(int position)
5. 在調(diào)用mock出來(lái)的方法中,改變方法參數(shù)的值
when( myMock.someMethod( any( List.class ) ) ).thenAnswer( ( new Answer<Void>() {
@Override
public Void answer( InvocationOnMock invocation )
throws Throwable {
Object[] args = invocation.getArguments();
List arg1 = (List)args[0];
arg1.add("12345");
return null;
}
} ) );
Verifying with generic parameters
verify(someService).process(Matchers.<Collection<Person>>any());
verify(adunoMasterBaseProcessor).processBinFiles( anyListOf(File.class) );
Oracle提供的JDK其實(shí)已經(jīng)自帶一定程度的熱加載功能,但是如果你修改了類(lèi)名,方法名,或者添加了新類(lèi),新方法的話。 Tomcat都需要重新啟動(dòng)來(lái)使得剛才的更改生效。 而JRebel和springloaded都能有效地解決這個(gè)問(wèn)題。其中springloaded是開(kāi)源軟件,可以免費(fèi)使用,尤其難得。 其主頁(yè):https://github.com/spring-projects/spring-loaded 在官方頁(yè)面的簡(jiǎn)單介紹中,作者只講述了如何在java程序中應(yīng)用springloaded,而沒(méi)有說(shuō)明如何在tomcat中進(jìn)行配置。 本文將簡(jiǎn)要進(jìn)行介紹。 1,下載springloaded到本地目錄,比如:c:\temp\springloaded-1.2.3.RELEASE.jar 2. 修改tomcat的應(yīng)用,禁止tomcat自己的熱加載,方法是在META-INF目錄下創(chuàng)建context.xml文件,里面包含如下語(yǔ)句,關(guān)鍵便是其中設(shè)置reloadable為false <?xml version="1.0" encoding="UTF-8"?> <Context antiResourceLocking="false" privileged="true" useHttpOnly="true" reloadable="false" /> 3.在運(yùn)行環(huán)境中添加springloaded的jar文件,在eclipse中右鍵點(diǎn)擊項(xiàng)目,run as->run configuration 在彈出的窗口中,選擇Arguments標(biāo)簽,在vm arguments的末尾添加: -javaagent:C:\temp\springloaded-1.2.3.RELEASE.jar -noverify 點(diǎn)擊應(yīng)用按鈕。 以上便完成了所有的配置,步驟并不復(fù)雜。
java wrapper是一個(gè)可以用于將java應(yīng)用程序包裝成windows服務(wù)的工具。 并且可以通過(guò)簡(jiǎn)單的配置來(lái)允許使用visualVM進(jìn)行監(jiān)控。 配置方法: 在wrapper.conf中添加如下3行 wrapper.java.additional.1=-Dcom.sun.management.jmxremote.port=9898 #這里的端口號(hào)可以自行選擇。 wrapper.java.additional.2=-Dcom.sun.management.jmxremote.ssl=false wrapper.java.additional.3=-Dcom.sun.management.jmxremote.authenticate=false 修改完畢保存后重新啟動(dòng)服務(wù)。 打開(kāi)visualVM, 在菜單中選擇 file->Add JMX Connection。 在彈出窗口中,connection一項(xiàng)中輸入: localhost:9898 即可。 此配置對(duì)于jconsole也同樣有效。
在一些歷史遺留代碼中,會(huì)用到j(luò)ava.util.logging. 如果在新的項(xiàng)目中引用了這些代碼,而又不希望去一個(gè)一個(gè)的修改原來(lái)的代碼。 可以使用slf4j提供的類(lèi)來(lái)轉(zhuǎn)接這部分的日志輸出。 方法: 1、類(lèi)路徑中添加 slf4j-api-1.7.10.jar jul-to-slf4j.1.7.10.jar ( 用于將java.util.logging的日志橋接到slf4j中) logback-core.1.1.2.jar logback-classic-1.1.2.jar 2、在代碼中添加: // Optionally remove existing handlers attached to j.u.l root logger SLF4JBridgeHandler.removeHandlersForRootLogger(); // (since SLF4J 1.6.5)
// add SLF4JBridgeHandler to j.u.l's root logger, should be done once during // the initialization phase of your application SLF4JBridgeHandler.install(); 注意事項(xiàng): 1、這個(gè)橋接可以會(huì)造成性能問(wèn)題。 和其他的橋接實(shí)現(xiàn)(比如:log4j, commons logging)不同,這個(gè)模塊并不真正的完全替代java.util.logging類(lèi),因?yàn)檫@個(gè)java.util.logging是java自帶的。 所以只是把原來(lái)的日志對(duì)象進(jìn)行了轉(zhuǎn)換,簡(jiǎn)單的說(shuō),這個(gè)轉(zhuǎn)換過(guò)程是有開(kāi)銷(xiāo)的。 關(guān)鍵在于,不管日志語(yǔ)句有沒(méi)有根據(jù)日志級(jí)別被關(guān)閉,這個(gè)轉(zhuǎn)換無(wú)法避免。 2、不能在類(lèi)路徑中放入 slf4j-jkd14.jar jul-toslf4j.jar
1. Text Editor: Notepad++/Syncplify.me Notepad! 2. Browser: Chrome/Firefox 3. 文件管理: XYplorer Lite/Explorer++/Q-Dir 4. Mind map: XMind Free 5. Video player: PotPlayer 6. Music player: Kugou 7. Mysql client: HeidiSql 8. PDF reader: Foxit Reader 9. File/Folder synchronize : FreeFileSync 10. MP3 tools: Audacity/MP3 Gain 11. Zip: 7-zip 12. Partition Management: EaseUS Partition Master Free / MiniTool Free Partition Manager 13. Data Recovery: EaseUS Data Recovery Wizard Free / MiniTool Free Data Recovery 14. PDF Printer: PDF reDirect v2 15. 個(gè)人信息管理: EssentialPIM Free Edition 16. 遠(yuǎn)程登錄: Terminals 17. 文本比較合并: winmerge 18. (s)FTP client: WinSCP 19. 圖像處理: GIMP
Ember 是一個(gè)旨在創(chuàng)建大型 web應(yīng)用的JavaScript框架,它消除了樣板(boilerplate)并提供了標(biāo)準(zhǔn)的應(yīng)用程序架構(gòu)。
Manning: Ember.js in action 第一章
Manning: Ember.js in action 第五章
先給一個(gè)例子: $http. get('/remote/item' ). then(function(response) { console.log('成功。'); }, function(errResponse) { console. error('出錯(cuò).' ); });
一。介紹Promise 在這個(gè)例子中,$http.get()函數(shù)返回了一個(gè)Promise對(duì)象, 有了這個(gè)對(duì)象,我們才能很方便地直接在后面添加then函數(shù)的定義。 Promise對(duì)象在AngularJS中是一個(gè)非常重要的存在。它提供了強(qiáng)大的功能和便利性。
1。異步性 從定義的語(yǔ)法上看,操作似乎是同步的,但是Promise的工作其實(shí)是異步的,只有在服務(wù)端返回?cái)?shù)據(jù)后,后續(xù)的函數(shù)才會(huì)被調(diào)用。這是一個(gè)事件驅(qū)動(dòng),非阻塞式的框架。
2。它避免了其它框架的嵌套回調(diào)函數(shù)的缺點(diǎn)。 -所有異步任務(wù)都會(huì)返回一個(gè)Promise對(duì)象 -每個(gè)Promise對(duì)象都有一個(gè)then函數(shù),then函數(shù)有兩個(gè)參數(shù),分別是成功處理函數(shù)和失敗處理函數(shù) -失敗處理函數(shù)和成功處理函數(shù)都只會(huì)在異步處理完成后被調(diào)用一次 -then函數(shù)也會(huì)返回Promise對(duì)象,這樣,我們可以把多個(gè)函數(shù)串連起來(lái)成為一個(gè)函數(shù)鏈 -成功處理函數(shù)和失敗處理函數(shù)的返回值可以被傳遞到函數(shù)鏈下一個(gè)的函數(shù)中 -如果在成功(或者失敗)處理函數(shù)中,又開(kāi)始了一個(gè)異步調(diào)用,那么函數(shù)鏈中的函數(shù)將會(huì)在這個(gè)異步調(diào)用結(jié)束后才開(kāi)始
二。異步鏈?zhǔn)秸{(diào)用的后續(xù)處理 假如我們定義了如下的函數(shù)鏈: $http.get('/item').then(s1, e1).then(s2, e2).then(s3, e3); 我們?nèi)绾巫灾鞯母鶕?jù)函數(shù)鏈中每個(gè)函數(shù)的運(yùn)行結(jié)果,決定觸發(fā)后續(xù)函數(shù)的成功處理函數(shù)或者失敗處理函數(shù)呢? 比如說(shuō),在s1處理過(guò)程中,發(fā)生問(wèn)題,于是我們觸發(fā)了e2, 但是在e2處理完后,我們又想觸發(fā)s3. AnguarJS提供了$q來(lái)滿足這樣的需求。 如果我們想觸發(fā)函數(shù)鏈中下一個(gè)函數(shù)的成功處理,我們只需要最后給出一個(gè)返回值,有了返回值,AngularJS會(huì)認(rèn)為函數(shù)執(zhí)行正確,自動(dòng)調(diào)用下一個(gè)函數(shù)中的成功處理 如果想觸發(fā)失敗處理,那么可以簡(jiǎn)單地返回$q.reject(data),這樣就會(huì)觸發(fā)下一個(gè)函數(shù)的失敗處理
在前文(http://www.tkk7.com/usherlight/archive/2015/02/01/422633.html)中我們?cè)?jīng)介紹過(guò),定義controller時(shí),需要2個(gè)參數(shù),第一個(gè)參數(shù)是controller的名稱,第二個(gè)參數(shù)是一個(gè)數(shù)組,數(shù)組的最后一個(gè)元素將是controller的函數(shù),前面的參數(shù)是controller的依賴項(xiàng)。我們現(xiàn)在就來(lái)仔細(xì)分析一下其中的具體過(guò)程。 先給一個(gè)例子: angular. module('notesApp' , []) . controller('MainCtrl' , ['$log' , function($log) { var self = this; self. logStuff = function() { $log. log('The button was pressed' ); }; }]) 在這個(gè)例子中可以看到,我們?cè)诘谝粋€(gè)參數(shù)中用字符串(服務(wù)名稱)添加了一個(gè)依賴項(xiàng)。當(dāng)我們通過(guò)字符串聲明了這一個(gè)服務(wù)之后,我們就可以把它當(dāng)作一個(gè)變量注入到函數(shù)中。AngularJS會(huì)自動(dòng)查找字符串名稱對(duì)應(yīng)的服務(wù)名,按照順序?qū)⑵渥⑷氲胶瘮?shù)中。 myModule.controller("MainCtrl", ["$log", "$window", function($l, $w) {}]); 在這個(gè)例子中,$log, $windows是AngularJS自帶的兩個(gè)服務(wù),在數(shù)組中通過(guò)名稱聲明后,會(huì)被注入到函數(shù)的兩個(gè)參數(shù)中。 比較常用的AngularJS自帶的服務(wù)有:$window, $location, $http等
從上面的例子中可以看出,AngularJS的設(shè)計(jì)思想就是不要在函數(shù)中自己去實(shí)例化或者通過(guò)其它途徑來(lái)獲取服務(wù)的實(shí)例,而是聲明需要的對(duì)象,由AngularJS來(lái)注入具體的實(shí)例。
創(chuàng)建自己的服務(wù) 什么時(shí)候應(yīng)該創(chuàng)建服務(wù),而不是controller呢? 1。 需要重用的時(shí)候 2。需要保留應(yīng)用級(jí)的狀態(tài)。這是非常重要的一點(diǎn),controller是會(huì)不斷地被創(chuàng)建和銷(xiāo)毀的,如果需要保存應(yīng)用級(jí)的狀態(tài),就需要使用service 3。和頁(yè)面顯示無(wú)關(guān) 4。需要和第三方服務(wù)整合 5。緩存
服務(wù)是會(huì)被延遲加載的,也就是說(shuō)只有在第一次被引用的時(shí)候,才會(huì)被創(chuàng)建。 服務(wù)將會(huì)被定義一次,也只會(huì)被實(shí)例化一次。
摘要: 默認(rèn)情況下,每隔一秒種,SpringLoaded就會(huì)掃描類(lèi)路徑,自動(dòng)加載改變過(guò)的類(lèi), 而不需要重新啟動(dòng)應(yīng)用 閱讀全文
07. ng-repeart a. 在循環(huán)map的時(shí)候,會(huì)自動(dòng)根據(jù)鍵值進(jìn)行排序。 b. 一些自帶的變量,$first(是否是第一個(gè)), $last(是否是最后一個(gè)), $middle(是否是中間的), $index(下標(biāo),根據(jù)鍵值排序后的下標(biāo)), $even, $odd 08. 自己定義新變量時(shí)不要使用$$開(kāi)頭。 09. 可以使用track-by表達(dá)式來(lái)優(yōu)化對(duì)DOM的操作,對(duì)DOM對(duì)象使用從數(shù)據(jù)庫(kù)取得的ID來(lái)進(jìn)行標(biāo)記,這樣的話,當(dāng)我們重復(fù)多次從數(shù)據(jù)庫(kù)中取出相同的數(shù)據(jù)的時(shí)候,DOM對(duì)象就能夠被重用。 10. 數(shù)據(jù)雙向綁定的好處 a. 如果我們想改變頁(yè)面Form中的數(shù)值,我們不需要在Javascript中,根據(jù)ID或者名稱來(lái)查找相應(yīng)的Form控件,只需要改變Controller變量的值,不需要JQuery的Selector,也不需要findElementByID b. 如果我們想在javascript中獲取Form控件的值,在控件的變量中就能直接獲得。 11. 使用ng-submit比在button上使用ng-click要好一些。HTML的表單的提交有多種方式,比如在輸入域中按回車(chē)鍵就會(huì)觸發(fā)ng-submit,而不會(huì)觸發(fā)button的ng-click事件。 12. 在ng-model中,可以直接引用一個(gè)對(duì)象,比如:<input type="text" ng-model="ctrl.user.name">,而不需要事先在model中以self.user={}定義。在AngularJS中,使用了ng-model的話,AngularJS在初始化數(shù)據(jù)綁定的時(shí)候,自動(dòng)創(chuàng)建其中的對(duì)象和鍵值。在剛才的例子中,一旦用戶開(kāi)始在輸入域中鍵入第一個(gè)字母,用戶user就會(huì)被自動(dòng)創(chuàng)建。 13. 推薦使用將相關(guān)數(shù)據(jù)集中到一個(gè)對(duì)象的方式來(lái)進(jìn)行數(shù)據(jù)綁定,比如,用戶名和密碼,推薦使用: <input type="text" ng-model="ctrl.user.name"> <input type="text" ng-model="ctrl.user.password"> 而不是: <input type="text" ng-model="ctrl.name"> <input type="text" ng-model="ctrl.password">
1. AngularJS的module函數(shù)有兩種用法,
a. 定義一個(gè)module, 需要傳入2個(gè)參數(shù),module('moduleName', []), 第一個(gè)參數(shù)是新的module名稱,第二個(gè)參數(shù)是新module所依賴的module數(shù)組。
b. 載入一個(gè)module, 只需要1個(gè)參數(shù),module('moduleName'), 唯一的一個(gè)參數(shù)指定要載入的module名稱。
2. 使用controller函數(shù)來(lái)定義一個(gè)控制器(controller), 用ng-controller將控制器綁定到具體的HTML組件上。定義控制器的controller函數(shù)也需要2個(gè)參數(shù),第一個(gè)是控制器名稱,第二個(gè)參數(shù)同樣也是一個(gè)數(shù)組,數(shù)組的最后一個(gè)元素就是controller本身的函數(shù),前面的元素用字符串的形式指定其需要的依賴項(xiàng)。如果沒(méi)有依賴項(xiàng),那就只需要定義函數(shù)。比如:
angular.module('app1', [])
.controller('mainControl', [function() {
console.log('controller created.');
}]);
3. 在controller函數(shù)中用var定義的局部變量,在HTML中是不可見(jiàn)的。
4. 推薦在controller函數(shù)中盡量避免直接引用this, 比較好的做法是使用代理。原因是一個(gè)函數(shù)中的this關(guān)鍵詞在被外部調(diào)用的時(shí)候,是會(huì)被覆蓋掉的。這樣的話,在函數(shù)內(nèi)部和外部的this會(huì)是完全不同兩個(gè)對(duì)象。
代理用法示例:
angular.module('app1', [])
.controller('mainControl', [function() {
var self = this;
self.message = 'Hello world';
self.changeMessage = function() {
self.message = 'Goodbye.';
};
}]);
5. ng-bind與雙大括號(hào)的區(qū)別, ng-bind和{{}}可以說(shuō)基本上是可以互相替換的,但是也有區(qū)別。區(qū)別在于:AngularJS在啟動(dòng)的時(shí)候就會(huì)執(zhí)行ng-bind, 而{{}}的替換時(shí)間會(huì)稍晚一些。有可能發(fā)現(xiàn)頁(yè)面在加載的時(shí)候,雙括號(hào)被一閃而過(guò)地替換掉(只在頁(yè)面初次加載的時(shí)候發(fā)生)。但是ng-bind就沒(méi)有這個(gè)問(wèn)題。
6. ng-cloak可以用于解決雙括號(hào)閃現(xiàn)的問(wèn)題。
1. HTML頁(yè)面的加載,這會(huì)觸發(fā)加載頁(yè)面包含的所有JS (包括 AngularJS) 2. AngularJS啟動(dòng),搜尋所有的指令(directive) 3. 找到ng-app,搜尋其指定的模塊(Module),并將其附加到ng-app所在的組件上。 4. AnguarJS遍歷所有的子組件,查找指令和bind命令 5. 每次發(fā)現(xiàn)ng-controller或者ng-repeart的時(shí)候,它會(huì)創(chuàng)建一個(gè)作用域(scope),這個(gè)作用域就是組件的上下文。作用域指明了每個(gè)DOM組件對(duì)函數(shù)、變量的訪問(wèn)權(quán)。 6. AngularJS然后會(huì)添加對(duì)變量的監(jiān)聽(tīng)器,并監(jiān)控每個(gè)變量的當(dāng)前值。一旦值發(fā)生變化,AngularJS會(huì)更新其在頁(yè)面上的顯示。 7. AngularJS優(yōu)化了檢查變量的算法,它只會(huì)在某些特殊的事件觸發(fā)時(shí),才會(huì)去檢查數(shù)據(jù)的更新,而不是簡(jiǎn)單地在后臺(tái)不停地輪詢。
Java虛擬機(jī)規(guī)范規(guī)定JVM的內(nèi)存分為了好幾塊,比如堆,棧,程序計(jì)數(shù)器,方法區(qū)等,而Hotspot jvm的實(shí)現(xiàn)中,將堆內(nèi)存分為了三部分,新生代,老年代,持久帶,其中持久帶實(shí)現(xiàn)了規(guī)范中規(guī)定的方法區(qū),而內(nèi)存模型中不同的部分都會(huì)出現(xiàn)相應(yīng)的OOM錯(cuò)誤,接下來(lái)我們就分開(kāi)來(lái)討論一下。 棧溢出(StackOverflowError) 棧溢出拋出java.lang.StackOverflowError錯(cuò)誤,出現(xiàn)此種情況是因?yàn)榉椒ㄟ\(yùn)行的時(shí)候棧的深度超過(guò)了虛擬機(jī)容許的最大深度所致。 出現(xiàn)這種情況,一般情況下是程序錯(cuò)誤所致的,比如寫(xiě)了一個(gè)死遞歸,就有可能造成此種情況。 下面我們通過(guò)一段代碼來(lái)模擬一下此種情況的內(nèi)存溢出。 - import java.util.*;
- import java.lang.*;
- public class OOMTest{
-
- public void stackOverFlowMethod(){
- stackOverFlowMethod();
- }
-
- public static void main(String... args){
- OOMTest oom = new OOMTest();
- oom.stackOverFlowMethod();
- }
-
- }
運(yùn)行上面的代碼,會(huì)拋出如下的異常: 引用 Exception in thread "main" java.lang.StackOverflowError at OOMTest.stackOverFlowMethod(OOMTest.java:6) 堆溢出(OutOfMemoryError:java heap space) 堆內(nèi)存溢出的時(shí)候,虛擬機(jī)會(huì)拋出java.lang.OutOfMemoryError:java heap space,出現(xiàn)此種情況的時(shí)候,我們需要根據(jù)內(nèi)存溢出的時(shí)候產(chǎn)生的dump文件來(lái)具體分析(需要增加-XX:+HeapDumpOnOutOfMemoryErrorjvm啟動(dòng)參數(shù))。出現(xiàn)此種問(wèn)題的時(shí)候有可能是內(nèi)存泄露,也有可能是內(nèi)存溢出了。 如果內(nèi)存泄露,我們要找出泄露的對(duì)象是怎么被GC ROOT引用起來(lái),然后通過(guò)引用鏈來(lái)具體分析泄露的原因。 如果出現(xiàn)了內(nèi)存溢出問(wèn)題,這往往是程序本生需要的內(nèi)存大于了我們給虛擬機(jī)配置的內(nèi)存,這種情況下,我們可以采用調(diào)大-Xmx來(lái)解決這種問(wèn)題。 下面我們通過(guò)如下的代碼來(lái)演示一下此種情況的溢出: - import java.util.*;
- import java.lang.*;
- public class OOMTest{
-
- public static void main(String... args){
- List<byte[]> buffer = new ArrayList<byte[]>();
- buffer.add(new byte[10*1024*1024]);
- }
-
- }
我們通過(guò)如下的命令運(yùn)行上面的代碼: - java -verbose:gc -Xmn10M -Xms20M -Xmx20M -XX:+PrintGC OOMTest
程序輸入如下的信息: 引用 [GC 1180K->366K(19456K), 0.0037311 secs] [Full GC 366K->330K(19456K), 0.0098740 secs] [Full GC 330K->292K(19456K), 0.0090244 secs] Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at OOMTest.main(OOMTest.java:7) 從運(yùn)行結(jié)果可以看出,JVM進(jìn)行了一次Minor gc和兩次的Major gc,從Major gc的輸出可以看出,gc以后old區(qū)使用率為134K,而字節(jié)數(shù)組為10M,加起來(lái)大于了old generation的空間,所以拋出了異常,如果調(diào)整-Xms21M,-Xmx21M,那么就不會(huì)觸發(fā)gc操作也不會(huì)出現(xiàn)異常了。 通過(guò)上面的實(shí)驗(yàn)其實(shí)也從側(cè)面驗(yàn)證了一個(gè)結(jié)論:當(dāng)對(duì)象大于新生代剩余內(nèi)存的時(shí)候,將直接放入老年代,當(dāng)老年代剩余內(nèi)存還是無(wú)法放下的時(shí)候,出發(fā)垃圾收集,收集后還是不能放下就會(huì)拋出內(nèi)存溢出異常了 持久帶溢出(OutOfMemoryError: PermGen space) 我們知道Hotspot jvm通過(guò)持久帶實(shí)現(xiàn)了Java虛擬機(jī)規(guī)范中的方法區(qū),而運(yùn)行時(shí)的常量池就是保存在方法區(qū)中的,因此持久帶溢出有可能是運(yùn)行時(shí)常量池溢出,也有可能是方法區(qū)中保存的class對(duì)象沒(méi)有被及時(shí)回收掉或者class信息占用的內(nèi)存超過(guò)了我們配置。當(dāng)持久帶溢出的時(shí)候拋出java.lang.OutOfMemoryError: PermGen space。 我在工作可能在如下幾種場(chǎng)景下出現(xiàn)此問(wèn)題。 1.使用一些應(yīng)用服務(wù)器的熱部署的時(shí)候,我們就會(huì)遇到熱部署幾次以后發(fā)現(xiàn)內(nèi)存溢出了,這種情況就是因?yàn)槊看螣岵渴鸬暮?,原?lái)的class沒(méi)有被卸載掉。 2.如果應(yīng)用程序本身比較大,涉及的類(lèi)庫(kù)比較多,但是我們分配給持久帶的內(nèi)存(通過(guò)-XX:PermSize和-XX:MaxPermSize來(lái)設(shè)置)比較小的時(shí)候也可能出現(xiàn)此種問(wèn)題。 3.一些第三方框架,比如spring,hibernate都通過(guò)字節(jié)碼生成技術(shù)(比如CGLib)來(lái)實(shí)現(xiàn)一些增強(qiáng)的功能,這種情況可能需要更大的方法區(qū)來(lái)存儲(chǔ)動(dòng)態(tài)生成的Class文件。 我們知道Java中字符串常量是放在常量池中的,String.intern()這個(gè)方法運(yùn)行的時(shí)候,會(huì)檢查常量池中是否存和本字符串相等的對(duì)象,如果存在直接返回對(duì)常量池中對(duì)象的引用,不存在的話,先把此字符串加入常量池,然后再返回字符串的引用。那么我們就可以通過(guò)String.intern方法來(lái)模擬一下運(yùn)行時(shí)常量區(qū)的溢出.下面我們通過(guò)如下的代碼來(lái)模擬此種情況: - import java.util.*;
- import java.lang.*;
- public class OOMTest{
-
- public static void main(String... args){
- List<String> list = new ArrayList<String>();
- while(true){
- list.add(UUID.randomUUID().toString().intern());
- }
- }
-
- }
我們通過(guò)如下的命令運(yùn)行上面代碼: java -verbose:gc -Xmn5M -Xms10M -Xmx10M -XX:MaxPermSize=1M -XX:+PrintGC OOMTest 運(yùn)行后的輸入如下圖所示: 引用 Exception in thread "main" java.lang.OutOfMemoryError: PermGen space at java.lang.String.intern(Native Method) at OOMTest.main(OOMTest.java:8) 通過(guò)上面的代碼,我們成功模擬了運(yùn)行時(shí)常量池溢出的情況,從輸出中的PermGen space可以看出確實(shí)是持久帶發(fā)生了溢出,這也驗(yàn)證了,我們前面說(shuō)的Hotspot jvm通過(guò)持久帶來(lái)實(shí)現(xiàn)方法區(qū)的說(shuō)法。 OutOfMemoryError:unable to create native thread 最后我們?cè)趤?lái)看看java.lang.OutOfMemoryError:unable to create natvie thread這種錯(cuò)誤。 出現(xiàn)這種情況的時(shí)候,一般是下面兩種情況導(dǎo)致的: 1.程序創(chuàng)建的線程數(shù)超過(guò)了操作系統(tǒng)的限制。對(duì)于Linux系統(tǒng),我們可以通過(guò)ulimit -u來(lái)查看此限制。 給虛擬機(jī)分配的內(nèi)存過(guò)大,導(dǎo)致創(chuàng)建線程的時(shí)候需要的native內(nèi)存太少。我們都知道操作系統(tǒng)對(duì)每個(gè)進(jìn)程的內(nèi)存是有限制的,我們啟動(dòng)Jvm,相當(dāng)于啟動(dòng)了一個(gè)進(jìn)程,假如我們一個(gè)進(jìn)程占用了4G的內(nèi)存,那么通過(guò)下面的公式計(jì)算出來(lái)的剩余內(nèi)存就是建立線程棧的時(shí)候可以用的內(nèi)存。 線程??偪捎脙?nèi)存=4G-(-Xmx的值)- (-XX:MaxPermSize的值)- 程序計(jì)數(shù)器占用的內(nèi)存 通過(guò)上面的公式我們可以看出,-Xmx 和 MaxPermSize的值越大,那么留給線程??捎玫目臻g就越小,在-Xss參數(shù)配置的棧容量不變的情況下,可以創(chuàng)建的線程數(shù)也就越小。因此如果是因?yàn)檫@種情況導(dǎo)致的unable to create native thread,那么要么我們?cè)龃筮M(jìn)程所占用的總內(nèi)存,或者減少-Xmx或者-Xss來(lái)達(dá)到創(chuàng)建更多線程的目的。
現(xiàn)在的顯示屏都在飚像素,商家的宣傳一個(gè)比一個(gè)噱頭大,什么 Retina、4K、8K 這種名詞一個(gè)接一個(gè)的出來(lái), 這些到底都是啥意思? 首先,Retina 和 4K 以及 8K 并不是同一層面的定義。屏幕一般是以像素點(diǎn)做單位的,4K 和 8K 就是直接限定了像素點(diǎn)的多少,而 Retina 則是沒(méi)有硬性的規(guī)范。Retina 屏幕的概念最早由蘋(píng)果公司執(zhí)行長(zhǎng)史蒂夫·喬布斯(Steve Jobs)于 WWDC2010 發(fā)布 iPhone 4 時(shí)提出的。 定義是:要求在正常觀看距離下,足以使人肉眼無(wú)法分辨其中的單獨(dú)像素。因此它并沒(méi)有限定像素值多少。
4K 就是水平方向每一行的像素值達(dá)到或是接近 1024 的 4 倍,8K 就是達(dá)到或接近 8 倍。 以此為標(biāo)準(zhǔn),4K 一般圖像就是指 4096*2160 的分辨率。當(dāng)然,這也不是硬性要求,像市場(chǎng)上很多 4K 屏幕其實(shí)是 3840*2160 或是 3656*2664,這些都是 4K 圖像分辨率的范疇。 8K 就是分辨率在 7680*4320 左右。
順便說(shuō)一下,720p 則是指豎直方向的像素點(diǎn)達(dá)到 720 個(gè),1080p 則是 1080 個(gè),“P”是逐行掃描的意思
問(wèn):那到底 Retina 和 4K 或是 Retina 和 8K 哪個(gè)更清楚呢? 答:不一定,二者不能平行比較。 因?yàn)?4K 和 8K 是限定了像素點(diǎn)的多少,而 Retina 是要求正常距離看不到像素點(diǎn)。 舉個(gè)例子:如果放到正常的 42 寸屏幕上,4K 和 8K 在正常距離觀看下都看不到像素點(diǎn),那么兩者都可以被稱作“Retina 屏幕”。
可是如果給你一臺(tái) 500 寸的巨大屏幕,那么即便是 8K 也會(huì)到處是馬賽克,這時(shí) Retina 觀感依然是高清無(wú)像素點(diǎn),必然比 8K 和 4K 清楚的多。
Last_SQL_Error: Error 'Lock wait timeout exceeded; try restarting transaction' on query. Default database: 'test'. Query: 'DELETE FROM table1 WHERE id = 361' 1 row in set (0.00 sec)
solution: restart slave;
stop slave; start slave;
1. server.xml 在<engine>中添加 <Realm className="org.apache.catalina.realm.MemoryRealm" /> 2. tomcat-user.xml <role rolename="manager"/> <role rolename="manager-gui"/>
<user username="admin" password="tomcat" roles="manager"/>
1. 自動(dòng)掃描配置文件改動(dòng)
<configuration scan="true" scanPeriod="30 seconds">
....
</configuration
2. 日志每天歸檔,同時(shí)目錄名包含相應(yīng)的年份和月份
<fileNamePattern>F:\Programs\GlobalPos\GatewayCiti\logs\%d{yyyy/MM,aux}\G%d{dd}-%i.log</fileNamePattern>
注意其中aux的使用,在fileNamePatter中如果出現(xiàn)多個(gè)%d的情況下,只能有一個(gè)為主配置,其他都需要使用aux標(biāo)記為附屬配置
其中的%i請(qǐng)參看下節(jié)的介紹
3. 文件同時(shí)根據(jù)日期和大小滾動(dòng)創(chuàng)建
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily -->
<!--
<fileNamePattern>F:\Programs\GlobalPos\NetReport\logs\Portal-%d{yyyyMMdd}.log</fileNamePattern>
-->
<!-- Size and time based archiving -->
<fileNamePattern>D:\logs\%d{yyyy/MM,aux}\L%d{dd}-%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
fileNamePattern在上一節(jié)已經(jīng)介紹,這里主要介紹timeBasedFileNamingAndTriggeringPolicy,此處配置對(duì)文件大小的限定,由fileNamePattern的%i在確定下標(biāo)在文件名中的位置
此示例產(chǎn)生的日志文件將會(huì)是:
D:\logs\2015\01\L05-0.log 如果該文件大于100M,就會(huì)生成D:\logs\2015\01\L05-1.log
|