注意事項:
1.單向一對多
只需在“一”放進行配置
2.雙向一對多
需要在關聯雙方都加以配置,而且需要在一的一方設置inverse=true
首先是實體類:
TAddress.java(多的一方)
public class TAddress implements Serializable {
private static final long serialVersionUID = 1121137857691229229L;
private Integer id;
private String address;
private String zipcode;
private String tel;
private String type;
private TUser user; //必須有
............
}
TUser.java(一的一方)
public class TUser implements Serializable {
private static final long serialVersionUID = 1224691192698621789L;
private Integer id;
private Integer age;
private String name;
@SuppressWarnings("rawtypes")
private Set address = new HashSet(); //多的一方放在集合中
....................
}
然后是各個實體類的配置文件
TAddress.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<!-- 一對多 -->
<hibernate-mapping>
<class name="com.model.TAddress" table="t_address"
dynamic-update="false" dynamic-insert="false">
<id name="id" type="java.lang.Integer" column="id" unsaved-value="0">
<generator class="native" />
</id>
<property name="address" column="address" type="string" />
<property name="tel" column="tel" type="string" />
<property name="zipcode" column="zipcode" type="string" />
<property name="type" column="type" type="string" />
<!-- 必須有many-to-one 否則關聯字段(user_id)為null -->
<many-to-one name="user"
class="com.model.TUser"
cascade="none"
outer-join="auto"
update="true"
insert="true"
access="property"
column="user_id"
not-null="true">
</many-to-one>
</class>
</hibernate-mapping>
TUser.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<!-- 一對多 外鍵關聯 -->
<!-- Select from TUser where id=1 Select from TUser where id=1 to Select
from TUser where id=1 or id=2 -->
<!-- batch-size 批量加載機制 可以自定義每次批量加載的數量 -->
<hibernate-mapping>
<class name="com.model.TUser" table="t_user" dynamic-update="true"
>
<id name="id" type="java.lang.Integer" column="id" unsaved-value="0">
<generator class="native" />
</id>
<property name="name" column="name" />
<property name="age" column="age" />
<set name="address" table="t_address" cascade="all" order-by="zipcode asc"
lazy="true" inverse="true">
<key column="user_id" /><!-- 確定關聯的外鍵列 -->
<one-to-many class="com.model.TAddress" />
</set>
</class>
</hibernate-mapping>
其次是hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- properties -->
<!-- 數據庫URL -->
<property name="hibernate.connection.url">jdbc:mysql://localhost/onetomany</property>
<!-- 數據庫JDBC驅動 -->
<property name="hibernate.connection.driver_class">org.gjt.mm.mysql.Driver</property>
<!-- 數據庫用戶名 -->
<property name="hibernate.connection.username">root</property>
<!-- 數據庫密碼 -->
<property name="hibernate.connection.password">hello</property>
<!-- 數據庫方言 -->
<property name="dialect">net.sf.hibernate.dialect.MySQLDialect</property>
<!-- 是否日志調試 -->
<property name="show_sql">true</property>
<!-- 是否使用數據庫外連接 -->
<property name="use_outer_join">true</property>
<!-- 事務管理 使用JDBC Transaction(使用JTA會報錯) -->
<property name="transaction.factory_class">
net.sf.hibernate.transaction.JDBCTransactionFactory
</property>
<!-- 指定hibernate每次提交的SQL數量 對批量操作的性能提升幫助很大!!!!!!!!!!!!! -->
<property name="hibernate.jdbc.batch_size">25</property>
<!-- 映射文件配置,配置文件名必須包含其相對于根的全路徑 -->
<mapping resource="com/model/TUser.hbm.xml" />
<mapping resource="com/model/TAddress.hbm.xml" />
</session-factory>
</hibernate-configuration>
測試代碼(部分)
增加
public void testSave(){
try {
Transaction tx=session.beginTransaction();
// TUser user=(TUser) session.load(TUser.class, 1);
TUser user=new TUser();
user.setName("zhangsan");
user.setAge(20);
TAddress address=new TAddress();
address.setAddress("jingsan");
address.setTel("1361380");
address.setZipcode("45000");
address.setType("java");
address.setUser(user); //設置關聯的TUser對象
user.getAddress().add(address);
session.save(user); //級聯更新
tx.commit();
} catch (HibernateException e) {
e.printStackTrace();
}
}
查詢
public void testLoad(){
try {
Transaction tx=session.beginTransaction();
String hql="from TUser where name='zhangsan'";
List list=session.createQuery(hql).list();
System.out.println("-------------1------------");
Iterator iter=list.iterator();
while(iter.hasNext()){
TUser user=(TUser) iter.next();
System.out.println("--------------2------------");
System.out.println("user.name="+user.getName());
System.out.println("--------------3------------");
System.out.println("user.address="+user.getAddress().size());
System.out.println("--------------4------------");
}
} catch (HibernateException e) {
e.printStackTrace();
}
}
批量插入(可以提高性能)
實現機制:如果使用了批量加載機制,hibernate在進行數據查詢操作前,會自動在當前session中尋找是否還存在
其他同類型待加載的數據,如果有,則將其查詢條件合并在當前的select語句中一并提交,這樣,通過
一次數據庫操作即完成了多個讀取任務。
//批量插入操作性能優化 通過配置<property name="hibernate.jdbc.batch_size">25</property>
public void testBatchInsert(){
long start=System.currentTimeMillis();
this.importUserList();
long end=System.currentTimeMillis();
System.out.println("批量插入花費時間是"+(end-start));
}
public void importUserList(){
try {
Transaction tx=session.beginTransaction();
for(int i=0;i<10000;i++){
TUser user=new TUser();
user.setName("user"+i);
session.save(user);
if(i%25==0){ //以每25個數據作為一個處理單元
session.flush();
session.clear();
}
}
tx.commit();
} catch (HibernateException e) {
e.printStackTrace();
}
}
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- properties -->
<!-- 數據庫URL -->
<property name="hibernate.connection.url">jdbc:mysql://localhost/tablepersubclass</property>
<!-- 數據庫JDBC驅動 -->
<property name="hibernate.connection.driver_class">org.gjt.mm.mysql.Driver</property>
<!-- 數據庫用戶名 -->
<property name="hibernate.connection.username">root</property>
<!-- 數據庫密碼 -->
<property name="hibernate.connection.password">hello</property>
<!-- 數據庫方言 -->
<property name="dialect">net.sf.hibernate.dialect.MySQLDialect</property>
<!-- 是否日志調試 -->
<property name="show_sql">true</property>
<!-- 是否使用數據庫外連接 -->
<property name="use_outer_join">true</property>
<!-- 事務管理 使用JDBC Transaction(使用JTA會報錯) -->
<property name="transaction.factory_class">
net.sf.hibernate.transaction.JDBCTransactionFactory
</property>
<!-- 映射文件配置,配置文件名必須包含其相對于根的全路徑 -->
<mapping resource="com/model/TItem.hbm.xml" />
</session-factory>
</hibernate-configuration>
把日志調試設置為true,需要log4j.properties配置文件支持
log4j.properties
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### direct messages to file hibernate.log ###
#log4j.appender.file=org.apache.log4j.FileAppender
#log4j.appender.file.File=hibernate.log
#log4j.appender.file.layout=org.apache.log4j.PatternLayout
#log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### set log levels - for more verbose logging change 'info' to 'debug' ###
log4j.rootLogger=warn, stdout
log4j.logger.net.sf.hibernate=info
### log just the SQL
#log4j.logger.net.sf.hibernate.SQL=debug
### log JDBC bind parameters 把這一行改為debug ###
log4j.logger.net.sf.hibernate.type=debug
### log schema export/update ###
log4j.logger.net.sf.hibernate.tool.hbm2ddl=debug
### log cache activity ###
#log4j.logger.net.sf.hibernate.cache=debug
### log jdbc resource acquisition
#log4j.logger.net.sf.hibernate.impl.BatcherImpl=debug
### enable the following line if you want to track down connection ###
### leakages when using DriverManagerConnectionProvider ###
#log4j.logger.net.sf.hibernate.connection.DriverManagerConnectionProvider=trace
一直想學Linux,在校期間有Linux選修課,看到教員在上課侃侃而談、命令操縱隨心而動……
最近項目忙完了,就開始著手學習。本人安裝的Redhat AS4,相關安裝步驟網上有很多,就不再詳細介紹了。(如有需要再單獨寫一遍安裝、初步使用等文章)
安裝完成后輸入賬戶進入系統就開始進行Linux命令學習。
創建用戶:
useradd chenyang【用戶名】 ---添加用戶
passwd chenyang【用戶名】 ---設置密碼


注:新建用戶"chenyang"在/home下面
用戶之間切換用:su
清屏命令:clear
顯示當前用戶:whoami
userdel chenyang【用戶名】 ---刪除用戶

userdel –rf chenyang【用戶名】 ---刪除用戶所在的目錄

創建組:
groupadd newgroup【組名】 ---添加組
注:新建組在/etc下面,用more group查看

groupdel newgroup 【組名】 ---刪除組

安裝JDK:
1.
先查看系統是否有默認的jdk rpm -qa|grep gcj
如果有可以選擇卸載或繼續使用 卸載:rpm –e 要卸載的jdk
2.
下載jdk for Linux,比如 jdk-6u25-linux-i586-rpm.bin
3.
上傳到Linux系統中,使用SSH SecureShellClient,SSH SecureShellClient是非常好用的把window上的文件上傳到Linux上的工具,我用的是從這http://download.csdn.net/source/3525638下載的,網友可以也可以從別的地方下載
4.
文件上傳到Linux系統中后,需要改變文件權限,不然不能安裝 chmod 777 jdk-6u25-linux-i586-rpm.bin
5.
./jdk-6u25-linux-i586-rpm.bin(中間不能有空格)
6.
安裝jdk rpm -ivh jdk-6u25-linux-i586.rpm
安裝成功后java目錄在/usr下面
7.
配置環境變量
需要進入/etc目錄下,然后vi profile
輸入o就可以像在window下的記事本編輯
export JAVA_HOME=/usr/java/jdk1.6.0_25
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
(至于這樣設置的原因,可以看這篇文章http://www.cnblogs.com/wangchenyang/archive/2011/08/17/2143620.html)
完成后按"Esc"鍵,然后輸入:w就可以保存,退出時輸入:q,可以簡單些,直接輸入:wq
輸入:q!是直接退出不保存
8.測試
寫個test.java文件(文件名不重要)
vi test.java
class test{
public static void main(String[] args){
System.out.println("hello linux");
}
}
javac test.java
java test
若顯示hello linux,恭喜你!jdk正確安裝,否則環境變量等有問題。
從大二開始接觸Java,之后是斷斷續續的學習。大三真正開始Java之旅,估計大部分初學者在學Java時被Java的環境變量搞的暈頭轉向,雖然找到了正確設置環境變量的方式,但其中的原因一知半解,設置壓根不知道是何原因。
今天為止對環境變量的設置還不是很懂,而且網上的大部分資料幾乎都是設置方法,沒有說原因。今天學Linux,遇到了Java環境變量的設置,無意間找到了詳細透徹講解Java環境變量的設置。
“
1. PATH環境變量。作用是指定命令搜索路徑,在shell下面執行命令時,它會到PATH變量所指定的路徑中查找看是否能找到相應的命令程序。我們需要把 jdk安裝目錄下的bin目錄增加到現有的PATH變量中,bin目錄中包含經常要用到的可執行文件如javac/java/javadoc等待,設置好 PATH變量后,就可以在任何目錄下執行javac/java等工具了。
2. CLASSPATH環境變量。作用是指定類搜索路徑,要使用已經編寫好的類,前提當然是能夠找到它們了,JVM就是通過CLASSPTH來尋找類的。我們 需要把jdk安裝目錄下的lib子目錄中的dt.jar和tools.jar設置到CLASSPATH中,當然,當前目錄“.”也必須加入到該變量中。
3. JAVA_HOME環境變量。它指向jdk的安裝目錄,Eclipse/NetBeans/Tomcat等軟件就是通過搜索JAVA_HOME變量來找到并使用安裝好的jdk。
”
在此要感謝“SamCN”,謝謝你的這邊文章,不僅解決了Linux中遇到了問題,而且解決了學Java那么長時間的困惑。謝謝!
尋找出色的產品經理
“哪里能找到出色的產品經理?”CEO經常問我這個問題。
我總是這樣回答:出色的產品經理就在公司里,只不過在其他崗位上,有可能是軟件工程師、用戶體驗設計師、系統工程師,等著伯樂去發掘。無論你打算從公司內部還是從公司外部招聘產品經理,必須清楚合適的人選應該具備哪些特質。這一章,我將列舉產品經理應有的特質。

個人素質和態度
技術可以學習,素質卻難以培養,有些素質是成功的產品經理必不可少的。
~~對產品的熱情
有這樣一群人,他們對產品有一種本能的熱愛,把自己生活中的一切事物都看成產品,懷揣對優秀的產品的熱愛和尊重。這份熱情是產品經理必備的素質,是他們夜以繼日克服困難、完善產品的動力。這份熱情能感染團隊成員,激勵所有人。
辨別這種特質很容易,可以讓應聘者談談自己最喜歡的產品及喜歡的原因,聊聊不同領域的產品和他討厭的產品,問問對方,如果有機會,他打算怎樣完善自己最喜歡的產品。熱情是難以偽裝的,虛偽的做作容易畢露無遺。
~~用戶立場
理想的產品經理不一定來自產品的目標市場(這種情況有利也有弊),但是他必須融入目標市場。這一特質對制造大眾產品的高科技企業尤為難得。我們傾向于從自己的角度去理解用戶和市場。事實上,目標用戶的經驗、喜好、價值觀、知覺能力、忍受程度、技術理解很可能與我們的大相徑庭。
可以就產品的目標市場向應聘者發問,讓他談談如何換位思考。了解應聘者對目標市場的感覺,最重要的是看對方是尊重目標市場希望融入其中,還是打算一意孤行改變用戶習慣。
對國際化的產品和針對特定地域的產品來說,換位思考尤其重要。各種文化雖有共通之處,但也存在許多差異。有些差異對產品無關緊要,有些則至關重要。應該考察應聘者是否足夠了解目標市場,能否區分這兩種差異。
~~智力
人的智力水平是無法替換的。產品管理需要洞察力和判斷力,因此必須具備敏銳的頭腦。勤奮當然是必需的,但從事這項工作光有勤奮還遠遠不夠。
招聘聰明人是項知易行難的任務,結果在很大程度上取決于招聘者的能力和可靠性。常言道,“物以類聚,人以群分”,此言不虛。方法之一是測試應聘者解決問題的能力。微軟令人稱道的、深入而有效的面試,即是考察應聘者解決問題的能力,通常由一位或多位領域專家就一個問題對應聘者進行深入考察。面試官不關心應聘者是否知道正確答案,而看重應聘者解決問題的思路和方法(智力優于知識)。如果應聘者回答正確,面試官會將問題略作調整,詢問應聘者在新情況下如何應付。重復這個過程,直到應聘者被迫處理他不知道答案的情況,說出解決方法。
~~職業操守
每種團隊角色承擔的義務和付出的努力都不相同。產品經理肩負著產品的前途和命運,絕不適合貪圖安逸的人擔任。即便掌握了時間管理和產品管理的技巧,產品經理依然要為產品投入大量精力。成功的產品經理能擁有時間享受清閑的家庭生活嗎?只要具備足夠的經驗,我相信可以做到。但是,如果你期望的是一周只工作四十個小時,下班后把工作拋諸腦后,那是不現實的。
成功的產品經理需要付出多少努力?在這個問題上,我對應聘者向來坦率,產品管理工作絕不能用時間來衡量,付出多少都不為過。緊急情況下臨時找來的“救火隊員”多半不是合適的產品經理人選。
在漫長的項目周期里,產品經理需要付出的努力和承擔的義務并非一成不變。有的階段比較輕松,有的階段則很緊張。但是稱職的產品經理對產品的關注和憂慮程度,以及愿意為之付出努力的熱情是不會改變的。
~~正直
在所有產品團隊成員里,產品經理最能體現公司和產品的價值觀。通常產品經理不直接管理團隊成員,不能要求別人執行命令,所以他必須通過行動影響、說服身邊的同事。這種影響基于相互的信任和尊重,要求產品經理必須是個正直的人。
產品經理是產品團隊、銷售團隊、公司高管之間的樞紐,經常要協調處理各種問題,比如提早供貨、滿足大客戶的特殊要求。產品經理如何處理這些難題,同事們都看在眼里。
信任和尊重需要時間培養,產品經理唯有通過工作展示自己的素質和能力,才能成為真正的團隊領導。如果產品經理對待同事缺乏誠意,懷有私心,一碗水端不平,那么勢必會影響整體團結和工作效率。產品經理雖然不必事事精通,但應當知道每位成員最擅長做什么,尊重大家發揮工作特長的意愿,充分信任大家。
考察一個人是否正直絕不比考察他的智力容易,考察陌生的應聘者是否正直就更難了。對那些有工作經驗的應聘者,可以問問他們如何處理工作中的壓力,多追問工作細節。
~~信心
很多人相信經驗可以讓人產生自信。如果僅憑經驗可以建立信心,為什么許多工作多年的產品經理卻毫無自信?相反,剛剛步入社會的大學畢業生卻往往充滿自信(雖然這種自信通常源自對自身狀況的無知)。
自信是很重要的素質。公司高管、產品團隊、銷售團隊都需要看到產品經理的信心,確信他們投入的時間、金錢、努力不會付之東流。自信的人更有說服力,更容易成為人們愿意追隨的領導者。
~~態度
稱職的產品經理把自己當成產品的CEO,愿意為產品的最終成敗承擔全部責任,絕不找借口。雖然他清楚產品按時成功上市要克服許多困難——開發難度大、開發時間長、成本過高、產品復雜等,但他明白預見和解決這些問題是他的責任。
這并不是說產品經理要事必恭親,監督每個人的工作,而是指出現問題時他應該及時承擔責任,進展順利時他應該及時給大家以鼓勵。稱職的產品經理知道,雖然產品的實現離不開大家的協助,但是他應該對自己的產品創意負責。
技能
掌握一些重要的技能是打造成功產品的關鍵。我相信,只要具備優秀的個人素質,所有技能都可以習得。
~~運用技術的能力
很多成功的產品經理是工程師出身,因為策劃產品在很大程度上取決于對新技術的理解,以及如何應用技術解決相關的問題。
出色的產品經理并不需要自己發明或實現新技術,但必須有能力理解技術、發掘技術的應用潛力。
培養理解技術的能力有多種途徑,可以參加培訓課程,閱讀相關書籍和文章,向程序員和架構師請教,參加開發團隊的頭腦風暴也不失為一種途徑。
~~注意力
產品經理要優先解決重要問題。研發產品的過程中有很多干擾。能否集中注意力解決關鍵問題、克制不斷增加功能的沖動、不受關鍵人物或重要客戶的影響,取決于產品經理是否有足夠強的自律性——不但要遵守公司制度,還要嚴格要求自己。
幾乎所有產品都有些不那么重要的功能——這些功能對提高銷量和用戶滿意度毫無作用。如果去掉這些功能,產品甚至會因為簡單、易用獲得更多用戶的喜愛。我建議過濾多余的功能,縮短研發時間,降低生產成本,讓產品更早上市。
~~時間管理
電子郵件、即時消息和手機構成的世界充滿了干擾。你可能一大早就來上班,拼命工作一整天,連吃飯喝水都顧不上,深夜回到家卻發現到頭來沒完成一件重要工作。時間都用來“救火”和處理“緊急”事件了。
熟練、迅速地區分重要任務和緊急任務,合理地規劃和安排時間是產品經理必備的技能。如果產品經理無法集中精力完成真正重要的任務,那產品就難免命運多舛了。
我認識太多每星期工作七十個小時、累得精疲力竭的產品經理。他們把所有的時間和精力都花在工作上,體力透支到了極限。對他們而言,最可怕的事實莫過于做的都是無用功。為此,我有意在培訓課程中加入了時間管理和合理安排工作任務的內容。產品經理的時間應該用來改變現狀,而不是疲于奔命參加大小會議、逐一回復郵件。有許多事情不值得做。
~~溝通技能
雖然溝通技巧可以學習,但要做到出類拔萃需要經年累月的練習。溝通(包括口頭表達和書面表達)能力是產品經理必備的技能,如前所述,產品經理只能以理服人,絕不能靠職位壓制他人。
口頭表達能力可以在面試中測試,測試書面表達能力則需另尋他法。我常建議應聘者隨身攜帶文字材料證明其書面表達能力,比如,不涉及專利的產品策劃文檔。
注意,如果應聘者使用非母語時帶有口音或有輕微的語法錯誤,不代表其溝通技巧不佳,只要說話口齒清晰、易于理解、具有說服力即可,完美的發音和語法不是必要條件。
產品經理會花許多時間寫電子郵件、產品說明文檔、策劃書、同類產品分析文檔等。聰明的產品經理不會浪費時間寫沒人看的東西,一旦決定動筆就要做到最好,言之有物,讓人信服。
書面表達務必條理清晰、言簡意賅,因為同事(特別是公司高管)會根據這些文字評估產品經理的工作。有時文字材料是他們評判的唯一依據。
還有一種常見的溝通形式是演講。對許多人來說,面對聽眾演講并非易事,有效地表達觀點更是困難。盡管如此,演講是產品經理的家常便飯。產品經理必須用最短的時間向公司高管、大客戶、銷售團隊解釋產品的內涵和重要性。
我們都聽過糟糕的演講——幻燈片一張接一張沒完沒了,演講人死板地朗誦條目,聽眾不得不費勁地揣摩每張圖表的意義,既抓不住重點,也不明白價值何在。
與此相反,成功的產品經理盡可能減少幻燈片的頁數,他們的演講充滿熱情、重點清晰、數據充分、引人入勝,絕不超時(甚至提前結束)。他們更喜歡聽眾提問,即使遇到暫時無法回答的問題,也會努力嘗試向提問者和聽眾闡述自己的理解。杰里·韋斯曼(Jerry
Weissman)的《演講制勝:講故事的藝術》是一本非常好的提高演講水平的指南。
商業技能
作為產品團隊的發言人,產品經理要協調團隊與財務部門、營銷部門、銷售團隊、公司高管之間的工作——必須使用這些人聽得懂的概念和術語。
我認為產品經理應該具備雙語技能。這并非指中文和英文,而是指產品經理既能與程序員討論技術,又能與管理層和營銷人員討論成本結構、邊際效應、市場份額、產品定位和品牌。
由于上述原因,很多產品經理都是商學院畢業的。企業需要懂得商務的人,所以雇用MBA。雖然MBA也可以成長為出色的產品經理,但總的來說商業技能只是產品經理需要具備的多種技能之一,而且完全可以在商學院以外的地方學到。比如,技術人員進入產品管理領域后,通過閱讀、培訓學習商業技能是很常見的事。
去哪里招聘產品經理?
具備以上這些素質和技能條件的人極少見,和優秀的產品一樣稀少。沒有比產品經理更重要的職位了,所以必須用嚴格的標準考察應聘者。
關于招聘產品經理,有許多不同的看法。許多公司認為他們需要的只是營銷部門的人或有MBA學歷的人,就像教科書對產品經理的定義一樣。這種看法也許曾經是正確的,但如今無疑是一種謬論。
許多公司喜歡招聘從頂級商學院畢業、擁有技術類學士文憑、具有行業經驗的MBA。不過別忘了MBA課程幾乎不涉及產品管理。如果你認為現在的MBA畢業生們知道如何管理產品,那就大錯特錯了。
最有效的招聘途徑是尋找具有上述特質潛力的人,通過培訓課程和傳幫帶把他們訓練成高素質的產品經理。這些人可能就藏身于公司內部。我認識許多優秀的產品經理,他們曾經是程序員、用戶體驗設計師、客服人員、技術支持人員、營銷人員,甚至曾經是目標用戶。他們利用各自的經驗進一步完善產品管理工作。出于同樣的原因,公司高管應該聽取不同崗位員工對產品管理的建議。對于高管來說,這是寶貴的經驗。
行業經驗重要嗎?
最近一位朋友向我了解一位產品經理應聘者(大衛)的情況,我曾經和大衛一起工作過。我的朋友是一家大眾網絡服務公司的主管,他非常喜歡大衛,但他心里有個疑問:“大衛是企業級軟件產品方面的專家,他適合我們這種企業嗎?”
我忍不住笑了,告訴他四年前我遇到過類似的問題。當時大衛現在的主管問我:“這個人對系統軟件十分在行,可他能夠做好企業級軟件嗎?”
其實大衛所受的教育與系統軟件、企業級軟件、大眾網絡服務都無關,甚至與軟件技術無關。他是學金融出身的,非常聰明,善于快速進入新領域,理解新技術。
許多產品經理是因為他們的行業經驗獲聘的。經常有人問我產品經理是否必須具備領域和行業經驗,我認為對某些產品來說,專業知識是必要的,比如,研發心臟除顫器,最好有一位懂得心臟護理的產品經理。但這只是個例,并非原則。
我甚至認為資深行業經驗對產品經理的工作可能是不利的,因為長期從事某一行業的人通常會落入一種常見的心理陷阱:他們以為自己了解目標客戶,盲目自信。產品經理應該習慣放下自己的成見。擁有資深行業經驗的人也能做到這一點,但他們必須付出更多努力,保持開放的心態。
我并不是說管理產品不需要行業知識,相反,我覺得了解產品的領域知識(粗淺的了解不算數)是絕對必要的。我相信通過積極學習,高素質的產品經理可以快速熟悉新行業。以我自己為例,熟悉新行業達到自信制定產品策略的程度,只需要兩三個月時間。
我相信開發企業級軟件、系統軟件、大眾網絡服務和消費類電子產品各自有不同的技能要求。例如,企業級軟件的用戶是數目較少的大企業(而不是數量上百萬的消費者),所以有不同的手段了解需求、定義產品;不同類型產品的銷售渠道各不相同;如果產品涉及硬件設備,則必須了解它會對流程和進度造成哪些影響;如果開發大眾網絡服務,必須知道如何展開規模管理和社區管理。
總的來說,我認為產品經理大約有80%的技能和天分可以用于不同類型的產品。
我并非要貶低經驗的價值,但我發現最寶貴的經驗不是行業知識或技術(這些都可能過時),而是打造優秀產品的流程、領導產品團隊的能力、應對產品擴張的經驗、個人對自己的認知,以及自我激勵的能力。
與行業知識密切相關的是技術專長,業界一度非常看重兩者的聯系。有一次,我看到一家企業級軟件公司招聘產品經理,要求應聘者具備開發Linux產品的經驗。的確,不同操作系統之間差異很大,但產品經理如果連處理不同操作系統對產品影響的能力都不具備,那么等待他的麻煩將遠比缺乏Linux知識來得多。
高科技產品行業雖然要求快速學習新技術,但更重要的是預見如何應用技術合理地解決問題。技術發展很快,所以產品經理必須善于快速學習新技術,解決新問題。我面試應聘者時,不關心他們已掌握的知識,只看重他們的學習思路。比如,讓他們回憶研發產品之前,他們需要學習哪些知識,需要多長時間學習,如何利用這些知識。
年齡不是問題
各個年齡段都有出色的產品經理。為什么有人二十五歲就脫穎而出?首先,互聯網真正普及是1995年以后的事情,因此,今天二十五歲左右的人和我們的上網經驗一樣多。互聯網興起時,十幾歲的青少年很快學會了成年人搞不懂的技術。其次,經驗雖然需要時間積累,但其他素質,比如智力和對產品的熱情則與年齡無關。
當年為網景公司年輕的創始人馬克•安德森(Marc
Andreessen)工作時,我不得不適應給這個二十出頭的年輕人打工的事實。但是當我發現他吸收新技術和說服他人的能力后,我很快就忘記了他的年齡。未曾與他謀面的人會認為,擁有這種商業能力的人至少得年過四十。
尋找出色的產品經理不能以年齡、性別或種族作為判斷標準。我知道行業中仍然存在不少偏見。例如,由于重視溝通技巧,我們盡量招聘母語是英語的應聘者。
我指出這一點并不是想譴責誰,只是想提醒大家,無意的偏見可能會讓我們錯過出色的產品經理。下次某個大學畢業生帶著他的產品創意來找你時,你或許應該聽一聽,他的創意很可能是下一個Facebook。
出自:http://www.yixieshi.com/zhichang/8810.html
正常情況下開發人員使用已經定義好的API,這個過程叫Call。但是有時這樣不能滿足需求,就需要程序員注冊自己的程序,然后讓事先定義好多API在合適的時候調用注冊的方法,這叫CallBack。
“當通常大家說的回調函數一般就是按照別人的定好的接口規范寫的,等待別人調用的函數,在C語言中,回調函數通常通過函數指針來傳遞;在Java中,通常就是編寫另外一個類或類庫的人規定一個接口,然后你來實現這個接口,然后把這個實現類的一個對象作為參數傳給別人的程序,別人的程序必要時就會通過那個接口來調用你編寫的函數。”
使用技巧:定一個接口,在接口中聲明我們想調用的方法。
在另一個方法中注冊剛定義的回調接口
package com.call;
public interface Callback {
public void executeMethod();
}
-----------------------------------------------------
package com.call;
public class Tools {
public void getTime(Callback call) {
long start = System.currentTimeMillis();
call.executeMethod();
long end = System.currentTimeMillis();
System.out.println("cost time=" + (end - start));
}
}
---------------------------------------------
package com.call;
//測試執行方法消耗時間
public class Main {
public static void main(String[] args) {
Tools tool = new Tools();
tool.getTime(new Callback() {
public void executeMethod() {
new Main().testMethod();
}
});
}
public void testMethod() {
for (int i = 0; i < 10000; i++) {
System.out.print("");
}
}
}