2013年3月22日 #
Lucene 的 Directory類就像它的意思一樣“目錄”,如“目錄”不存在,第一次啟動(dòng)被創(chuàng)建,一旦文件被創(chuàng)建,它只能打開閱讀,或刪除。允許讀取和寫入隨機(jī)訪問。Java I/O api 不能直接使用,只能通過這個(gè)API 。Directory的實(shí)現(xiàn)類可以分為文件目錄,內(nèi)存目錄和目錄的代理類及工具類。具體如下圖所示:
一:文件目錄
SimpleFSDirectory:FSDirectory的簡單實(shí)現(xiàn),并發(fā)能力有限,遇到多線程讀同一個(gè)文件時(shí)會(huì)遇到瓶頸,通常用NIOFSDirectory或MMapDirectory代替。
NIOFSDirectory:通過java.nio's FileChannel實(shí)行定位讀取,支持多線程讀(默認(rèn)情況下是線程安全的)。該類僅使用FileChannel進(jìn)行讀操作,寫操作則是通過FSIndexOutput實(shí)現(xiàn)。
注意:NIOFSDirectory 不適用于Windows系統(tǒng),另外如果一個(gè)訪問該類的線程,在IO阻塞時(shí)被interrupt或cancel,將會(huì)導(dǎo)致底層的文件描述符被關(guān)閉,后續(xù)的線程再次訪問NIOFSDirectory時(shí)將會(huì)出現(xiàn)ClosedChannelException異常,此種情況應(yīng)用SimpleFSDirectory代替。
MMapDirectory:通過內(nèi)存映射進(jìn)行讀,通過FSIndexOutput進(jìn)行寫的FSDirectory實(shí)現(xiàn)類。使用該類時(shí)要保證用足夠的虛擬地址空間。另外當(dāng)通過IndexInput的close方法進(jìn)行關(guān)閉時(shí)并不會(huì)立即關(guān)閉底層的文件句柄,只有GC進(jìn)行資源回收時(shí)才會(huì)關(guān)閉。
為了能適應(yīng)各個(gè)操作系統(tǒng)選擇最佳Directory方案,lucene 提供FSDirectory類的靜態(tài)方法open()實(shí)現(xiàn)自適應(yīng)。
public static FSDirectory open(File path, LockFactory lockFactory) throws IOException {
if ((Constants.WINDOWS || Constants.SUN_OS || Constants.LINUX)
&& Constants.JRE_IS_64BIT && MMapDirectory.UNMAP_SUPPORTED) {
return new MMapDirectory(path, lockFactory);
} else if (Constants.WINDOWS) {
return new SimpleFSDirectory(path, lockFactory);
} else {
return new NIOFSDirectory(path, lockFactory);
}
}
二:內(nèi)存目錄
RAMDirectory:常駐內(nèi)存的Directory實(shí)現(xiàn)方式。默認(rèn)通過SingleInstanceLockFactory(單實(shí)例鎖工廠)進(jìn)行鎖的實(shí)現(xiàn)。該類不適合大量索引的情況。另外也不適用于多線程的情況。 在索引數(shù)據(jù)量大的情況下建議使用MMapDirectory代替。RAMDirectory是Directory抽象類在使用內(nèi)存最為文件存儲(chǔ)的實(shí)現(xiàn)類,其主要是將所有的索引文件保存到內(nèi)存中。這樣可以提高效率。但是如果索引文件過大的話,則會(huì)導(dǎo)致內(nèi)存不足,因此,小型的系統(tǒng)推薦使用,如果大型的,索引文件達(dá)到G級(jí)別上,推薦使用FSDirectory。
NRTCachingDirectory:是對RAMDirectory的封裝,適用于近乎時(shí)時(shí)(near-real-time)操作的環(huán)境。
三:Direcotry的代理類及工具類
FileSwitchDirectory:文件切換的Directory實(shí)現(xiàn).針對lucene的不同的索引文件使用不同的Directory .借助FileSwitchDirectory整合不同的Directory實(shí)現(xiàn)類的優(yōu)點(diǎn)于一身
比如MMapDirectory,借助內(nèi)存映射文件方式提高性能,但又要減少內(nèi)存切換的可能 ,當(dāng)索引太大的時(shí)候,內(nèi)存映射也需要不斷地切換,這樣優(yōu)點(diǎn)也可能變?nèi)秉c(diǎn),而之前的NIOFSDirectory實(shí)現(xiàn)java NIO的方式提高高并發(fā)性能,但又因高并發(fā)也會(huì)導(dǎo)致IO過多的影響,所以這次可以借助FileSwitchDirectory發(fā)揮他們兩的優(yōu)點(diǎn)。
RateLimitedDirectoryWrapper:通過IOContext來限制讀寫速率的Directory封裝類。
CompoundFileDirectory:用于訪問一個(gè)組合的數(shù)據(jù)流。僅適用于讀操作。對于同一段內(nèi)擴(kuò)展名不同但文件名相同的所有文件合并到一個(gè)統(tǒng)一的.cfs文件和一個(gè)對應(yīng)的.cfe文件內(nèi)。
.cfs文件由Header,FileData和FileCount組成。.cfe文件由Header,FileCount,FileName,DataOffset,DataLength組成。.cfs文件中存儲(chǔ)著索引的概要信息及組合文件
的數(shù)目(FileCount)。.cfe文件存儲(chǔ)文件目錄的條目內(nèi)容,內(nèi)容中包括文件數(shù)據(jù)扇區(qū)的起始位置,文件的長度及文件的名稱。
TrackingDirectoryWrapper:Directory的代理類。用于記錄哪些文件被寫入和刪除。
四:Direcotry讀寫對象的類圖
文章轉(zhuǎn)載過來的!
本機(jī)已經(jīng)安裝了jdk1.6,而比較早期的項(xiàng)目需要依賴jdk1.5,于是同時(shí)在本機(jī)安裝了jdk1.5和jdk1.6.
安裝jdk1.5前,執(zhí)行java -version得到
java version "1.6.0_38"
Java(TM) SE Runtime Environment (build 1.6.0_38-b05)
Java HotSpot(TM) 64-Bit Server VM (build 20.13-b02, mixed mode)
安裝完jdk1.5,并修改環(huán)境變量JAVA_HOME為D:\devSoftware\jdk1.5.再執(zhí)行 java -version時(shí),依然顯示:
java version "1.6.0_38"
Java(TM) SE Runtime Environment (build 1.6.0_38-b05)
Java HotSpot(TM) 64-Bit Server VM (build 20.13-b02, mixed mode)
看上去,新的環(huán)境變量JAVA_HOME=D:\devSoftware\jdk1.5并沒有生效。 在網(wǎng)上找了很多資料才發(fā)現(xiàn):
在安裝JDK1.6時(shí)(本機(jī)先安裝jdk1.6再安裝的jdk1.5),自動(dòng)將java.exe、javaw.exe、javaws.exe三個(gè)可執(zhí)行文件復(fù)制到了C:\Windows\System32目錄,由于這個(gè)目錄在WINDOWS環(huán)境變量中的優(yōu)先級(jí)高于JAVA_HOME設(shè)置的環(huán)境變量優(yōu)先級(jí)
解決方案:將java.exe,javaw.exe,javaws.exe刪除即可。開啟新的命令行窗口,再執(zhí)行java -version時(shí),就得到了期望中的結(jié)果
java version "1.5.0_17"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_17-b04)
Java HotSpot(TM) 64-Bit Server VM (build 1.5.0_17-b04, mixed mode)
在學(xué)lucene 之初看了許多書,都是走馬觀花,沒有項(xiàng)目的驅(qū)動(dòng)下,來一個(gè)用例demo感覺也不是很難,“我會(huì)了”這是我的第一感覺。
在2013年底公司接到一個(gè)項(xiàng)目用到lucene,這是我第一次正真接觸Lucene,代碼比較老3.6版本,不適合新項(xiàng)目的需求(空間查詢)。于是下載了最新版本 4.51,有帶“空間查詢”模塊。各大搜索引擎都沒有找到像樣例子,于是想到了lucene svn的 trunk目錄測試用例中找到了測試?yán)樱_始了一段lucene之旅。
寫數(shù)據(jù),創(chuàng)建IndexWriter,通過它的構(gòu)造函數(shù)需要一個(gè)索引目錄(Diectory)和索引寫入配置項(xiàng)(InderWriterConfig),直接上代碼:
//設(shè)置寫入目錄(好幾種呵呵)
Directory d=FSDirectory.open(new File("D:/luceneTest"));
//設(shè)置分詞 StandardAnalyzer(會(huì)把句子中的字單個(gè)分詞)
Analyzer analyzer= new StandardAnalyzer(Version.LUCENE_45);
//設(shè)置索引寫入配置
IndexWriterConfig config=new IndexWriterConfig(Version.LUCENE_45,analyzer);
//設(shè)置創(chuàng)建模式
//config.setOpenMode(IndexWriterConfig.OpenMode.CREATE_OR_APPEND);
IndexWriter indexwriter= new IndexWriter(d,config);
上面四行代碼就創(chuàng)建好了indexwriter,下面把數(shù)據(jù)填入就好了,寫入有多種方式如下圖:
用 addDocment 舉例代碼如下:
Document doc=new Document();
doc.add(new StringField("id", "1", Store.YES));
doc.add(new StringField("name", "brockhong", Store.YES));
doc.add(new TextField("content", "lucene 文檔第一次寫看著給分吧", Store.YES));
//寫入數(shù)據(jù)
indexwriter.addDocument(doc);
//提交
indexwriter.commit();
用 Luke 工具查看Text列,這是標(biāo)準(zhǔn)分詞惹的禍哦!寫入成功。
讀數(shù)據(jù)查詢,創(chuàng)建 IndexSearcher 構(gòu)造函數(shù)設(shè)置indexReader ,輸入查詢條件,上面content字段數(shù)據(jù)設(shè)置了分詞,所以必須通過查詢解析類QueryParser設(shè)定分詞字段、版本、分詞模式,并通過parse方法得到查詢條件。代碼如下:
//讀數(shù)據(jù)
//創(chuàng)建 indexReader 這個(gè)已過時(shí) IndexReader.open(d),里面的代碼一樣可能為了兼容老版本
IndexReader indexReader = DirectoryReader.open(d);
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
//查詢 設(shè)置分詞字段
QueryParser queryParser = new QueryParser(Version.LUCENE_45, "content",
new StandardAnalyzer(Version.LUCENE_45));
//or 關(guān)系 “給”、“分”
queryParser.setDefaultOperator(QueryParser.OR_OPERATOR);
Query query = queryParser.parse("給分");
TopDocs results = indexSearcher.search(query, 100);
int numTotalHits = results.totalHits;
System.out.println("共 " + numTotalHits + " 完全匹配的文檔");
ScoreDoc[] hits = results.scoreDocs;
for (int i = 0; i < hits.length; i++) {
Document document = indexSearcher.doc(hits[i].doc);
System.out.println("content:" + document.get("content"));
}
使用SAXReader的read(File file)方法時(shí),如果xml文件異常會(huì)導(dǎo)致文件被服務(wù)器占用不能移動(dòng)文件,建議不使用read(File file)方法而使用read(FileInputStream fis)等流的方式讀取文件,異常時(shí)關(guān)閉流,這樣就不會(huì)造成流未關(guān)閉,文件被鎖的現(xiàn)象了。(在服務(wù)器中運(yùn)行時(shí)會(huì)鎖住文件,main方法卻不會(huì))。
1、以下方式xml文件異常時(shí)會(huì)導(dǎo)致文件被鎖
- Document document = null;
- File file = new File(xmlFilePath);
- SAXReader saxReader = new SAXReader();
- try
- {
- document = saxReader.read(file);
- } catch (DocumentException e)
- {
- logger.error("將文件[" + xmlFilePath + "]轉(zhuǎn)換成Document異常", e);
- }
2、以下方式xml文件異常時(shí)不會(huì)鎖文件(也可以使用其他的流來讀文件)
- Document document = null;
- FileInputStream fis = null;
- try
- {
- fis = new FileInputStream(xmlFilePath);
- SAXReader reader = new SAXReader();
- document = reader.read(fis);
- }
- catch (Exception e)
- {
- logger.error("將文件[" + xmlFilePath + "]轉(zhuǎn)換成Document異常", e);
- }
- finally
- {
- if(fis != null)
- {
- try
- {
- fis.close();
- } catch (IOException e)
- {
- logger.error("將文件[" + xmlFilePath + "]轉(zhuǎn)換成Document,輸入流關(guān)閉異常", e);
- }
- }
- }
arcgis
CGCS2000_3_Degree_GK_Zone_40
WKID: 4528 Authority: EPSG
Projection: Gauss_Kruger
False_Easting: 40500000.0
False_Northing: 0.0
Central_Meridian: 120.0
Scale_Factor: 1.0
Latitude_Of_Origin: 0.0
Linear Unit: Meter (1.0)
Geographic Coordinate System: GCS_China_Geodetic_Coordinate_System_2000
Angular Unit: Degree (0.0174532925199433)
Prime Meridian: Greenwich (0.0)
Datum: D_China_2000
Spheroid: CGCS2000
Semimajor Axis: 6378137.0
Semiminor Axis: 6356752.314140356
Inverse Flattening: 298.257222101
Java 自定義
經(jīng)緯度轉(zhuǎn)換
///+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=40500000 +y_0=0 +ellps=GRS80 +units=m +no_defs
Point2D.Double srcProjec = null;
Point2D.Double dstProjec = null;
Projection proj = ProjectionFactory.fromPROJ4Specification (proj4_w);
// "epsg:4528" 數(shù)據(jù)從proj4 拷貝 nad
// Point2D.Double srcProjec = null;
// Point2D.Double dstProjec = null;
// Projection proj = ProjectionFactory.getNamedPROJ4CoordinateSystem ("epsg:4528");
srcProjec = new Point2D.Double (120.159,30.267);
//40515348.2903 3349745.5395
dstProjec = proj.transform (srcProjec, new Point2D.Double ());
System.out.println ("TM:" + dstProjec);
// TM: Point2D.Double [644904.399587292, 400717.8948938238]
srcProjec = new Point2D.Double (40515348.2903 ,3349745.5395);
dstProjec = proj.inverseTransform (srcProjec, new Point2D.Double ());
System.out.println ("TM:" + dstProjec);
今天研究Oracle遇到了這個(gè)問題ora-01033:oracle initializationor shutdown in progress
ORA-01033:ORACLEinitialization or shutdown in progress
解決方法
1)開始-運(yùn)行-cmd
2)命令行中輸入SQLPLUS SYS/SYS AS SYSDBA
3)輸入SHUTDOWN
4)輸入STARTUP.注意這里是最重要的地方,在顯示相關(guān)數(shù)據(jù)后,它還會(huì)顯示為什么不能啟動(dòng)的錯(cuò)誤所在.
C:\Users\lenovo>SQLPLUSSYS/SYS AS SYSDBA
SQL*Plus: Release 10.2.0.3.0 - Production on星期三 7月 3 11:43:32 2013
Copyright (c) 1982, 2006, Oracle. All Rights Reserved.
連接到:
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 -Production
With the Partitioning, OLAPand Data Mining options
SQL> SHUTDOWN
ORA-01109:數(shù)據(jù)庫未打開
已經(jīng)卸載數(shù)據(jù)庫。
ORACLE例程已經(jīng)關(guān)閉。
SQL> STARTUP
ORACLE例程已經(jīng)啟動(dòng)。
Total System Global Area 293601280 bytes
Fixed Size 1290208 bytes
Variable Size 234881056 bytes
Database Buffers 50331648 bytes
Redo Buffers 7098368 bytes
數(shù)據(jù)庫裝載完畢。
ORA-01157:無法標(biāo)識(shí)/鎖定數(shù)據(jù)文件 6 - 請參閱 DBWR 跟蹤文件
ORA-01110:數(shù)據(jù)文件 6: 'F:\DC\DB\SDRS\TS_SDRS.DBF'
SQL> alter databasedatafile'F:\DC\DB\SDRS\TS_SDRS.DBF'offline drop;
數(shù)據(jù)庫已更改。
SQL> alter database open;
數(shù)據(jù)庫已更改。
SQL> drop tablespaceTS_SDRS including contents;
表空間已刪除。
SQL> create undo tablespace TS_SDRS
2 datafile'CracleoradatasmsdbUNDOTBS01.DBF'size 2048M extent management local;
表空間已創(chuàng)建。
SQL> alter system setundo_tablespace=TS_SDRS;
系統(tǒng)已更改。
SQL> shutdown
數(shù)據(jù)庫已經(jīng)關(guān)閉。
已經(jīng)卸載數(shù)據(jù)庫。
ORACLE例程已經(jīng)關(guān)閉。
SQL> startup
ORACLE例程已經(jīng)啟動(dòng)。
Total System Global Area 293601280 bytes
Fixed Size 1290208 bytes
Variable Size 243269664 bytes
Database Buffers 41943040 bytes
Redo Buffers 7098368 bytes
數(shù)據(jù)庫裝載完畢。
數(shù)據(jù)庫已經(jīng)打開。
SQL>
------------------
ORA-01245、ORA-01547錯(cuò)誤的解決
數(shù)據(jù)庫rman restore database 之后,執(zhí)行recover database的時(shí)候,報(bào)告ORA-01245錯(cuò)誤,詳細(xì)的錯(cuò)誤信息如下:
SQL> recover database until cancel; ORA-00279: change 575876 generated at 12/01/2009 08:19:49 needed for thread 1 ORA-00289: suggestion : /oracle/flash_recovery_area/ORCL/archivelog/2009_12_01/o1_mf_1_2_%u_.arc ORA-00280: change 575876 for thread 1 is in sequence #2 Specify log: { auto ORA-00308: cannot open archived log '/oracle/flash_recovery_area/ORCL/archivelog/2009_12_01/o1_mf_1_2_%u_.arc' ORA-27037: unable to obtain file status Linux Error: 2: No such file or directory Additional information: 3 ORA-00308: cannot open archived log '/oracle/flash_recovery_area/ORCL/archivelog/2009_12_01/o1_mf_1_2_%u_.arc' ORA-27037: unable to obtain file status Linux Error: 2: No such file or directory Additional information: 3 ORA-01547: warning: RECOVER succeeded but OPEN RESETLOGS would get error below ORA-01245: offline file 2 will be lost if RESETLOGS is done ORA-01110: data file 2: '/oracle/oradata/orcl/undotbs01.dbf' SQL> |
[@more@]
檢查ORA-01245那一行,發(fā)現(xiàn)是datafile 2狀態(tài)為offline,解決的方法就是首先將datafile 2 online,然后再recover database。
SQL> alter database datafile 2 online; Database altered. SQL> recover database until cancel; ORA-00279: change 575876 generated at 12/01/2009 08:19:49 needed for thread 1 ORA-00289: suggestion : /oracle/flash_recovery_area/ORCL/archivelog/2009_12_01/o1_mf_1_2_%u_.arc ORA-00280: change 575876 for thread 1 is in sequence #2 Specify log: { cancel Media recovery cancelled. SQL> alter database open resetlogs; Database altered. SQL> |
--------------------
ORA-01589: 要打開數(shù)據(jù)庫則必須使用 RESETLOGS 或 NOR
ORA-01589: 要打開數(shù)據(jù)庫則必須使用 RESETLOGS 或 NORESETLOGS
選項(xiàng)
SQL> alter database open
ORA-01589: 要打開數(shù)據(jù)庫則必須使用 RESETLOGS 或
NORESETLOGS 選項(xiàng)
SQL> alter database open resetlogs;
alter database
open resetlogs
*
ERROR 位于第 1 行:
ORA-01113: 文件 1 需要介質(zhì)恢復(fù)
ORA-01110:
數(shù)據(jù)文件 1: 'E:\ORACLE\ORADATA\EYGLE\SYSTEM01.DBF'
SQL> recover database
using backup controlfile;
ORA-00279: 更改 1670743 (在 04/17/2008 14:13:16 生成)
對于線程 1 是必需的
ORA-00289: 建議: E:\ORACLE\ORA92\RDBMS\ARC00030.001
ORA-00280:
更改 1670743 對于線程 1 是按序列 # 30 進(jìn)行的
指定日志: {<RET>=suggested | filename |
AUTO | CANCEL}
E:\oracle\oradata\EYGLE\REDO01.LOG
ORA-00310: 存檔日志包含序列
29;要求序列 30
ORA-00334: 歸檔日志:
'E:\ORACLE\ORADATA\EYGLE\REDO01.LOG'
SQL> recover database using
backup controlfile;
ORA-00279: 更改 1670743 (在 04/17/2008 14:13:16 生成) 對于線程 1
是必需的
ORA-00289: 建議: E:\ORACLE\ORA92\RDBMS\ARC00030.001
ORA-00280: 更改
1670743 對于線程 1 是按序列 # 30 進(jìn)行的
指定日志: {<RET>=suggested | filename |
AUTO |
CANCEL}
E:\oracle\oradata\EYGLE\REDO02.LOG
已應(yīng)用的日志。
完成介質(zhì)恢復(fù)。
SQL>
alter database open resetlogs;
數(shù)據(jù)庫已更改。
OK,搞定了!
首先來看問題,然后來看函數(shù)的定義,其實(shí)什么都在函數(shù)定義里面說明白了
1.正則表達(dá)式字符串問題
首先輸入的regex是一個(gè)正則表達(dá)式,而不是一個(gè)普通的字符串,所以導(dǎo)致很多在正則表達(dá)式里面有特殊意義的比如 "." "|" "\" ,如果直接使用是不行的,另外一個(gè)方面我們輸入的regex是以字符串形式傳遞的,對有些字符必須要轉(zhuǎn)義,尤其是"\",下面請看例子
String[] aa = "aaa|bbb|ccc".split("|");//wrong
String[] aa = "aaa|bbb|ccc".split("\\|"); //
String[] aa = "aaa*bbb*ccc".split("*");//wrong
String[] aa = "aaa|bbb|ccc".split("\\*");
String[] aa = "aaa*bbb*ccc".split(".");//wrong
String[] aa = "aaa|bbb|ccc".split("\\.");
String[] aa = "aaa\\bbb\\bccc".split("\\");//wrong
String[] aa = "aaa\\bbb\\bccc".split("\\\\");
2.數(shù)組長度的問題
String a = "";
String[] b = a.split(",");
b.length為 1;
*
String a = "c";
String[] b = a.split(",");
b.length為 1;
**
String a = "c,,,";
String[] b = a.split(",");
b.length為 1;
***
String a = "c,,c";
String[] b = a.split(",");
b.length為 3;
****
String a = ",";
String[] b = a.split(",");
b.length為 0;
其實(shí)只要添加一個(gè)參數(shù)即可,例如
String str = "abcdef,ghijk,lmno,pqrst,,,";
String[] array = str.split(",");
輸出:abcdef,ghijk,lmno,pqrst,
String str = "abcdef,ghijk,lmno,pqrst,,,";
String[] array = str.split(",",-1);
輸出:abcdef,ghijk,lmno,pqrst,,,,
public String [] split (String regex, int limit)
最后一個(gè)參數(shù)limit是影響返回?cái)?shù)組的長度的
=========================請關(guān)注紅色字體(括號(hào)內(nèi)為注釋)==========================================
public String[] split(String regex)
- 根據(jù)給定的正則表達(dá)式的匹配來拆分此字符串。
該方法的作用就像是使用給定的表達(dá)式和限制參數(shù) 0 來調(diào)用兩參數(shù)
split
方法。因此,結(jié)果數(shù)組中不包括結(jié)尾空字符串(直接使用會(huì)造成數(shù)組大小問題)。例如,字符串 "boo:and:foo" 產(chǎn)生帶有下面這些表達(dá)式的結(jié)果:
Regex 結(jié)果 : { "boo", "and", "foo" } o { "b", "", ":and:f" } - 參數(shù):
regex
- 定界正則表達(dá)式- 返回:
- 字符串?dāng)?shù)組,根據(jù)給定正則表達(dá)式的匹配來拆分此字符串,從而生成此數(shù)組。
public String[] split(String regex,
int limit)
- 根據(jù)匹配給定的正則表達(dá)式來拆分此字符串。
此方法返回的數(shù)組包含此字符串的每個(gè)子字符串,這些子字符串由另一個(gè)匹配給定的表達(dá)式的子字符串終止或由字符串結(jié)束來終止。數(shù)組中的子字符串按它們在此字符串中的順序排列。如果表達(dá)式不匹配輸入的任何部分,則結(jié)果數(shù)組只具有一個(gè)元素,即此字符串。
limit 參數(shù)控制模式應(yīng)用的次數(shù),因此影響結(jié)果數(shù)組的長度。如果該限制 n 大于 0,則模式將被最多應(yīng)用 n - 1 次,數(shù)組的長度將不會(huì)大于 n,而且數(shù)組的最后項(xiàng)將包含超出最后匹配的定界符的所有輸入。如果 n 為非正,則模式將被應(yīng)用盡可能多的次數(shù),而且數(shù)組可以是任意長度。如果 n 為零,則模式將被應(yīng)用盡可能多的次數(shù),數(shù)組可有任何長度,并且結(jié)尾空字符串將被丟棄。
例如,字符串 "boo:and:foo" 使用這些參數(shù)可生成下列結(jié)果:
Regex Limit 結(jié)果 : 2 { "boo", "and:foo" } : 5 { "boo", "and", "foo" } : -2 { "boo", "and", "foo" } o 5 { "b", "", ":and:f", "", "" } o -2 { "b", "", ":and:f", "", "" } o 0 { "b", "", ":and:f" } 這種形式的方法調(diào)用 str.split(regex, n) 產(chǎn)生與以下表達(dá)式完全相同的結(jié)果:
Pattern
.compile
(regex).split
(str, n) - 參數(shù):
regex
- 定界正則表達(dá)式limit
- 結(jié)果閾值,如上所述- 返回:
- 字符串?dāng)?shù)組,根據(jù)給定正則表達(dá)式的匹配來拆分此字符串,從而生成此數(shù)組
List<Calendar> l = new ArrayList<Calendar>();
while (true) {
l.add(Calendar.getInstance());
System.out.println(l.size());
}
605473
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Calendar.<init>(Unknown Source)
at java.util.GregorianCalendar.<init>(Unknown Source)
at java.util.Calendar.createCalendar(Unknown Source)
at java.util.Calendar.getInstance(Unknown Source)
at jodatestmemory.Main.main(Main.java:25)
#ifndef CLASS_GEOMETRYTOSTRING
--------------------------------
java --HelloJNI ---
-----GeodbEntity ----
-環(huán)境的搭建,下載與安裝LIBXML2和ICONV
Libxml2是一個(gè)C語言的XML程序庫,可以簡單方便的提供對XML文檔的各種操作,并且支持XPATH查詢,以及部分的支持XSLT轉(zhuǎn)換等功能。Libxml2的下載地址是http://xmlsoft.org/downloads.html,完全版的庫是開源的,并且?guī)в欣映绦蚝驼f明文檔。完全版的文件名為:libxml2-2.7.8.tar.gz。
Libxml2中默認(rèn)的內(nèi)碼是UTF-8,所有使用libxml2進(jìn)行處理的xml文件,必須首先顯式或者默認(rèn)的轉(zhuǎn)換為UTF-8編碼才能被處理。
要在xml中使用中文,就必須能夠在UTF-8和GB2312內(nèi)碼(較常用的一種簡體中文編碼)之間進(jìn)行轉(zhuǎn)換。Libxml2提供了默認(rèn)的內(nèi)碼轉(zhuǎn)換機(jī)制,并且在libxml2的Tutorial中有一個(gè)例子,事實(shí)證明這個(gè)例子并不適合用來轉(zhuǎn)換中文。所以需要我們顯式的使用ICONV來進(jìn)行內(nèi)碼轉(zhuǎn)換,libxml2本身也是ICONV使用進(jìn)行轉(zhuǎn)換的。ICONV是一個(gè)專門用來進(jìn)行編碼轉(zhuǎn)換的庫,基本上支持目前所有常用的編碼。它是glibc庫的一個(gè)部分,常常被用于UNIX系統(tǒng)中。當(dāng)然,在windows下面使用也沒有任何問題。
其下載地址是http://gnuwin32.sourceforge.net/packages/libiconv.htm,文件名為libiconv-1.9.2-1-lib.zip。
將libiconv-1.9.2-1-lib.zip解壓,將其中的iconv.h放入C:\opt\include目錄中,將其中的libiconv.lib放入C:\opt\lib中,并改名為iconv.lib.(沒有opt目錄就新建一個(gè))。
解壓libxml2-2.7.8.tar.gz文件到C盤根目錄,在c:\libxml2-2.7.8\libxml2-2.7.8\win32目錄中存放了多個(gè)Windows平臺(tái)編譯器的Makefile文件,我們使用vs2008,所以待會(huì)會(huì)用Makefile.msvc文件。
1.進(jìn)入Visual Studio 2008 Command Prompt;
2.cd c:\libxml2-2.7.8\libxml2-2.7.8\win32
3.輸入cscript configure.js compiler=msvc prefix=c:\opt include=c:\opt\include lib=c:\opt\lib debug=yes,回車執(zhí)行。
4.最后使用nmake命令進(jìn)行編譯,輸入nmake /f Makefile.msvc并回車。
此時(shí)會(huì)出現(xiàn)一下錯(cuò)誤提示,
Makefile.msvc(465) : fatal error U1020: end-of-file found before next directive
Stop.
網(wǎng)上找了下原因,原來是Makefile.msvc中存在錯(cuò)誤。
將以上三行前面的+號(hào)都刪掉,重新執(zhí)行nmake即可。
在當(dāng)前win32目錄中生成了一個(gè)bin.msvc目錄,其中就有開發(fā)需要的libxml2.lib和libxml2.dll文件。
RBCXF-CVBGR-382MK-DFHJ4-C69G8
-------------------------------------------------------------------------------------------
GeohashPrefixTree grid = new GeohashPrefixTree(ctx, 12);//< 1 meter == 11 maxLevels
grid刪除最后一行數(shù)據(jù)后,store reload ,因?yàn)閿?shù)據(jù)庫中已經(jīng)沒有數(shù)據(jù)了,所以返回null .
但是ext不認(rèn)這個(gè)東西,所以在service中進(jìn)行判斷。如果數(shù)據(jù)為null ,則返回
"{total:0,gridData:[]}" ;
重新編譯,運(yùn)行后,刪除最后一行數(shù)據(jù),就會(huì)看不到了。
一.問題的提出
/usr/local/webserver/mysql/bin/mysql -u root -h 172.29.141.112 -p -S /tmp/mysql.sock
Enter password:
ERROR 2003 (HY000): Can't connect to MySQL server on '172.29.141.112' (113)
二.問題的分析
出現(xiàn)上述問題,可能有以下幾種可能
1. my.cnf 配置文件中 skip-networking 被配置
skip-networking 這個(gè)參數(shù),導(dǎo)致所有TCP/IP端口沒有被監(jiān)聽,也就是說出了本機(jī),其他客戶端都無法用網(wǎng)絡(luò)連接到本mysql服務(wù)器
所以需要把這個(gè)參數(shù)注釋掉。
2.my.cnf配置文件中 bindaddress 的參數(shù)配置
bindaddress,有的是bind-address ,這個(gè)參數(shù)是指定哪些ip地址被配置,使得mysql服務(wù)器只回應(yīng)哪些ip地址的請求,所以需要把這個(gè)參數(shù)注釋掉。
3.防火墻的原因
通過 /etc/init.d/iptables stop 關(guān)閉防火墻
我的問題,就是因?yàn)檫@個(gè)原因引起的。關(guān)閉mysql 服務(wù)器的防火墻就可以使用了。
三.問題的解決
1. 如果是上述第一個(gè)原因,那么 找到 my.cnf ,注釋掉 skip-networking 這個(gè)參數(shù)
sed -i 's%skip-networking%#skip-networking%g' my.cnf
2. 如果是上述第二個(gè)原因,那么 找到 my.cnf ,注釋掉 bind-address 這個(gè)參數(shù)
sed -i 's%bind-address%#bind-address%g' my.cnf
sed -i 's%bindaddress%#bindaddress%g' my.cnf
最好修改完查看一下,這個(gè)參數(shù)。
3.如果是上述第三個(gè)原因,那么 把防火墻關(guān)閉,或者進(jìn)行相應(yīng)配置
/etc/init.d/iptables stop
四.參考
http://hi.baidu.com/vbkan/blog/item/cd5035030cefee793812bb56.html
http://dev.firnow.com/course/7_databases/mysql/myxl/20090820/169010.html
上面方法不行,下面的可以
步驟1、配置/etc/sysconfig/network-scripts/ifcfg-eth0 里的文件。it動(dòng)力的CentOS下的ifcfg-eth0的配置詳情:
[root@localhost ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE="eth0"
HWADDR="00:0C:29:FD:FF:2A"
NM_CONTROLLED="yes"
ONBOOT="yes"
IPADDR=192.168.1.31
NETMASK=255.255.255.0
GATEWAY=192.168.1.1
BOOTPROTO=static
前面三行是系統(tǒng)睚帶的,后面就是手動(dòng)添加的。
這樣設(shè)置扣,記得重啟網(wǎng)卡:
[root@localhost ~]# /etc/init.d/network stop
[root@localhost ~]# /etc/init.d/network start
行了,現(xiàn)在就可以PING得通網(wǎng)關(guān)了,如果還得上網(wǎng),不必須設(shè)置DNS。設(shè)置DNS就詳見步驟2
步驟2、修改dns
[root@localhost ~]# vi /etc/resolv.conf
在里面添加二個(gè)dns:
nameserver 202.96.134.133
nameserver 8.8.8.8
ok,大攻告成,即可上網(wǎng)了!!!!
The VMware vSphere Web Services SDK includes all the components necessary to work with the VMware vSphere API, including WSDL files, sample code, and libraries. The vSphere Web Services SDK facilitates development of client applications that target the VMware vSphere API. With the vSphere Web Services SDK, developers can create client applications to manage, monitor, and maintain VMware vSphere components, as deployed on VMware®VMware vSphere®ESX®, ESXi™, and VMware®vCenter™ Server systems.
這是官方對vSphere Web Services SDK的介紹,簡單來說就是提供了管理vcenter,ESXi的程序接口,目前支持JAVA和.NET平臺(tái),下面以windows 7平臺(tái)為例,介紹JAVA開發(fā)環(huán)境的部署過程
一、開發(fā)環(huán)境準(zhǔn)備
1、安裝JAVA開發(fā)環(huán)境 J2SE 1.6 b22
安裝到c:\java下,不要安裝到C:\program files下,目錄中有空格,執(zhí)行腳本的時(shí)候會(huì)報(bào)錯(cuò)
2、安裝SOAP工具JAX-WS2.1
http://jax-ws.java.net/2.1.1/index.html
雙擊安裝即可
3、下載vSphere Web Services SDK 5.1
http://communities.vmware.com/community/vmtn/developer/downloads
解壓到c:\devprojects下
二、開發(fā)環(huán)境配置
1、設(shè)置系統(tǒng)變量
JAVA_HOME=C:\java\jdk1.6.0_22
JAVAHOME=C:\java\jdk1.6.0_22
SDKHOME=C:\devprojects
VMKEYSTORE=C:\VMware-Certs\vmware.keystore(稍后介紹安裝過程)
WEBHOME=C:\devprojects\vsphere-ws\java\Axis\lib\wbem.jar
WS_SDK_HOME=C:\devprojects\SDK\vsphere-ws
CLASSPATH=.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;C:\devprojects\SDK\vsphere-ws\java\JAXWS\lib\samples.jar;C:\devprojects\SDK\vsphere-ws\java\JAXWS\lib\vim25.jar(這個(gè)變量很重要)
2、服務(wù)器認(rèn)證
2.1、將ESX Server或Vcenter的證書導(dǎo)入本機(jī),ESXi的證書在/etc/vmware/ssl/rui.crt;Vcenter的證書在C:/Documents and Settings/All Users/Application Data/VMware/VMware VitualCenter/SSL/rui.crt
2.2、證書拷貝到本機(jī)的C:/VMware-Certs目錄下,打開windows7的命令行界面,切換到C:/VMware-Certs目錄下,使用jdk的keytool工具導(dǎo)入證書:
keytool -import -file <certificate-filename> -alias <server-name> -keystore vmware.keystore
其中certificate-filename為rui.crt,service-name可以為服務(wù)器的機(jī)器名或IP地址,運(yùn)行成功后會(huì)在C:/VMware-Certs目錄下生成vmware.keystore文件。
3、重新編譯JAX-WS
如果你的安裝的版本不是JDK 1.6 b22或者SOAP不是用 JAX-WS2.1,就需要重新編譯
打開CMD,切換到C:\devprojects\SDK\vsphere-ws\java\JAXWS\
運(yùn)行build.bat
運(yùn)行成功會(huì)出現(xiàn)會(huì)出現(xiàn)
#cd mysql-5.0.56
#./configure --prefix=/usr/local/mysql --localstatedir=/usr/loal/mysql/data -- libexecdir=/usr/local/mysql/lib --disable-shared
#make
#make install
#cd /usr/local/mysql/
#groupadd -g 1003 mysql
#useradd -g 1003 mysql
#chown -R mysql .
#chgrp -R mysql .
#chown -R mysql lib
#./bin/mysql_install_db --user=mysql //以mysql的用戶身份安裝
#chown -R root .
#./bin/mysqld_safe --user=mysql & //在后臺(tái)啟動(dòng)mysql
# cd /root/mysql-5.0.56
# cp support-files/my-medium.cnf /etc/my.cnf
# cp support-files/mysql.server /etc/rc.d/init.d/mysqld
# chmod 700 !$
# chkconfig --add mysqld
# chkconfig --list mysqld
mysqld 1:off 2:on 3:on 4:on 5:on 6:off
# service mysqld start[restart/reload/stop]
# vi /etc/my.cnf
add this:(防止mysql服務(wù)器無查詢后8小時(shí)自動(dòng)重連)
wait_timeout = 86400
#/usr/local/mysql/bin/mysqladmin -uroot password 'aptech'
#./bin/mysql -uroot -paptech
#cd bind-9.5.0-P2
#./configure --prefix=/usr/local/bind9 --with-dlz-mysql=/usr/local/mysql --enable-threads=no
#make
#make install
3、創(chuàng)建database,table
key "rndc-key" {
algorithm hmac-md5;
secret "c4aUV+N7GbOF773V+/LnAA==";
};
controls {
inet 127.0.0.1 port 953
allow { 127.0.0.1; } keys { "rndc-key"; };
};
# End of named.conf
options {
directory "/usr/local/bind9/etc/";
pid-file "/usr/local/bind9/var/run/named.pid";
allow-query { any; };
recursion no;
version "gaint-d1";
};
include "/usr/local/bind9/etc/cnc.cl";
include "/usr/local/bind9/etc/other.cl";
view "cnc-user" {
match-clients { cnc; };
dlz "Mysql zone" {
database "mysql
{host=localhost dbname=mydata ssl=false port=3306 user=root pass=aptech}
{select zone from cnc_dns_records where zone = '%zone%'}
{select ttl, type, mx_priority, case when lower(type)='txt' then concat('/"', data,
'/"')
when lower(type) = 'soa' then concat_ws('
', data, resp_person, serial, refresh, retry, expire, minimum) else data end as mydata from
cnc_dns_records where zone = '%zone%' and host = '%record%'}";
};
};
view "other-user" {
match-clients { other; };
dlz "Mysql zone" {
database "mysql
{host=localhost dbname=mydata ssl=false port=3306 user=root pass=aptech}
{select zone from other_dns_records where zone='%zone%'}
{select ttl, type, mx_priority, case when lower(type) = 'txt' then concat('/"', data,
'/"')
when lower(type)='soa' then concat_ws('
', data, resp_person, serial, refresh, retry, expire, minimum) else data end as mydata from
other_dns_records where zone = '%zone%' and host = '%record%'}";
};
};
[root@dlz etc]# less cnc.cl
acl "cnc"{
192.168.9.0/24;
};
acl "other" {
127.0.0.0/18;
};
06-Mar-2009 22:23:02.569 starting BIND 9.5.0-P2 -gc /usr/local/bind9/etc/named.conf
06-Mar-2009 22:23:02.579 loading configuration from '/usr/local/bind9/etc/named.conf'
06-Mar-2009 22:23:02.583 listening on IPv4 interface lo, 127.0.0.1#53
06-Mar-2009 22:23:02.586 listening on IPv4 interface eth0, 192.168.1.5#53
06-Mar-2009 22:23:02.588 Loading 'Mysql zone' using driver mysql
06-Mar-2009 22:23:02.604 default max-cache-size (33554432) applies: view cnc-user
06-Mar-2009 22:23:02.609 Loading 'Mysql zone' using driver mysql
06-Mar-2009 22:23:02.612 default max-cache-size (33554432) applies: view other-user
06-Mar-2009 22:23:02.616 default max-cache-size (33554432) applies: view _bind
06-Mar-2009 22:23:02.621 command channel listening on 127.0.0.1#953
06-Mar-2009 22:23:02.621 ignoring config file logging statement due to -g option
06-Mar-2009 22:23:02.623 running
癥狀:系統(tǒng)運(yùn)行了一段時(shí)間報(bào)錯(cuò):java.sql.SQLException: ORA-01000: 超出打開游標(biāo)的最大數(shù)
step 1:
查看數(shù)據(jù)庫當(dāng)前的游標(biāo)數(shù)配置slqplus:show parameter open_cursors;
step 2:
查看游標(biāo)使用情況:
select o.sid, osuser, machine, count(*) num_curs
from v$open_cursor o, v$session s
where user_name = 'user' and o.sid=s.sid
group by o.sid, osuser, machine
order by num_curs desc;
此處的user_name='user'中,user代表占用數(shù)據(jù)庫資源的數(shù)據(jù)庫用戶名.
step 3:
查看游標(biāo)執(zhí)行的sql情況:
select o.sid q.sql_text
from v$open_cursor o, v$sql q
where q.hash_value=o.hash_value and o.sid = 123;
step 4:
根據(jù)游標(biāo)占用情況分析訪問數(shù)據(jù)庫的程序在資源釋放上是否正常,如果程序釋放資源沒有問題,則加大游標(biāo)數(shù)。
alter system set open_cursors=2000 scope=both;
補(bǔ)充:在java代碼中,執(zhí)行conn.createStatement()和conn.prepareStatement()的時(shí)候,實(shí)際上都是相當(dāng)與在數(shù)據(jù)庫中打開了一個(gè)cursor。尤其是,如果你的createStatement和prepareStatement是在一個(gè)循環(huán)里面的話,就會(huì)非常容易出現(xiàn)這個(gè)問題。因?yàn)橛螛?biāo)一直在不停的打開,而且沒有關(guān)閉。
一般來說,我們在寫Java代碼的時(shí)候,createStatement和prepareStatement都應(yīng)該要放在循環(huán)外面,而且使用了這些Statment后,及時(shí)關(guān)閉。最好是在執(zhí)行了一次executeQuery、executeUpdate等之后,如果不需要使用結(jié)果集(ResultSet)的數(shù)據(jù),就馬上將Statment關(guān)閉,調(diào)用close()方法。
1 做產(chǎn)品經(jīng)理,而不是功能經(jīng)理;
2 做產(chǎn)品需求,而不是用戶需求;
3 要錦上添花,而不是畫蛇添足;
4 追求人性化,而不是追求完美。
產(chǎn)品經(jīng)理是個(gè)很奇怪的崗位,好像大多數(shù)人都能做,因?yàn)槊總€(gè)人對某個(gè)產(chǎn)品都有自己的看法,都能提出一些意見和想法,甚至能設(shè)計(jì)實(shí)現(xiàn)原理;也好像大多數(shù)人都做不好產(chǎn)品經(jīng)理,因?yàn)榛ヂ?lián)網(wǎng)上成千上萬個(gè)產(chǎn)品,大部分是垃圾,沒幾個(gè)產(chǎn)品是用戶真心覺得很不錯(cuò)的。
我做產(chǎn)品經(jīng)理,還不到兩年,以前十來年一直在做技術(shù)。之前做技術(shù)的時(shí)候,我很看不上產(chǎn)品經(jīng)理。當(dāng)時(shí)想:產(chǎn)品經(jīng)理自己什么都實(shí)現(xiàn)不了,每天就是提點(diǎn)想法,而且想法還經(jīng)常不靠譜,如果哪天裁員,產(chǎn)品經(jīng)理的位置最危險(xiǎn)了;但等我轉(zhuǎn)來做了產(chǎn)品經(jīng)理,想法發(fā)生了根本的變化:嗯,產(chǎn)品經(jīng)理太重要的,一個(gè)產(chǎn)品的未來就決定在產(chǎn)品經(jīng)理身上。
你問我現(xiàn)在如何看待技術(shù)人員?嘿嘿,我現(xiàn)在覺得,技術(shù)就是一把刀,讓它殺誰就殺誰!當(dāng)然,這只是開玩笑。一個(gè)好的技術(shù)團(tuán)隊(duì)對于產(chǎn)品經(jīng)理來說,那是相當(dāng)重要。
對如何做產(chǎn)品經(jīng)理,我還真的是小學(xué)生,自己負(fù)責(zé)的淘寶搜索最近兩年也沒什么大提升。特別是看了周鴻祎、張小龍關(guān)于對產(chǎn)品的一些訪談以后,我更發(fā)現(xiàn)自己在這方面的差距。
不過我有個(gè)優(yōu)點(diǎn),就是善于學(xué)習(xí)、思考、總結(jié)并分享。而且作為一個(gè)外行進(jìn)入到這個(gè)領(lǐng)域,觀察的角度也會(huì)不一樣。這一年多下來,也找到一些感覺,發(fā)現(xiàn)周圍的一些產(chǎn)品經(jīng)理,容易走入一些誤區(qū),分享給大家。
1 做產(chǎn)品經(jīng)理,而不是功能經(jīng)理。
這句話我最早是聽天貓總裁逍遙子說的,當(dāng)時(shí)沒有感覺,現(xiàn)在發(fā)現(xiàn)非常有道理,因?yàn)橹車嗟漠a(chǎn)品經(jīng)理實(shí)際上是在做一名功能經(jīng)理。
他們只是不停的在接產(chǎn)品功能需求,然后不停實(shí)現(xiàn)產(chǎn)品功能。缺登錄,設(shè)計(jì)一個(gè)登錄框;沒有數(shù)據(jù),找某個(gè)平臺(tái)打通一下;管理不方便,設(shè)計(jì)一個(gè)工具來管理;頁面不美觀,重新規(guī)劃一下頁面結(jié)構(gòu)……
功能經(jīng)理,每天都很忙,關(guān)注還有多少需求在后面排隊(duì),需求方是否得到滿足。而用戶體驗(yàn)到底如何,功能是否真的真有價(jià)值,是否可以更加完美,功能經(jīng)理很少關(guān)心。當(dāng)有人抱怨某個(gè)功能不爽的時(shí)候,他會(huì)說:
這個(gè)功能我已經(jīng)有了啊,你說體驗(yàn)不太好?沒辦法,工程師資源太緊張啊,你說為啥設(shè)計(jì)的這么別扭?kao,想起來就來氣,大老板非要求這樣啊,我們也只能這樣設(shè)計(jì),沒辦法!
他經(jīng)常表達(dá)的語氣是他也不得已而為之,把責(zé)任都推到其他人身上。
然而做一個(gè)合格的產(chǎn)品經(jīng)理,需要關(guān)注用戶的體驗(yàn),真正關(guān)注用戶的反饋,關(guān)注數(shù)據(jù)的質(zhì)量,關(guān)注每一個(gè)細(xì)節(jié)。就像買一雙鞋一樣,不只是能穿,還要考慮是否合腳,是否舒服,款式是否漂亮。
有一次開會(huì),淘寶的總裁語嫣姐姐說了一句很樸素但很有道理的一句話:產(chǎn)品能用和好用完全不是一回事!
(大家不用批評(píng)淘寶搜索啊,我知道很多地方還不好用。大家再給我點(diǎn)時(shí)間,我也認(rèn)識(shí)到這個(gè)問題不是......)
2 實(shí)現(xiàn)產(chǎn)品需求,而不是用戶需求。
這個(gè)話題很有意思。當(dāng)你問用戶需要什么的時(shí)候,他會(huì)回答他需要一匹更快的馬。喬布斯說,永遠(yuǎn)不要問用戶想要什么!因?yàn)橛脩舳际巧倒希恢雷约合胍裁础?/span>
這其實(shí)是產(chǎn)品經(jīng)理經(jīng)常把用戶需求當(dāng)成產(chǎn)品需求。對所有用戶說的,他們沒錯(cuò),提的都是自己的期望,不是一個(gè)產(chǎn)品需求。前些天有張小龍的采訪,張小龍說他不看用戶的數(shù)據(jù)。其實(shí)張小龍很關(guān)心用戶的需求,我和張小龍?jiān)谝粋€(gè)群里,如果有人在群里提一些微信使用不爽的功能,張小龍會(huì)很快給出反饋。
這些產(chǎn)品大神們,背后的意思是,不應(yīng)該簡單滿足用戶需求,而應(yīng)該思考把用戶需求提煉成產(chǎn)品需求。當(dāng)一個(gè)產(chǎn)品的用戶有上百萬上千萬的時(shí)候,產(chǎn)品需求的理解和提煉,就相當(dāng)重要。
這個(gè)道理比較容易理解,不做多解釋。
3 要錦上添花,而不是畫蛇添足。
互聯(lián)網(wǎng)的發(fā)展,讓很多互聯(lián)網(wǎng)產(chǎn)品經(jīng)理有個(gè)慣性:做產(chǎn)品迭代要快。快速上線,快速修改。這里也有誤區(qū),對于一些基本功能,確實(shí)要快速上線,快速迭代。因?yàn)橛惺袌龈偁帲枰焖偾腥胧袌觯@得用戶。然而大部分的產(chǎn)品經(jīng)理,沒有機(jī)會(huì)從零開始設(shè)計(jì)一個(gè)新產(chǎn)品,大部分時(shí)候在現(xiàn)有的產(chǎn)品上做升級(jí)或優(yōu)化。這時(shí)設(shè)計(jì)的很多功能,都是錦上添花的功能,還真不能太快。
錦上添花的功能,同樣重要,會(huì)讓產(chǎn)品更好玩,更有意思,更有特點(diǎn)。例如微信最早設(shè)計(jì)的搖一搖功能、朋友圈功能。微博的微刊功能、之前的送禮物的功能。
問題在于,錦上添花,添上去的一定是一朵花,說得俗一點(diǎn),不能添上去是一坨屎。如果是后者,那么就有點(diǎn)畫蛇添足了,或者成了雞肋功能。
什么是一朵花?就是功能添加上去以后,會(huì)讓用戶眼前一亮。給人有“哇!!!”的感覺……
遺憾的是淘寶搜索之前的很多功能添上去的都不是一朵花,上線了太多的畫蛇添足的功能。這些功能一旦上線,就很難下線。因?yàn)楫?dāng)你產(chǎn)品的用戶群有上億的時(shí)候,再爛的一個(gè)功能,每天也會(huì)有幾十萬用戶在使用。一旦你下線,會(huì)有很多人很不爽。
淘寶搜索的同店購就有點(diǎn)這個(gè)味道。技術(shù)實(shí)現(xiàn)成本高,體驗(yàn)一般,用的人也不多。有一段時(shí)間我們把這個(gè)功能隱藏起來了,有人在微博上說:
媽的,我現(xiàn)在最想做的事情,就是找把刀殺個(gè)淘寶搜索的產(chǎn)品經(jīng)理來解解恨,我居然死活找不到我最常用的同店購了!
畫蛇添足的功能越多,讓產(chǎn)品背負(fù)的垃圾就越多,造成好的功能沒有資源做,差的功能又無法下線。
4 追求人性化,而不是追求完美。
很多產(chǎn)品經(jīng)理,追求完美。這是作為產(chǎn)品經(jīng)理很好的品質(zhì),然而,有一點(diǎn)卻經(jīng)常被產(chǎn)品經(jīng)理忽視,產(chǎn)品的人性化。
永遠(yuǎn)沒有完美的產(chǎn)品,特別是當(dāng)一個(gè)產(chǎn)品的用戶量到達(dá)上百萬上千萬的時(shí)候。用戶的喜好千差萬別。如何讓用戶能喜歡產(chǎn)品的優(yōu)點(diǎn)的同時(shí)能容忍產(chǎn)品的缺點(diǎn)?
大家看選美大賽獲勝的美女,經(jīng)常會(huì)有感嘆,為什么這么丑還能得前三啊!是因?yàn)樵u(píng)委的口味太特別?當(dāng)然有一部分評(píng)委原因,但更多原因在于,大家每個(gè)人的審美觀不一樣。大家是把選美冠軍作為一個(gè)完美的人來評(píng)判。
實(shí)際上,無論選出誰是冠軍,都會(huì)有人覺得難看。任何一個(gè)產(chǎn)品,無論產(chǎn)品經(jīng)理推出多么好用的功能,都會(huì)有人不喜歡!
然而,大家對待周圍的朋友,就不會(huì)用選美的標(biāo)準(zhǔn)要求他們,他們有明顯的缺點(diǎn),但也有很多值得欣賞的地方。大家訂閱鬼腳七的微信,絕大部分人不會(huì)期望,鬼腳七每天的文章都會(huì)符合自己的口味。有人不看文章,只看看【7哥閑談】也會(huì)覺得很有意思。為什么?因?yàn)榇蠹也粫?huì)期待鬼腳七這個(gè)賬號(hào)是個(gè)完美的賬號(hào),把鬼腳七作為一個(gè)朋友在看待。鬼腳七有缺點(diǎn),也有優(yōu)點(diǎn)。
如果能讓用戶把我們的產(chǎn)品當(dāng)成周圍的朋友來看待呢?感覺會(huì)完全不一樣。
淘寶有個(gè)做運(yùn)營的同事有一天跟我感嘆說:我忽然覺得攻城獅們離我好近,每個(gè)攻城獅內(nèi)心都住著個(gè)詩人!我問為什么會(huì)忽然有這種感覺?她說有一天晚上,發(fā)現(xiàn)在淘寶內(nèi)部一個(gè)TMS系統(tǒng)的標(biāo)題欄上忽然多了一句話:
每個(gè)人的壓力,少部分來自生存,大部分來自攀比。
就這一句話,讓用戶感覺到了產(chǎn)品背后的那位工程師。還記得微信有個(gè)版本的歡迎頁面上的文字嗎:
少發(fā)微信,多和朋友見見面!
就這一句話,讓我感覺到產(chǎn)品背后的那群人的心理活動(dòng)。微信的一些小瑕疵,我也能容忍。
就是這句話,我喜歡上了微信。
人性化,是不是讓產(chǎn)品開始具有了靈魂?
如何讓產(chǎn)品更加人性化?如何讓淘寶搜索更加人性化?是我最近一直在思考的問題。我定義2013年搜索的關(guān)鍵詞:專業(yè)和有趣。希望2013年能讓更多的人把淘寶搜索當(dāng)成一個(gè)朋友,而不是一個(gè)工具。
寫了這么多,回頭看看我這篇文章,好像沒有什么產(chǎn)品設(shè)計(jì)方法,只是一些思考,僅此而已。
作者介紹:
鬼腳七,一個(gè)簡單的人,分享電商資訊、搜索變化、淘寶動(dòng)態(tài)、產(chǎn)品設(shè)計(jì)、管理心得、生活感悟;偶爾文藝,偶爾深沉。做一個(gè)有思想的人!微信賬號(hào): taobaoguijiaoqi 加為好友后回復(fù) m 可以看到作者之前的所有文章。