<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    qileilove

    blog已經(jīng)轉(zhuǎn)移至github,大家請訪問 http://qaseven.github.io/

    論如何進(jìn)行有效的需求管理

     論文摘要:
      本文主要討論如何更有效的進(jìn)行需求管理,需求管理中需求考慮的一些問題,項目中事先識別的風(fēng)險和沒有預(yù)料到而發(fā)生的變更等風(fēng)險的應(yīng)對措施的分析,也包括項目中發(fā)生的變更和項目中發(fā)生問題的分析統(tǒng)計,以及需求管理中的一些應(yīng)對措施。
      關(guān)鍵字:
      需求管理, 業(yè)務(wù)建模、項目管理、數(shù)據(jù)流圖
      通過高級項目經(jīng)理5天課程的培訓(xùn),個人感覺對于原先的工作實踐有了一個很好的指導(dǎo),從原先的實踐上升了一個層次,對于實踐有了一個很好的理論指導(dǎo)。
      我想很多人可能會與我同感,一個項目做了很久,感覺總是做不完,就像一個“無底洞”。你想加人盡快完成這個項目,而用戶總是有新的需求要項目開發(fā)方來做,就像用戶是一個不知廉恥的要求者,而開發(fā)方是在苦苦接收的接受者。實際上,這里涉及到一個需求管理的概念。項目中哪些該做,哪些不該做,做到什么程度,都是由需求管理來決定的。那么,到底什么是需求管理,從這幾天的學(xué)習(xí)中,我從理論上對此問題做了一個分析,表達(dá)一些自已的想法。
      影響項目的最后成功的因素是多方面的,包括項目管理的九大知識領(lǐng)域(包括項目的整體管理、范圍管理、時間管理、費用管理、質(zhì)量管理、溝通管理、成本管理、人力資源管理、采購管理)。然而,要這九大知識領(lǐng)域?qū)椖砍晒Ξa(chǎn)生的影響的輕重程度上進(jìn)行比較的話,我個人認(rèn)為其中項目范圍管理中的需求管理是最為重要的。本文主要講述范圍管理中的需求管理部分。
      需求管理是軟件項目中一項十分重要的工作,據(jù)調(diào)查顯示在眾多失敗的軟件項目中,由于需求原因?qū)е碌募s占了很大的一部分,本人從事的工作經(jīng)歷中有好2次就是因為需求不明確,導(dǎo)致最終的系統(tǒng)不可控,項目陷入困境。因此,需求工作將對軟件項目能否最終實現(xiàn)產(chǎn)生至關(guān)重要的影響。雖然如此,在項目開發(fā)工作中,很多人對需求的認(rèn)識還遠(yuǎn)遠(yuǎn)不夠,從本人參與或接觸到的一些項目來看,小到幾萬元,大到上千萬元的軟件項目的需求都或多多少的存在問題。
      有的是開發(fā)者本身不重視原因,有的是技術(shù)原因、有的是人員組織原因、有的是溝通原因、有的是機(jī)制原因,以上種種原因都表明做好軟件需求開發(fā)是一項系統(tǒng)工作,而不是簡單的技術(shù)工作,只有系統(tǒng)的了解和掌握需求的基本概念、方法、手段、評估標(biāo)準(zhǔn)、風(fēng)險等相關(guān)知識,并在實踐中加以應(yīng)用,才能真正做好需求的開發(fā)和管理工作。在軟件項目的開發(fā)過程中,需求變更貫穿了軟件項目的整個生命周期,從軟件的項目立項,研發(fā),維護(hù),用戶的經(jīng)驗在增加,對使用軟件的感受有變化,以及整個行業(yè)的新動態(tài),都為軟件帶來不斷完善功能,優(yōu)化性能,提高用戶友好性的要求。在軟件項目管理過程中,項目經(jīng)理經(jīng)常面對用戶的需求變更。如果不能有效處理這些需求變更,項目計劃會一再調(diào)整,軟件交付日期一再拖延,項目研發(fā)人員的士氣將越來越低落,將直接導(dǎo)致項目成本增加、質(zhì)量下降及項目交付日期推后。這決定了項目組必須擁有需求管理策略。
      下面主要針對需求開發(fā)及需求管理兩個方面對需求進(jìn)行分析。
      1. 需求開發(fā),從目前我們的實際工作情況來看按順序主要分成如下幾個部分:
      請教行業(yè)專家
      行業(yè)客戶對信息化的需求越來越細(xì)化,對專業(yè)性以及行業(yè)能力的全面性要求越來越高,惟有深入行業(yè),洞察其需求,研發(fā)出更適合客戶需求的產(chǎn)品,才能成功。因此有必要先請這方面的行業(yè)專家對于客戶的業(yè)務(wù)需求進(jìn)行從流程上的梳理。為什么請行業(yè)專家,而不是直接請客戶進(jìn)行交談,得到其實需求,個人認(rèn)為主要是因為目前各政府部門、企事業(yè)單位對于信息化與業(yè)需求的整合這一塊缺少經(jīng)驗,大部分情況還不能完全整理出完善、清晰的系統(tǒng)需求來。只有通過行業(yè)專家對其實業(yè)務(wù)流程進(jìn)行梳理,一方面更容易與客戶產(chǎn)生共鳴,另一方面也可以大大減少因為知識方面的差異導(dǎo)致錯識需求的產(chǎn)生。
      和客戶交談
      你要面對“正確”的客戶區(qū)分不同層次的客戶需求,要面對不同層級,不同部門的客戶,把客戶分類,區(qū)分需求的優(yōu)先級別.如果你做的項目業(yè)務(wù)是你熟悉的,那還好,如果是你不熟悉的,一定要花點精力學(xué)習(xí)一下這個行業(yè)業(yè)務(wù)的背景資料,這也是我上面談到的先請行業(yè)專家的原因。畢竟,客戶是不可能給你系統(tǒng)地介紹業(yè)務(wù)的。只有你通曉了行業(yè)業(yè)務(wù),才能和用戶交流,并正確而有效地引導(dǎo)客戶,做好需求分析,你不能指望客戶能明確地說出需求。當(dāng)然,這也是系統(tǒng)分析人員的職責(zé)所在。在開始做需求的時候,你最后花一點時間搞清楚你接觸的客戶是不是做實際業(yè)務(wù)的客戶,如果你面對的客戶不是將來的系統(tǒng)的實際使用者。你就有點麻煩了。可能他是客戶公司派過來的IT部的人,他會提一大堆東西,而這些東西可能根本不是實際業(yè)務(wù)需要的功能,而他一般還會興致勃勃地給你一些技術(shù)實現(xiàn)的建議。這個時候你就要小心了,如果你聽了他的話,你可能在最后才發(fā)現(xiàn),你花了大量精力解決的問題,其實并不是客戶真正需要的。而你真正需要關(guān)注的,卻做得遠(yuǎn)遠(yuǎn)不夠。
     參考其他類似軟件和系統(tǒng)
      在經(jīng)過與客戶的溝通,并形成初步的需求之后,不要急成正式的需求,請先參考一下以前的一些系統(tǒng),去理解一下了解到的需求與原先系統(tǒng)的差異,并去發(fā)現(xiàn)是否有些需求會產(chǎn)生錯識需求。
      業(yè)務(wù)建模
      為需求建立模型,需求的圖形分析模型是軟件需求規(guī)格說明極好的補(bǔ)充說明。它們能提供不同的信息與關(guān)系以有助于找到不正確的、不一致的、遺漏的和冗余的需求。這樣的模型包括數(shù)據(jù)流圖、實體關(guān)系圖、狀態(tài)變換圖、對話框圖、對象類及交互作用圖。
      需求整理并形成需求規(guī)格說明書
      需求規(guī)格說明書的模板我想每家公司都是不一樣的,也沒有必要都一樣,但我認(rèn)為每個需求規(guī)格說明書至少應(yīng)包括
      軟件需求一旦通過了評審,就應(yīng)該基線化,納入配置管理庫.而在配置管理庫中的文檔或代碼不能再輕易進(jìn)行修改.當(dāng)有需求要進(jìn)行變更的時候,就必須提出申請,寫需求變更計劃,審核通過,才有權(quán)限進(jìn)行需求變更.然后配置管理員一定要做好需求的跟蹤.,凡是跟變更需求有牽連的開發(fā)人員和測試人員都要同步的通知到和及時讓他們做好相應(yīng)部分的各類文檔的修改。
      需求變更管理
      需求的變更管理我個人認(rèn)為是最容易出問題,一般項目做不完也主要是由此產(chǎn)生。需求變更的出現(xiàn)主要是因為在項目的需求確定階段,用戶往往不能確切地定義自己需要什么。用戶常常以為自己清楚,但實際上他們提出的需求只是依據(jù)當(dāng)前的工作所需,而采用的新設(shè)備、新技術(shù)通常會改變他們的工作方式;或者要開發(fā)的系統(tǒng)對用戶來說也是個未知數(shù),他們以前沒有過相關(guān)的使用經(jīng)驗。隨著開發(fā)工作的不斷進(jìn)展,系統(tǒng)開始展現(xiàn)功能的雛形,用戶對系統(tǒng)的了解也逐步深入。于是,他們可能會想到各種新的功能和特色,或?qū)σ郧疤岢龅囊筮M(jìn)行改動。他們了解得越多,新的要求也就越多,需求變更因此不可避免地一次又一次出現(xiàn)。如何有效的管理需求變更,下面是我公司目前的做法。公司采用Test Director作為需求管理工具,需求人員每次與客戶溝通后形成需求調(diào)查表,統(tǒng)一錄入Test Director,并進(jìn)行綜合及整理后形成需求規(guī)格說明書, 之后由研發(fā)部、產(chǎn)品部、及銷售代表(如果有客戶參加就更好了)進(jìn)行需求評審,建立需求基線。制訂簡單、有效的變更控制流程,并形成文檔。在建立了需求基線后提出的所有變更都必須遵循變更控制流程進(jìn)行控制,同時每一筆重要的需求變更都需要客戶簽字確認(rèn)才認(rèn)為需求變更生效。需求變更后,受影響的軟件計劃、產(chǎn)品、活動都要進(jìn)行相應(yīng)的變更,以保持和更新的需求一致。因為Test Director提供了需求變更記錄,可以幫助我們形成良好的文檔,便于進(jìn)行管理。
      2. 需求管理
      首先要針對需求做出分析,隨后應(yīng)用于產(chǎn)品并提出方案。需求分析的模型正是產(chǎn)品的原型樣本,優(yōu)秀的需求管理提高了這樣的可能性:它使最終產(chǎn)品更接近于解決需求,提高了用戶對產(chǎn)品的滿意度,從而使產(chǎn)品成為真正優(yōu)質(zhì)合格的產(chǎn)品。從這層意義上說,需求管理是產(chǎn)品質(zhì)量的基礎(chǔ)。
      需求管理的目的是在客戶與開發(fā)方之間建立對需求的共同理解,維護(hù)需求與其它工作成果的一致性,并控制需求的變更。
      需求確認(rèn)是指開發(fā)方和客戶共同對需求文檔進(jìn)行評審,雙方對需求達(dá)成共識后作出書面承諾,使需求文檔具有商業(yè)合同效果。
      需求跟蹤是指通過比較需求文檔與后續(xù)工作成果之間的對應(yīng)關(guān)系,建立與維護(hù)“需求跟蹤矩陣”,確保產(chǎn)品依據(jù)需求文檔進(jìn)行開發(fā)。
      需求變更控制是指依據(jù)“變更申請-審批-更改-重新確認(rèn)”的流程處理需求的變更,防止需求變更失去控制而導(dǎo)致項目發(fā)生混亂。
      根據(jù)上面描述的具體方法及步驟,由于需求分析的參與人員、業(yè)務(wù)模式、投資、時間等客觀因素的影響和需求本身具有主觀性和可描述性差的特點,因此,需求分析工作往往面臨著一些潛在的風(fēng)險,應(yīng)引起項目相關(guān)干系人的注意。這些風(fēng)險主要表現(xiàn)如下:
      1)用戶不能正確表達(dá)自身的需求。在實際開發(fā)過程中,常常碰到用戶對自己真正的需求并不是十分明確的情況,他們認(rèn)為計算機(jī)是萬能的,只要簡單的說說自己想干什么就是把需求說明白了,而對業(yè)務(wù)的規(guī)則、工作流程卻不愿多談,也講不清楚。這種情況往往會增加需求分析工作難度,分析人員需要花費更多的時間和精力與用戶交流,幫助他們梳理思路,搞清用戶的真實需求。從另一方面來看,他們對于計算機(jī)的理解肯定不是很到位,而我們?nèi)绾我龑?dǎo),正確梳理出正確的需求就需要先從工作業(yè)務(wù)流程出發(fā),而不是先從計算機(jī)方面來考慮問題。
      2)業(yè)務(wù)人員配合力度不夠。有的用戶日常工作繁忙,他們不愿意付出更多的時間和精力向分析人員講解業(yè)務(wù),這樣會加大分析人員的工作難度和工作量,也可能導(dǎo)致因業(yè)務(wù)需求不足而使系統(tǒng)無法使用。針對此類問題我們一般的做法是在項目開始階段先確定好一個與客戶溝通過的需求調(diào)研計劃,當(dāng)然這樣還是經(jīng)常會有變動,但相對來講從責(zé)任上來講,客戶也會有一定的壓力,因為如果不配合可能會導(dǎo)致系統(tǒng)進(jìn)度的延誤,其實這也不是客戶希望看到的。
      3)用戶需求的不斷變更。由于需求識別不全、業(yè)務(wù)發(fā)生變化、需求本身錯誤、需求不清楚等原因,需求在項目的整個生命周期都可能發(fā)生變化,因此,我們要認(rèn)識到,軟件開發(fā)的過程實際上是同變化做斗爭的過程,需求變化是每個開發(fā)人員、項目管理人員都會遇到的問題,也是最頭痛的問題,一旦發(fā)生了需求變化,就不得不修改設(shè)計、重寫代碼、修改測試用例、調(diào)整項目計劃等等,需求的變化就像是萬惡之源,為項目的正常的進(jìn)展帶來不盡的麻煩。針對這類需求變更的問題,個人認(rèn)為是影響進(jìn)度的最大的敵人,目前我們的做法是每次根據(jù)客戶的需求整理出一個書面的文件,由客戶簽字確認(rèn)。當(dāng)然這里還有一個很重要的問題就是不是每個需求都是必須做的,我們要學(xué)習(xí)如何拒絕客戶。
      4)需求的完整程度。需求如何做到?jīng)]有遺漏?這是一個大問題,大的系統(tǒng)要想窮舉需求幾乎是不可能的,即使小的系統(tǒng),新的需求也總會不時地冒出來。一個系統(tǒng)很難確定明確的范圍并把所有需求一次性提出來,這會導(dǎo)致開發(fā)人員在項目進(jìn)展中去不斷完善需求,先建立系統(tǒng)結(jié)構(gòu)再完成需求說明,造成返工的可能性很大,會給開發(fā)人員帶來挫折感,降低他們完成項目的信心。
      5)需求的細(xì)化程度。需求到底描述到多細(xì),才算可以結(jié)束了?雖然國家標(biāo)準(zhǔn)有需求說明的編寫規(guī)范,但具體到某一個需求上,很難給出一個具體的指標(biāo),可謂仁者見仁,智者見智,并沒有定論。需求越細(xì),周期越長,可能的變化越多,對設(shè)計的限制越嚴(yán)格,對需求的共性提取要求也越高,相反,需求越粗,開發(fā)人員在技術(shù)設(shè)計時不清楚的地方就越多,影響技術(shù)設(shè)計。
      6)需求描述的多義性。需求描述的多義性一方面是指不同讀者對需求說明產(chǎn)生了不同的理解;另一方面是指同一讀者能用不同的方式來解釋某個需求說明。多義性會使用戶和開發(fā)人員等項目參與者產(chǎn)生不同的期望,也會使開發(fā)、測試人員為不同的理解而浪費時間,帶來不可避免的后果便是返工重做。
      7)忽略了用戶的特點分析。分析人員往往容易忽略了系統(tǒng)用戶的特點,系統(tǒng)是由不同的人使用其不同的特性,使用頻繁程度有所差異,使用者受教育程度和經(jīng)驗水平不盡相同。如果忽略這些的話,將會導(dǎo)致有的用戶對產(chǎn)品感到失望。
      8)需求開發(fā)的時間保障。為了確保需求的正確性和完整性,項目負(fù)責(zé)人往往堅持要在需求階段花費較多的時間,但用戶和開發(fā)部門的領(lǐng)導(dǎo)卻會因為項目遲遲看不到實際成果而焦慮,他們往往會強(qiáng)迫項目盡快往前推進(jìn),需求開發(fā)人員也會被需求的復(fù)雜和善變折騰的筋疲力盡,他們也希望盡快結(jié)束需求階段。


      在實際的工作中,我列了一些需要關(guān)注的問題,以避免一些不必要的麻煩。
      1)抓住決策者最迫切和最關(guān)心的問題,引起重視。用戶方?jīng)Q策者對項目的關(guān)心重視程度是項目能否順利開展的關(guān)鍵,決策者的真實意圖也是用戶方的最終需求,因此,在開發(fā)過程中要利用一切機(jī)會了解決策者關(guān)心的問題,同時也要讓他們了解項目的情況。在諸如談判、專題匯報、協(xié)調(diào)會議、領(lǐng)導(dǎo)視察、階段性成果演示等過程中用簡短明確的語言或文字抓住領(lǐng)導(dǎo)最關(guān)心的問題,引導(dǎo)他們了解和重視項目的開發(fā),當(dāng)決策者認(rèn)識到項目的重要性時,需求分析工作在人力、物力、時間上就有了保障。
      2)建立組織保障,明確的責(zé)任分工。項目開發(fā)一般都會成立相應(yīng)的項目組或工程組,目前,常見的組織形式是:產(chǎn)品管理組、質(zhì)量與測試組、程序開發(fā)組、用戶代表組和后勤保障組,各組的主要分工是:產(chǎn)品管理組負(fù)責(zé)確定和設(shè)置項目目標(biāo),根據(jù)需求的優(yōu)先級確定功能規(guī)范,向相關(guān)人員通報項目進(jìn)展。程序管理組負(fù)責(zé)系統(tǒng)分析,根據(jù)軟件開發(fā)標(biāo)準(zhǔn)協(xié)調(diào)日常開發(fā)工作確保及時交付開發(fā)任務(wù),控制項目進(jìn)度。程序開發(fā)組負(fù)責(zé)按照功能規(guī)范要求交付軟件系統(tǒng)。質(zhì)量與測試組負(fù)責(zé)保證系統(tǒng)符合功能規(guī)范的要求,測試工作與開發(fā)工作是獨立并行的。用戶代表組負(fù)責(zé)代表用戶方提出需求,負(fù)責(zé)軟件的用戶方測試。后勤保障組負(fù)責(zé)確保項目順利進(jìn)行的后勤保障工作。
      3)建立良好的溝通環(huán)境和氛圍。分析人員與用戶溝通的程度關(guān)系到需求分析的質(zhì)量,因此建立一個良好的溝通氛圍、處理好分析人員與用戶之間的關(guān)系顯得尤其重要,一般情況,用戶作為投資方會有一些心理優(yōu)勢,希望他們的意見得到足夠的重視,分析人員應(yīng)該充分的認(rèn)識到這一點,做好心理準(zhǔn)備,盡量避免與他們發(fā)生爭執(zhí),因為我們的目的是幫助用戶說出他們的最終需要。在溝通時分析人員應(yīng)注意以下幾個方面:1)態(tài)度上要尊重對方,但不謙恭。謙恭可能會讓用戶一時感到滿意,但對長期合作并沒有好處,尤其是在發(fā)生沖突的時候,用戶會習(xí)慣性地感到自己的優(yōu)勢,而忽略分析人員地意見。2)分析人員要努力適應(yīng)不同用戶的語言表達(dá)方式。每個人都有自己的表達(dá)方式,所以優(yōu)秀的分析人員應(yīng)該是一個優(yōu)秀的“傾聽者”,他們能很快的適應(yīng)用戶的語言風(fēng)格,理解他們的意思。 3)善于表達(dá)自己,善于提問。分析人員在開口前應(yīng)該先讓對方充分表達(dá)他的意思,在領(lǐng)會了后,自己再說,盡量不要搶話。4)工作外的交流有助于增進(jìn)理解,加強(qiáng)溝通。
      4)需求質(zhì)量控制要制度化需求的變化是軟件項目不可避免的事實,因此需求質(zhì)量控制是一項艱苦的工作,要保證該項工作的順利實施,就必須有制度保證,這個制度可以在項目質(zhì)量控制方案中制定,該方案主要是具體化、定量化的描述用戶要求,形成全面、一致、規(guī)范的軟件需求分析規(guī)格說明書,明確需求分析規(guī)格說明書的工作程序和要素,規(guī)范開發(fā)活動,為后續(xù)軟件設(shè)計、實現(xiàn)、測試、評審及驗收提供依據(jù)。在方案中要明確項目組各部門關(guān)于需求質(zhì)量控制的職責(zé),制定需求分析的工作程序,包括編制需求分析工作計劃、編制《需求分析說明書》、《需求分析規(guī)格說明書》的評審和確認(rèn)、《需求分析規(guī)格說明書》修改控制、確定需求質(zhì)量控制的質(zhì)量記錄文檔規(guī)范等內(nèi)容。
      本文論述圍繞于需求管理,需求管理是開發(fā)工作有效進(jìn)行的確證。很明顯需求管理是一種很高層次的系統(tǒng)行為,涉及整個開發(fā)過程和產(chǎn)品本身。需求管理首先要針對需求做出分析,隨后應(yīng)用于產(chǎn)品并提出方案。需求分析的模型正是產(chǎn)品的原型樣本,優(yōu)秀的需求管理提高了這樣的可能性:它使最終產(chǎn)品更接近于解決需求,提高了用戶對產(chǎn)品的滿意度,從而使產(chǎn)品成為真正優(yōu)質(zhì)合格的產(chǎn)品。從這層意義上說,需求管理是產(chǎn)品質(zhì)量的基礎(chǔ)。

    posted @ 2014-12-03 13:39 順其自然EVO 閱讀(211) | 評論 (0)編輯 收藏

    你應(yīng)當(dāng)知道的7個Java工具

     AlexZhitnitsky告訴我們這7個輔助工具的主要功能特點,這些工具每個java程序員都應(yīng)該了解一下。這篇文章最初發(fā)表在takipi的博客–Java與Scala異常分析和性能監(jiān)控.
      在準(zhǔn)備進(jìn)行鎖和負(fù)載測試之前,應(yīng)該對一些最新的最具創(chuàng)新性的工具有一個快速了解。為了防止你錯過這些信息,rebellabs最近公布了對Java工具和技術(shù)全景的一個全球性調(diào)查結(jié)果。除了一些已有的或知名度很高的工具,現(xiàn)在市場上還充滿了很多不為人知的全新的工具和框架。
      在這篇文章中我們決定收集制作一個關(guān)于這類工具的簡略名單,他們中的大多數(shù)工具只是最近推出的。其中一些工具是為Java定制的,但也有一些是支持其他語言。但對于Java項目而言,他們都是非常好的,并且擁有同一個愿景:簡單化。讓我們開始吧。
      1.JClarity–性能監(jiān)測工具
      它發(fā)布于去年9月。圍繞java性能,當(dāng)前這款工具提供了兩個產(chǎn)品:Illuminate和Censum。
      Illuminate是一款性能監(jiān)測工具,而censum是一種聚焦于垃圾收集日志分析的應(yīng)用。
      它不僅僅提供了數(shù)據(jù)收集功能和可視化,對于檢測到的問題,這兩個工具能夠提供具有實踐性強(qiáng)的建議,幫助開發(fā)人員去解決問題。
      “我們要做的是把問題從數(shù)據(jù)收集階段轉(zhuǎn)移到數(shù)據(jù)分析和觀察階段”–JClarityCo-FounderBenEvans.
      主要特性:
      瓶頸檢測(磁盤I/O,垃圾收集,死鎖等)
      實施計劃–提出解決問題的具體建議,如“應(yīng)用程序需要增加活動線程數(shù)”。
      解釋–一般性問題的定義以及引起該問題的常見原因,例如“垃圾回收時停頓時間耗時比例過高,可能意味著堆內(nèi)存不夠,太小了”。
      獨特之處:進(jìn)行監(jiān)測和性能問題確認(rèn)后,他會立即提供可行性的意見來解決這些問題
      幕后故事:JClarity是在倫敦建立的,他的創(chuàng)始人包括MartijnVerburg,KirkPepperdin和BenEvans,都是在java性能領(lǐng)域有著非常豐富經(jīng)驗的人。
      想要獲取更多關(guān)于JClarity的信息,點擊這里
      2.Bintray-二元次的社交平臺
      當(dāng)從一些”匿名”倉庫中導(dǎo)入庫文件時,Java開發(fā)人員在某種程度上被蒙在鼓里。Bintray給這些代碼添了“一張臉”,作為一個社會化平臺為java開發(fā)者服務(wù),分享開源的軟件包(會不會有人說這是二元次的github?).它擁有超過85000個文件包,涵蓋18000個庫,展示了當(dāng)前流行的和新版本的包。
      主要特性:
      上傳你的二進(jìn)制文件,讓全世界都可以看到,并且可以和其他開發(fā)者進(jìn)行交流,并得到一些反饋。
      使用Gradle/Maven/Yum/Apt工具下載包文件,或者直接從平臺下載。
      管理包的版本說明和相關(guān)文檔
      REST風(fēng)格的API-查詢/檢索文件接口和自動分發(fā)接口
      獨特之處:Bintray的基礎(chǔ)功能類似于maven中央倉庫。但他增加了一個社交層,提供了一個將文件分發(fā)到CDN服務(wù)器的簡單辦法。
      幕后故事:JFrog基于Israel和California,開發(fā)了Bintray。該工具是去年4月公開的,并在上次JavaOne大會上贏得了Duke’schoiceaward獎項
      JFrog也開發(fā)Artifactory,Artifactory當(dāng)然也是跑在Bintray上的。
      3.Librato–監(jiān)控和可視化云服務(wù)
      Librato作為一個監(jiān)控和管理云應(yīng)用的托管服務(wù),它可以瞬間完成自定義面板的創(chuàng)建,而不需要用戶去配置或者安裝任何軟件。
      相比其他面板,他的外觀和感受如黃油般順滑。
      “僅當(dāng)你能夠從數(shù)據(jù)中獲得具有實際意義的信息時,數(shù)據(jù)才是有價值的”—JoeRuscio,Co-Founder&CTO
      主要特性:
      數(shù)據(jù)收集:集成了Heroku、AWS、數(shù)十種集成代理,以及綁定了java、Clojure等語言。
      自定義報告:性能指標(biāo)和告警可以通過郵件、HipChat、Campfire以及HTTPPOST請求與你所想到的任何東西進(jìn)行整合
      數(shù)據(jù)可視化:帶有注釋、相關(guān)性分析,共享和嵌入選項的美觀的圖片展示
      告警:當(dāng)指標(biāo)超過一定閾值時會自動發(fā)出通知告警
      特別之處:很難找到任何Librato不知道如何表述以及對數(shù)據(jù)的理解。
      幕后故事:FredvandenBosch,JoeRuscio,MikeHeffnerandDanStodin幾個人在SanFrancisco創(chuàng)建了Librato
      4.Takipi的建立基于一個簡單的目的:告訴開發(fā)人員到底在何時什么原因代碼出現(xiàn)異常。每當(dāng)一個新的異常拋出,或者一個錯誤日志發(fā)生,Takipi就會捕獲它,給用戶展示可能引起該異常的變量狀態(tài),經(jīng)過的方法和設(shè)備。Takipi在錯誤發(fā)生時刻將會覆蓋實際執(zhí)行代碼—所以在你分析異常時,就如同當(dāng)異常發(fā)生時你正好在場。
      主要特性
      監(jiān)控-捕獲/未捕獲的異常,http錯誤,和被日志記錄的錯誤
      優(yōu)先排序-如果異常錯誤涉及到新增的代碼或者修改過的代碼,工具會統(tǒng)計集群中這樣的錯誤發(fā)生的頻率,以及錯誤發(fā)生的概率是否在遞增。
      分析-觀測實際代碼和變量狀態(tài),甚至跨越不同的機(jī)器和應(yīng)用
      獨特之處:
      生產(chǎn)環(huán)境的GodMode模式。錯誤發(fā)生時展示實際執(zhí)行的異常代碼和變量狀態(tài)。這樣你分析異常時,就如同當(dāng)異常發(fā)生時你在場。
      幕后故事:Takipi創(chuàng)建于2012年的SanFrancisco和TelAviv。每種異常類型和錯誤都有唯一的怪物來代表他。\ 5.Elasticsearch–搜索和分析平臺
      Elasticsearch已經(jīng)存在一段時間了,但是他的1.0.0版本在2月份才發(fā)布。他是一個基于lucene的,托管在github上的開源項目,他有200位開發(fā)者。你可以從這checkout出代碼.Elasticsearch提供的主要特性是易于使用的,可擴(kuò)展的,分布式的,rest風(fēng)格的檢索。
      主要特性
      實時文檔存儲,文檔對象的每個field都建立了索引,都能被檢索
      構(gòu)建適應(yīng)于不同規(guī)模的應(yīng)用的體系結(jié)構(gòu),在此之上實現(xiàn)分布式搜索。
      為其他平臺系統(tǒng)提供了具有rest風(fēng)格的和原生javaapi。他也有hadoop的依賴包
      簡單可用性強(qiáng),不需要對搜索原理有深入的理解。該平臺有免費模式,所以你可以快速開始應(yīng)用起來。
      獨特之處:如他所說,他具有可伸縮性,靈活的構(gòu)建和易用性。提供一個易用性的平臺,進(jìn)行規(guī)模擴(kuò)展時無需考慮核心功能與用戶自定義選項間妥協(xié)。
      幕后故事:Elasticsearch由ShayBanonback創(chuàng)建于2010年,最近募集到了7000萬刀的資金。在創(chuàng)建該項目前,Banon就經(jīng)營一個Compass的開源項目,現(xiàn)在他是一個著名的搜索專家。那他進(jìn)入搜索領(lǐng)域的動機(jī)呢?原來是為了讓他妻子能夠保存和檢索所喜歡的食譜,進(jìn)而開發(fā)的一個應(yīng)用。
      6.Spark–微型Web框架
      回到j(luò)ava語言,Spark是一個極具自由靈感的,能夠快速創(chuàng)建Web應(yīng)用程序的微型Web框架。為了支持java8和lambdas,今年早些時候他被重寫了。Spark是一個開源項目,源代碼可以在github上可以看到(請點擊這里),目前開發(fā)該框架的人是PerWendel和過去幾年為了實現(xiàn)只需要付出很小的努力,便可以快速構(gòu)建一個web應(yīng)用這樣使命的一小撮人。
      主要特性:
      快速上手,配置簡單
      直觀的路由匹配器
      創(chuàng)建可復(fù)用組建的模板引擎,它支持Freemarker,ApacheVelocity和Mustache
      Spark可以運行在Jetty上,也可以在tomcat上跑
      獨特之處:圖片勝過千言萬語,圖片更加直觀,把代碼check出來感受一下吧
      幕后故事:Spark的創(chuàng)始人是PerWendel,瑞典人。目前與其他20個人開發(fā)Spark。去看看討論組,學(xué)習(xí)更多的關(guān)于Spark的知識,了解如何去給這個開源項目做貢獻(xiàn),解決bug。
      7.Plumbr–內(nèi)存泄漏檢測
      深入研究java虛擬機(jī),其中的GC(GarbageCollector垃圾收集器)將那些不再使用的對象進(jìn)行回收,釋放內(nèi)存。盡管如此,有時候,開發(fā)人員仍舊會持有那些不再使用的對象引用,占用內(nèi)存。這樣就會發(fā)生內(nèi)存泄漏,這個時候,Plumer就該登場了。如果應(yīng)用發(fā)生了內(nèi)存泄漏問題,Plumer就會進(jìn)行檢測,生成報告,并且提供切實可行的方案去fix掉這個問題。
      主要特性
      實時的內(nèi)存泄漏檢測和告警
      一份包含時間,內(nèi)存大小,速度(MB/h)以及泄漏事件的重要級別的報告。
      內(nèi)存泄漏的代碼位置
      獨特之處:快,切中要點,從代碼中分析并給出建議幫你修復(fù)Bug
      幕后故事:Plumbr創(chuàng)建于Estonia,創(chuàng)始人是PriitPotter,IvoM?gi,NikitaSalnikov-Tarnovski和Vladimir?or。加入這樣一個擁有非常豐富經(jīng)驗的java團(tuán)隊吧,這些家伙都是非常厲害的救火隊員。嗯,是這樣的

    posted @ 2014-12-03 13:38 順其自然EVO 閱讀(258) | 評論 (0)編輯 收藏

    你真的懂產(chǎn)品管理嗎?實際上你一直都做錯了

     有人會雇傭個銷售代表,讓更新網(wǎng)站,然后在思考為什么銷售不肯來了呢?
      或者聘請個會計師,讓她去管理開發(fā)團(tuán)隊,然后問她賬目為什么不是最新的?
      或者讓幾個程序猿花時間準(zhǔn)備營銷郵件,然后問他們?yōu)槭裁创a總被延期交付?
      或招聘個產(chǎn)品經(jīng)理,讓他更新網(wǎng)站,管理開發(fā)團(tuán)隊和撰寫營銷郵件,然后問他為什么產(chǎn)品戰(zhàn)略不夠高效,產(chǎn)品路線圖為什么不夠完善。
      好吧,前3種情況可能并不多見,但最后一種,產(chǎn)品管理的不幸總在許多公司上演,并在涉及到定義產(chǎn)品管理責(zé)任時,都會清晰地顯現(xiàn)出來。
      產(chǎn)品經(jīng)理名言
      我們曾調(diào)查,什么事阻止了產(chǎn)品經(jīng)理高效地工作?我們腦海里顯現(xiàn)出一幅清晰的畫面,產(chǎn)品經(jīng)理做的一切,從技術(shù)支持到項目管理,就如別人所說,“像個打雜的”。
      大部分公司會聘請員工來長期或短期地關(guān)注一些成功的產(chǎn)品,但這些員工過來后,往往會偏離招聘地初衷,干些其它的事情。
      產(chǎn)品管理是一個跨職能部分角色。但這并不意味著產(chǎn)品經(jīng)理就應(yīng)該做其它部分的工作。他們應(yīng)該確保工作是由合適的人在做,并與產(chǎn)品整體目標(biāo)保持一致。
      成功需要協(xié)調(diào)
      為了最大限度地提高產(chǎn)品的成功,需要做好以下4點:
      業(yè)務(wù)活動和目標(biāo)
      組織準(zhǔn)備(內(nèi)部和外部)
      產(chǎn)品上市的計劃和活動
      產(chǎn)品計劃和能力
      每個目標(biāo)可被分解成一系列活動及里程碑,一些工作應(yīng)該由產(chǎn)品經(jīng)理完成,或在產(chǎn)品經(jīng)理的監(jiān)督下,由其它組完成。如果產(chǎn)品管理不注重在這幾個方面調(diào)整和優(yōu)化每個產(chǎn)品的話,那么你在公司將失去核心價值。
      管理層需要確保該被其他組完成的工作,最后也是由這些組完成,而不是由(通常人員不足時)產(chǎn)品經(jīng)理完成。
      否則,你就像讓銷售代表來更新你的網(wǎng)站一樣。當(dāng)然,企業(yè)的效益也跟這一樣。

    posted @ 2014-12-03 13:38 順其自然EVO 閱讀(146) | 評論 (0)編輯 收藏

    Java數(shù)組的定義及用法

    數(shù)組是有序數(shù)據(jù)的集合,數(shù)組中的每一個元素具有同樣的數(shù)組名和下標(biāo)來唯一地確定數(shù)組中的元素。
      1. 一維數(shù)組
      1.1 一維數(shù)組的定義
      type arrayName[];
      type[] arrayName;
      當(dāng)中類型(type)能夠為Java中隨意的數(shù)據(jù)類型,包含簡單類型組合類型,數(shù)組名arrayName為一個合法的標(biāo)識符,[]指明該變量是一個數(shù)組類型變量。
      另外一種形式對C++開發(fā)人員可能認(rèn)為非常奇怪,只是對JAVA或C#這種開發(fā)語言來說,另外一種形式可能更直觀,由于這里定義的僅僅是個變量而已,系統(tǒng)并未對事實上例化,僅僅需指明變量的類型就可以,也不需在[]指定數(shù)組大小。(第一種形式是不是僅僅是為了兼容曾經(jīng)的習(xí)慣,畢竟C語言的影響太大了?)
      比如:
      int intArray[];
      聲明了一個整型數(shù)組,數(shù)組中的每一個元素為整型數(shù)據(jù)。與C、C++不同,Java在數(shù)組的定義中并不為數(shù)組元素分配內(nèi)存,因此[]中不用指出數(shù)組中元素個數(shù),即數(shù)組長度,并且對于如上定義的一個數(shù)組是不能訪問它的不論什么元素的。我們必須為它分配內(nèi)存空間,這時要用到運算符new,其格式例如以下:
      arrayName=new type[arraySize];
      當(dāng)中,arraySize指明數(shù)組的長度。如:
      intArray=new int[3];
      為一個整型數(shù)組分配3個int型整數(shù)所占領(lǐng)的內(nèi)存空間。
      通常,這兩部分能夠合在一起,格式例如以下:
      type arrayName=new type[arraySize];
      比如:
      int intArray=new int[3];
      1.2 一維數(shù)組元素的引用
      定義了一個數(shù)組,并用運算符new為它分配了內(nèi)存空間后,就能夠引用數(shù)組中的每個元素了。數(shù)組元素的引用方式為:
      arrayName[index]
      當(dāng)中:index為數(shù)組下標(biāo),它能夠為整型常數(shù)或表達(dá)式。如a[3],b[i](i為整型),c[6*I]等。下標(biāo) 從0開始,一直到數(shù)組的長度減1。對于上面樣例中的in-tArray數(shù)來說,它有3個元素,分別為:
      intArray[0],intArray[1],intArray[2]。注意:沒有intArray[3]。
      另外,與C、C++中不同,Java對數(shù)組元素要進(jìn)行越界檢查以保證安全性。同一時候,對于每一個數(shù)組都有一個屬性length指明它的長度,比如:intArray.length指明數(shù)組intArray的長度。
      執(zhí)行結(jié)果例如以下:
      C:/>java ArrayTest
      a[4]=4
      a[3]=3
      a[2]=2
      a[1]=1
      a[0]=0
      該程序?qū)?shù)組中的每一個元素賦值,然后按逆序輸出。
      1.3 一維數(shù)組的初始化
      對數(shù)組元素能夠依照上述的樣例進(jìn)行賦值。也能夠在定義數(shù)組的同一時候進(jìn)行初始化。
      比如:
      int a[]={1,2,3,4,5};
      用逗號(,)分隔數(shù)組的各個元素,系統(tǒng)自己主動為數(shù)組分配一定空間。
      與C中不同,這時Java不要求數(shù)組為靜態(tài)(static),事實上這里的變量相似C中的指針,所以將其作為返回值給其他函數(shù)使用,仍然是有效的,在C中將局部變量返回給調(diào)用函數(shù)繼續(xù)使用是剛開始學(xué)習(xí)的人非常easy犯的錯誤。
      2. 多維數(shù)組
      與C、C++一樣,Java中多維數(shù)組被看作數(shù)組的數(shù)組。比如二維數(shù)組為一個特殊的一維數(shù)組,其每一個元素又是一個一維數(shù)組。以下我們主要以二維數(shù)為例來進(jìn)行說明,高維的情況是相似的。
      2.1 二維數(shù)組的定義
      二維數(shù)組的定義方式為:
      type arrayName[][];
      比如:
      int intArray[][];
      與一維數(shù)組一樣,這時對數(shù)組元素也沒有分配內(nèi)存空間,同要使用運算符new來分配內(nèi)存,然后才干夠訪問每一個元素。
      對高維數(shù)組來說,分配內(nèi)存空間有以下幾種方法:
      1. 直接為每一維分配空間,如:
      int a[][]=new int[2][3];
      2. 從最高維開始,分別為每一維分配空間,如:
      int a[][]=new int[2][];
      a[0]=new int[3];
      a[1]=new int[3];
      完畢1中同樣的功能。這一點與C、C++是不同的,在C、C++中必須一次指明每一維的長度。
      2.2 二維數(shù)組元素的引用
      對二維數(shù)組中每一個元素,引用方式為:arrayName[index1][index2] 當(dāng)中index1、index2為下標(biāo),可為整型常數(shù)或表達(dá)式,如a[2][3]等,相同,每一維的下標(biāo)都從0開始。
      2.3 二維數(shù)組的初始化
      有兩種方式:
      1. 直接對每一個元素進(jìn)行賦值。
      2. 在定義數(shù)組的同一時候進(jìn)行初始化。
      如:int a[][]={{2,3},{1,5},{3,4}};
      定義了一個3×2的數(shù)組,并對每一個元素賦值。

    posted @ 2014-12-03 13:37 順其自然EVO 閱讀(243) | 評論 (0)編輯 收藏

    Java對象實例化

     JAVA類,只要知道了類名(全名)就可以創(chuàng)建其實例對象,通用的方法是直接使用該類提供的構(gòu)造方法,如
      NewObject o = new NewObject();
      NewObject o = new NewObject("test");
      NewObject o = new NewObject(new String[]{"aaa","bbb"});
      除此之外,還可以利用java.lang.Class<T>類來實現(xiàn)JAVA類的實例化。
      1、空構(gòu)造方法
      如果類有空構(gòu)造方法,如下面的類
    public class NewObject
    {
    String name;
    public NewObject(String[] name)
    {
    this.name = name[0];
    System.out.println(“ the object is created!”);
    }
    public void write()
    {
    System.out.println(this.name);
    }
    }
      使用以下代碼可實現(xiàn)實例化:
    NewObject no = null;
    try
    {
    no = (NewObject)Class.forName(className).newInstance();
    no.write();
    }
    catch (InstantiationException e)
    {
    e.printStackTrace();
    }
    catch (IllegalAccessException e)
    {
    e.printStackTrace();
    }
    catch (ClassNotFoundException e)
    {
    e.printStackTrace();
    }

    字體:        | 上一篇 下一篇 | 打印  | 我要投稿 

      2、帶參數(shù)構(gòu)造方法
    public class NewObject
    {
    String name;
    public NewObject()
    {
    System.out.println(“ the object is created!”);
    }
    public void write()
    {
    System.out.println(“”);
    }
    }
      使用以下代碼可實現(xiàn)實例化:
    try
    {
    no=(NewObject)Class.forName(className).getConstructor(String.class).newInstance(names);
    //no=(NewObject)Class.forName(className).getConstructor(newObject[]{String.class}).newInstance(names);
    }
    catch(IllegalArgumentExceptione)
    {
    e.printStackTrace();
    }
    catch(SecurityExceptione)
    {
    e.printStackTrace();
    }
    catch(InstantiationExceptione)
    {
    e.printStackTrace();
    }
    catch(IllegalAccessExceptione)
    {
    e.printStackTrace();
    }
    catch(InvocationTargetExceptione)
    {
    e.printStackTrace();
    }
    catch(NoSuchMethodExceptione)
    {
    e.printStackTrace();
    }
    catch(ClassNotFoundExceptione)
    {
    e.printStackTrace();
    }
      3、帶數(shù)組參數(shù)構(gòu)造方法
      public class NewObject
      {
      String name;
      public NewObject(String name)
      {
      this.name = name;
      System.out.println(“ the object is created!”);
      }
      public void write()
      {
      System.out.println(this.name);
      }
      }
      使用以下代碼可實現(xiàn)實例化:
    try
    {
    Constructor[] cs;
    cs = Class.forName(className).getConstructors();
    Constructor cc = Class.forName(className).getConstructor(String[].class);
    no = (NewObject)cc.newInstance(new Object[]{names});
    }
    catch (SecurityException e)
    {
    e.printStackTrace();
    }
    catch (ClassNotFoundException e)
    {
    e.printStackTrace();
    }
    catch (NoSuchMethodException e)
    {
    e.printStackTrace();
    }
    catch (IllegalArgumentException e)
    {
    e.printStackTrace();
    }
    catch (InstantiationException e)
    {
    e.printStackTrace();
    }
    catch (IllegalAccessException e)
    {
    e.printStackTrace();
    }
    catch (InvocationTargetException e)
    {
    e.printStackTrace();
    }

    posted @ 2014-12-03 13:37 順其自然EVO 閱讀(220) | 評論 (0)編輯 收藏

    Java 8的6個問題

    1. 并行Streams實際上可能會降低你的性能
      Java8帶來了最讓人期待的新特性之–并行。parallelStream() 方法在集合和流上實現(xiàn)了并行。它將它們分解成子問題,然后分配給不同的線程進(jìn)行處理,這些任務(wù)可以分給不同的CPU核心處理,完成后再合并到一起。實現(xiàn)原理主要是使用了fork/join框架。好吧,聽起來很酷對吧!那一定可以在多核環(huán)境下使得操作大數(shù)據(jù)集合速度加快咯,對嗎?
      不,如果使用不正確的話實際上會使得你的代碼運行的更慢。我們進(jìn)行了一些基準(zhǔn)測試,發(fā)現(xiàn)要慢15%,甚至可能更糟糕。假設(shè)我們已經(jīng)運行了多個線程,然后使用.parallelStream() 來增加更多的線程到線程池中,這很容易就超過多核心CPU處理的上限,從而增加了上下文切換次數(shù),使得整體都變慢了。
      基準(zhǔn)測試將一個集合分成不同的組(主要/非主要的):
      Map<Boolean, List<Integer>> groupByPrimary = numbers
      .parallelStream().collect(Collectors.groupingBy(s -> Utility.isPrime(s)));
      使得性能降低也有可能是其他的原因。假如我們分成多個任務(wù)來處理,其中一個任務(wù)可能因為某些原因使得處理時間比其他的任務(wù)長很多。.parallelStream() 將任務(wù)分解處理,可能要比作為一個完整的任務(wù)處理要慢。來看看這篇文章, Lukas Krecan給出的一些例子和代碼 。
      提醒:并行帶來了很多好處,但是同樣也會有一些其他的問題需要考慮到。當(dāng)你已經(jīng)在多線程環(huán)境中運行了,記住這點,自己要熟悉背后的運行機(jī)制。
      2. Lambda 表達(dá)式的缺點
      lambda表達(dá)式。哦,lambda表達(dá)式。沒有l(wèi)ambda表達(dá)式我們也能做到幾乎一切事情,但是lambda是那么的優(yōu)雅,擺脫了煩人的代碼,所以很容易就愛上lambda。比如說早上起來我想遍歷世界杯的球員名單并且知道具體的人數(shù)(有趣的事實:加起來有254個)。
      List lengths = new ArrayList();
      for (String countries : Arrays.asList(args)) {
      lengths.add(check(country));
      }
      現(xiàn)在我們用一個漂亮的lambda表達(dá)式來實現(xiàn)同樣的功能:
      Stream lengths = countries.stream().map(countries -< check(country));
      哇塞!這真是超級厲害。增加一些像lambda表達(dá)式這樣的新元素到Java當(dāng)中,盡管看起來更像是一件好事,但是實際上卻是偏離了Java原本的規(guī)范。字節(jié)碼是完全面向?qū)ο蟮模殡S著lambda的加入 ,這使得實際的代碼與運行時的字節(jié)碼結(jié)構(gòu)上差異變大。閱讀更多關(guān)于lambda表達(dá)式的負(fù)面影響可以看Tal Weiss這篇文章。
      從更深層次來看,你寫什么代碼和調(diào)試什么代碼是兩碼事。堆棧跟蹤越來越大,使得難以調(diào)試代碼。一些很簡單的事情譬如添加一個空字符串到list中,本來是這樣一個很短的堆棧跟蹤
      at LmbdaMain.check(LmbdaMain.java:19)
      at LmbdaMain.main(LmbdaMain.java:34)
      變成這樣:
    at LmbdaMain.check(LmbdaMain.java:19)
    at LmbdaMain.lambda$0(LmbdaMain.java:37)
    at LmbdaMain$$Lambda$1/821270929.apply(Unknown Source)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:512)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:502)
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.LongPipeline.reduce(LongPipeline.java:438)
    at java.util.stream.LongPipeline.sum(LongPipeline.java:396)
    at java.util.stream.ReferencePipeline.count(ReferencePipeline.java:526)
    at LmbdaMain.main(LmbdaMain.java:39
      lambda表達(dá)式帶來的另一個問題是關(guān)于重載:使用他們調(diào)用一個方法時會有一些傳參,這些參數(shù)可能是多種類型的,這樣會使得在某些情況下導(dǎo)致一些引起歧義的調(diào)用。Lukas Eder 用示例代碼進(jìn)行了說明。
      提醒:要意識到這一點,跟蹤有時候可能會很痛苦,但是這不足以讓我們遠(yuǎn)離寶貴的lambda表達(dá)式。
      3. Default方法令人分心
      Default方法允許一個功能接口中有一個默認(rèn)實現(xiàn),這無疑是Java8新特性中最酷的一個,但是它與我們之前使用的方式有些沖突。那么既然如此,為什么要引入default方法呢?如果不引入呢?
      Defalut方法背后的主要動機(jī)是,如果我們要給現(xiàn)有的接口增加一個方法,我們可以不用重寫實現(xiàn)來達(dá)到這個目的,并且使它與舊版本兼容。例如,拿這段來自Oracle Java教程中 添加指定一個時區(qū)功能的代碼來說:
    public interface TimeClient {
    // ...
    static public ZoneId getZoneId (String zoneString) {
    try {
    return ZoneId.of(zoneString);
    } catch (DateTimeException e) {
    System.err.println("Invalid time zone: " + zoneString +
    "; using default time zone instead.");
    return ZoneId.systemDefault();
    }
    }
    default public ZonedDateTime getZonedDateTime(String zoneString) {
    return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
    }
    }
      就是這樣,問題迎刃而解了。是這樣么?Default方法將接口和實現(xiàn)分離混合了。似乎我們不用再糾結(jié)他們本身的分層結(jié)構(gòu)了,現(xiàn)在我們需要解決新的問題了。想要了解更多,閱讀Oleg Shelajev在RebelLabs上發(fā)表的文章吧。
      提醒:當(dāng)你手上有一把錘子的時候,看什么都像是釘子。記住它們原本的用法,保持原來的接口而重構(gòu)引入新的抽象類是沒有意義的。
     4. 該如何拯救你,Jagsaw?
      Jigsaw項目的目標(biāo)是使Java模塊化,將JRE分拆成可以相互操作的組件。這背后最主要的動機(jī)是渴望有一個更好、更快、更強(qiáng)大的Java嵌入式。我試圖避免提及“物聯(lián)網(wǎng)”,但我還是說了。減少JAR的體積,改進(jìn)性能,增強(qiáng)安全性等等是這個雄心勃勃的項目所承諾的。
      但是,它在哪呢?Oracle的首席Java架構(gòu)師, Mark Reinhold說:  Jigsaw,通過了探索階段 ,最近才進(jìn)入第二階段,現(xiàn)在開始進(jìn)行產(chǎn)品的設(shè)計與實現(xiàn)。該項目原本計劃在Java8完成。現(xiàn)在推遲到Java9,有可能成為其最主要的新特性。
      提醒:如果這正是你在等待的, Java9應(yīng)該在2016年間發(fā)布。同時,想要密切關(guān)注甚至參與其中的話,你可以加入到這個郵件列表。
      5. 那些仍然存在的問題
      受檢異常
      沒有人喜歡繁瑣的代碼,那也是為什么lambdas表達(dá)式那么受歡迎的的原因。想想討厭的異常,無論你是否需要在邏輯上catch或者要處理受檢異常,你都需要catch它們。即使有些永遠(yuǎn)也不會發(fā)生,像下面這個異常就是永遠(yuǎn)也不會發(fā)生的:
      try {
      httpConn.setRequestMethod("GET");
      }?catch (ProtocolException pe) { /* Why don’t you call me anymore? */ }
      原始類型
      它們依然還在,想要正確使用它們是一件很痛苦的事情。原始類型導(dǎo)致Java沒能夠成為一種純面向?qū)ο笳Z言,而移除它們對性能也沒有顯著的影響。順便提一句,新的JVM語言都沒有包含原始類型。
      運算符重載
      James Gosling,Java之父,曾經(jīng)在接受采訪時說:“我拋棄運算符重載是因為我個人主觀的原因,因為在C++中我見過太多的人在濫用它。”有道理,但是很多人持不同的觀點。其他的JVM語言也提供這一功能,但是另一方面,它導(dǎo)致有些代碼像下面這樣:
      javascriptEntryPoints <<= (sourceDirectory in Compile)(base =>
      ((base / "assets" ** "*.js") --- (base / "assets" ** "_*")).get
      )
      事實上這行代碼來自Scala  Play框架,我現(xiàn)在都有點暈了。
      提醒:這些是真正的問題么?我們都有自己的怪癖,而這些就是Java的怪癖。在未來的版本中可能有會發(fā)生一些意外,它將會改變,但向后兼容性等等使得它們現(xiàn)在還在使用。
      6. 函數(shù)式編程–為時尚早
      函數(shù)式編程出現(xiàn)在java之前,但是它相當(dāng)?shù)膶擂巍ava8在這方面有所改善例如lambdas等等。這是讓人受歡迎的,但卻不如早期所描繪的那樣變化巨大。肯定比Java7更優(yōu)雅,但是仍需要努力增加一些真正需要的功能。
      其中一個在這個問題上最激烈的評論來自Pierre-yves Saumont,他寫了一系列的文章詳細(xì)的講述了函數(shù)式編程規(guī)范和其在Java中實現(xiàn)的差異。
      所以,選擇Java還是Scala呢?Java采用現(xiàn)代函數(shù)范式是對使用多年Lambda的Scala的一種肯定。Lambdas讓我們覺得很迷惑,但是也有許多像traits,lazy evaluation和immutables等一些特性,使得它們相當(dāng)?shù)牟煌?/div>
      提醒:不要為lambdas分心,在Java8中使用函數(shù)式編程仍然是比較麻煩的。

    posted @ 2014-12-03 13:36 順其自然EVO 閱讀(221) | 評論 (0)編輯 收藏

    聊聊Oracle外鍵約束的幾個操作選項

    關(guān)系型數(shù)據(jù)庫是以數(shù)據(jù)表和關(guān)系作為兩大對象基礎(chǔ)。數(shù)據(jù)表是以二維關(guān)系將數(shù)據(jù)組織在DBMS中,而關(guān)系建立數(shù)據(jù)表之間的關(guān)聯(lián),搭建現(xiàn)實對象模型。主外鍵是任何數(shù)據(jù)庫系統(tǒng)都需存在的約束對象,從對象模型中的業(yè)務(wù)邏輯加以抽象,作為物理設(shè)計的一個部分在數(shù)據(jù)庫中加以實現(xiàn)。
      Oracle外鍵是維護(hù)參照完整性的重要手段,大多數(shù)情況下的外鍵都是緊密關(guān)聯(lián)關(guān)系。外鍵約束的作用,是保證字表某個字段取值全都與另一個數(shù)據(jù)表主鍵字段相對應(yīng)。也就是說,只要外鍵約束存在并有效,就不允許無參照取值出現(xiàn)在字表列中。具體在Oracle數(shù)據(jù)庫中,外鍵約束還是存在一些操作選項的。本篇主要從實驗入手,介紹常見操作選項。
      二、環(huán)境介紹
      筆者選擇Oracle 11gR2進(jìn)行測試,具體版本號為11.2.0.4。
    SQL> select * from v$version;
    BANNER
    --------------------------------------------------------------------------------
    Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
    PL/SQL Release 11.2.0.4.0 - Production
    CORE      11.2.0.4.0     Production
    TNS for 64-bit Windows: Version 11.2.0.4.0 - Production
    NLSRTL Version 11.2.0.4.0 – Production
      創(chuàng)建數(shù)據(jù)表Prim和Child,對應(yīng)數(shù)據(jù)插入。
    SQL> create table prim (v_id number(3), v_name varchar2(100));
    Table created
    SQL> alter table prim add constraint pk_prim primary key (v_id);
    Table altered
    SQL> create table child (c_id number(3), v_id number(3), c_name varchar2(100));
    Table created
    SQL> alter table child add constraint pk_child primary key (c_id);
    Table altered
      二、默認(rèn)外鍵行為
      首先我們查看默認(rèn)外鍵行為方式。
      SQL> alter table CHILD
      2    add constraint FK_CHILD_PRIM foreign key (V_ID)
      3    references prim (V_ID)
      4  ;
      在沒有額外參數(shù)加入的情況下,Oracle外鍵將嚴(yán)格按照標(biāo)準(zhǔn)外鍵方式工作
      --在有子記錄情況下,強(qiáng)制刪除主表記錄;
      SQL> delete prim where v_id=2;
      delete prim where v_id=2
      ORA-02292:違反完整約束條件(A.FK_CHILD_PRIM) - 已找到子記錄
      --在存在子表記錄情況下,更改主表記錄;
      SQL> update prim set v_id=4 where v_id=2;
      update prim set v_id=4 where v_id=2
      ORA-02292:違反完整約束條件(A.FK_CHILD_PRIM) - 已找到子記錄
      --修改子表記錄
      SQL> update child set v_id=5 where v_id=2;
      update child set v_id=5 where v_id=2
      ORA-02291: 違反完整約束條件 (A.FK_CHILD_PRIM) - 未找到父項關(guān)鍵字
      上面實驗說明:在默認(rèn)的Oracle外鍵配置條件下,只要有子表記錄存在,主表記錄是不允許修改或者刪除的。子表記錄也必須時刻保證參照完整性。
     三、On delete cascade
      對于應(yīng)用開發(fā)人員而言,嚴(yán)格外鍵約束關(guān)系是比較麻煩的。如果直接操作數(shù)據(jù)庫記錄,就意味著需要手工處理主子表關(guān)系,處理刪除順序問題。On delete cascade允許了一種“先刪除主表,連帶刪除子表記錄”的功能,同時確保數(shù)據(jù)表整體參照完整性。
      創(chuàng)建on delete cascade外鍵,只需要在創(chuàng)建外鍵中添加相應(yīng)的子句。
      SQL> alter table child add constraint FK_CHILD_PRIM foreign key(v_id) references prim(v_id) on delete cascade;
      Table altered
      測試:
    SQL> delete prim where v_id=2;
    1 row deleted
    SQL> select * from prim;
    V_ID V_NAME
    ---- --------------------------------------------------------------------------------
    1 kk
    3 iowkd
    SQL> select * from child;
    C_ID V_ID C_NAME
    ---- ---- --------------------------------------------------------------------------------
    1    1 kll
    2    1 ddkll
    3    1 43kll
    SQL> rollback;
    Rollback complete
      刪除主表操作成功,對應(yīng)的子表記錄被連帶自動刪除。但是其他操作依然是不允許進(jìn)行。
      SQL> update prim set v_id=4 where v_id=2;
      update prim set v_id=4 where v_id=2
      ORA-02292:違反完整約束條件(A.FK_CHILD_PRIM) - 已找到子記錄
      SQL> update child set v_id=5 where v_id=2;
      update child set v_id=5 where v_id=2
      ORA-02291: 違反完整約束條件 (A.FK_CHILD_PRIM) - 未找到父項關(guān)鍵字
      On delete cascade被稱為“級聯(lián)刪除”,對開發(fā)人員來講是一種方便的策略,可以直接“無視”子記錄而刪掉主記錄。但是,一般情況下,數(shù)據(jù)庫設(shè)計人員和DBA一般都不推薦這樣的策略。
      究其原因,還是由于系統(tǒng)業(yè)務(wù)規(guī)則而定。On delete cascade的確在一定程度上很方便,但是這種自動操作在一些業(yè)務(wù)系統(tǒng)中是可能存在風(fēng)險的。例如:一個系統(tǒng)中存在一個參數(shù)引用關(guān)系,這個參數(shù)被引用到諸如合同的主記錄中。按照業(yè)務(wù)規(guī)則,如果這個參數(shù)被引用過,就不應(yīng)當(dāng)被刪除。如果我們設(shè)置了on delete cascade外鍵,連帶的合同記錄就自動的被“干掉”了。開發(fā)參數(shù)模塊的同事一般情況下,也沒有足夠的“覺悟”去做手工判定。基于這個因素,我們推薦采用默認(rèn)的強(qiáng)約束關(guān)聯(lián),起碼不會引起數(shù)據(jù)丟失的情況。
      四、On Delete Set Null
      除了直接刪除記錄,Oracle還提供了一種保留子表記錄的策略。注意:外鍵約束本身不限制字段為空的問題。如果一個外鍵被設(shè)置為on delete set null,當(dāng)刪除主表記錄的時候,無論是否存在子表對應(yīng)記錄,主表記錄都會被刪除,子表對應(yīng)列被清空。
      SQL> alter table child drop constraint fk_child_prim;
      Table altered
      SQL> alter table child add constraint FK_CHILD_PRIM foreign key(v_id) references prim(v_id) on delete set null;
      Table altered
      刪除主表記錄。
    SQL> delete prim where v_id=2;
    1 row deleted
    SQL> select * from prim;
    V_ID V_NAME
    ---- --------------------------------------------------------------------------------
    1 kk
    3 iowkd
    SQL> select * from child;
    C_ID V_ID C_NAME
    ---- ---- --------------------------------------------------------------------------------
    1    1 kll
    2    1 ddkll
    3    1 43kll
    4      43kll
    5      4ll
    SQL> rollback;
    Rollback complete
      主表記錄刪除,子表外鍵列被清空。其他約束動作沒有變化。
      SQL> update prim set v_id=4 where v_id=2;
      update prim set v_id=4 where v_id=2
      ORA-02292:違反完整約束條件(A.FK_CHILD_PRIM) - 已找到子記錄
      SQL> update child set v_id=5 where v_id=2;
      update child set v_id=5 where v_id=2
      ORA-02291: 違反完整約束條件 (A.FK_CHILD_PRIM) - 未找到父項關(guān)鍵字
      那么,下一個問題是:如果外鍵列不能為空,會怎么樣呢?
    SQL> desc child;
    Name   Type          Nullable Default Comments
    ------ ------------- -------- ------- --------
    C_ID   NUMBER(3)
    V_ID   NUMBER(3)     Y
    C_NAME VARCHAR2(100) Y
    SQL> alter table child modify v_id not null;
    Table altered
    SQL> desc child;
    Name   Type          Nullable Default Comments
    ------ ------------- -------- ------- --------
    C_ID   NUMBER(3)
    V_ID   NUMBER(3)
    C_NAME VARCHAR2(100) Y
    SQL> delete prim where v_id=2;
    delete prim where v_id=2
    ORA-01407: 無法更新 ("A"."CHILD"."V_ID")為 NULL
      更改失敗~
      五、傳說中的on update cascade
      On update cascade被稱為“級聯(lián)更新”,是關(guān)系數(shù)據(jù)庫理論中存在的一種外鍵操作類型。這種類型指的是:當(dāng)主表的記錄被修改(主鍵值修改),對應(yīng)子表的外鍵列值連帶的進(jìn)行修改。
      SQL> alter table child add constraint FK_CHILD_PRIM foreign key(v_id) references prim(v_id) on update cascade;
      alter table child add constraint FK_CHILD_PRIM foreign key(v_id) references prim(v_id) on update cascade
      ORA-00905: 缺失關(guān)鍵字
      目前的Oracle版本中,似乎還不支持on update cascade功能。Oracle在官方服務(wù)中對這個問題的闡述是:在實際系統(tǒng)開發(fā)環(huán)境中,直接修改主鍵的情況是比較少的。所以,也許在將來的版本中,這個特性會進(jìn)行支持。
      六、結(jié)論
      Oracle外鍵是我們?nèi)粘1容^常見的約束類型。在很多專家和業(yè)界人員的討論中,我們經(jīng)常聽到“使用外鍵還是系統(tǒng)編碼”的爭論。支持外鍵策略的一般都是數(shù)據(jù)庫專家和“大撒把”的設(shè)計師,借助數(shù)據(jù)庫天然的特性,可以高效實現(xiàn)功能。支持系統(tǒng)編碼的人員大都是“對象派”等新派人員,相信可以借助系統(tǒng)前端解決所有問題。
      筆者對外鍵的觀點是“適度外鍵,雙重驗證”。外鍵要設(shè)計在最緊密的引用關(guān)系中,對驗證動作,前端和數(shù)據(jù)庫端都要進(jìn)行操作。外鍵雖然可以保證最后安全渠道,但是不能將正確易于接受的信息反饋到前端。前端開發(fā)雖然比較直觀,但是的確消耗精力。所以,把握適度是重要的出發(fā)點。

    posted @ 2014-12-03 13:35 順其自然EVO 閱讀(622) | 評論 (0)編輯 收藏

    SQL優(yōu)化中索引列使用函數(shù)之靈異事件

     在SQL優(yōu)化內(nèi)容中有一種說法說的是避免在索引列上使用函數(shù)、運算等操作,否則Oracle優(yōu)化器將不使用索引而使用全表掃描,但是也有一些例外的情況,今天我們就來看看該靈異事件。
      一般而言,以下情況都會使Oracle的優(yōu)化器走全表掃描,舉例:
      1.         substr(hbs_bh,1,4)=’5400’,優(yōu)化處理:hbs_bh like ‘5400%’
      2.         trunc(sk_rq)=trunc(sysdate), 優(yōu)化處理:sk_rq>=trunc(sysdate) and sk_rq<trunc(sysdate+1)
      3.         進(jìn)行了顯式或隱式的運算的字段不能進(jìn)行索引,如:
      ss_df+20>50,優(yōu)化處理:ss_df>30
      'X' || hbs_bh>’X5400021452’,優(yōu)化處理:hbs_bh>'5400021542'
      sk_rq+5=sysdate,優(yōu)化處理:sk_rq=sysdate-5
      4.         條件內(nèi)包括了多個本表的字段運算時不能進(jìn)行索引,如:ys_df>cx_df,無法進(jìn)行優(yōu)化
      qc_bh || kh_bh='5400250000',優(yōu)化處理:qc_bh='5400' and kh_bh='250000'
      5.  避免出現(xiàn)隱式類型轉(zhuǎn)化
      hbs_bh=5401002554,優(yōu)化處理:hbs_bh='5401002554',注:此條件對hbs_bh 進(jìn)行隱式的to_number轉(zhuǎn)換,因為hbs_bh字段是字符型。
      有一些其它的例外情況,如果select 后邊只有索引列且where查詢中的索引列含有非空約束的時候,以上規(guī)則不適用,如下示例:
      先給出所有腳本及結(jié)論:
      drop table t  purge;
      Create Table t  nologging As select *  from    dba_objects d ;
      create   index ind_objectname on  t(object_name);
      select t.object_name from t where t.object_name ='T';        --走索引
      select t.object_name from t where UPPER(t.object_name) ='T';       --不走索引
      select t.object_name from t where UPPER(t.object_name) ='T' and t.object_name IS NOT NULL ;           --走索引  (INDEX FAST FULL SCAN)
      select t.object_name from t where UPPER(t.object_name) ||'AAA' ='T'||'AAA' and t.object_name IS NOT NULL ;     --走索引  (INDEX FAST FULL SCAN)
      select t.object_name,t.owner from t where UPPER(t.object_name) ||'AAA' ='T'||'AAA' and t.object_name IS NOT NULL ;     --不走索引
      測試代碼:
    C:\Users\華榮>sqlplus lhr/lhr@orclasm
    SQL*Plus: Release 11.2.0.1.0 Production on 星期三 11月 12 10:52:29 2014
    Copyright (c) 1982, 2010, Oracle.  All rights reserved.
    連接到:
    Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
    With the Partitioning, Automatic Storage Management, OLAP, Data Mining
    and Real Application Testing options
    SQL>
    SQL>
    SQL> drop table t  purge;
    表已刪除。
    SQL> Create Table t  nologging As select *  from    dba_objects d ;
    表已創(chuàng)建。
    SQL>  create   index ind_objectname on  t(object_name);
    索引已創(chuàng)建。
     ---- t表所有列均可以為空
    SQL> desc t
    Name                      Null?    Type
    ----------------------------------------- -------- ----------------------------
    OWNER                               VARCHAR2(30)
    OBJECT_NAME                         VARCHAR2(128)
    SUBOBJECT_NAME                      VARCHAR2(30)
    OBJECT_ID                           NUMBER
    DATA_OBJECT_ID                      NUMBER
    OBJECT_TYPE                         VARCHAR2(19)
    CREATED                             DATE
    LAST_DDL_TIME                       DATE
    TIMESTAMP                           VARCHAR2(19)
    STATUS                              VARCHAR2(7)
    TEMPORARY                           VARCHAR2(1)
    GENERATED                           VARCHAR2(1)
    SECONDARY                           VARCHAR2(1)
    NAMESPACE                           NUMBER
    EDITION_NAME                        VARCHAR2(30)
    SQL>
    SQL>  set autotrace traceonly;
    SQL>  select t.object_name from t where t.object_name ='T';
    執(zhí)行計劃
    ----------------------------------------------------------
    Plan hash value: 4280870634
    -----------------------------------------------------------------------------------
    | Id  | Operation        | Name           | Rows  | Bytes | Cost (%CPU)| Time     |
    -----------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT |                |     1 |    66 |     3   (0)| 00:00:01 |
    |*  1 |  INDEX RANGE SCAN| IND_OBJECTNAME |     1 |    66 |     3   (0)| 00:00:01 |
    -----------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    1 - access("T"."OBJECT_NAME"='T')
    Note
    -----
    - dynamic sampling used for this statement (level=2)
    - SQL plan baseline "SQL_PLAN_503ygb00mbj6k165e82cd" used for this statement
    統(tǒng)計信息
    ----------------------------------------------------------
    34  recursive calls
    43  db block gets
    127  consistent gets
    398  physical reads
    15476  redo size
    349  bytes sent via SQL*Net to client
    359  bytes received via SQL*Net from client
    2  SQL*Net roundtrips to/from client
    0  sorts (memory)
    0  sorts (disk)
    1  rows processed
    SQL>  select t.object_name from t where UPPER(t.object_name) ='T';
    執(zhí)行計劃
    ----------------------------------------------------------
    Plan hash value: 1601196873
    --------------------------------------------------------------------------
    | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |      |    12 |   792 |   305   (1)| 00:00:04 |
    |*  1 |  TABLE ACCESS FULL| T    |    12 |   792 |   305   (1)| 00:00:04 |
    --------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    1 - filter(UPPER("T"."OBJECT_NAME")='T')
    Note
    -----
    - dynamic sampling used for this statement (level=2)
    - SQL plan baseline "SQL_PLAN_9p76pys5gdb2b94ecae5c" used for this statement
    統(tǒng)計信息
    ----------------------------------------------------------
    29  recursive calls
    43  db block gets
    1209  consistent gets
    1092  physical reads
    15484  redo size
    349  bytes sent via SQL*Net to client
    359  bytes received via SQL*Net from client
    2  SQL*Net roundtrips to/from client
    0  sorts (memory)
    0  sorts (disk)
    1  rows processed
    SQL>  select t.object_name from t where UPPER(t.object_name) ='T' and t.object_name IS NOT NULL ;
    執(zhí)行計劃
    ----------------------------------------------------------
    Plan hash value: 3379870158
    ---------------------------------------------------------------------------------------
    | Id  | Operation            | Name           | Rows  | Bytes | Cost (%CPU)| Time     |
    ---------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT     |                |    51 |  3366 |   110   (1)| 00:00:02 |
    |*  1 |  INDEX FAST FULL SCAN| IND_OBJECTNAME |    51 |  3366 |   110   (1)| 00:00:02 |
    ---------------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    1 - filter("T"."OBJECT_NAME" IS NOT NULL AND UPPER("T"."OBJECT_NAME")='T')
    Note
    -----
    - dynamic sampling used for this statement (level=2)
    - SQL plan baseline "SQL_PLAN_czkarb71kthws18b0c28f" used for this statement
    統(tǒng)計信息
    ----------------------------------------------------------
    29  recursive calls
    43  db block gets
    505  consistent gets
    384  physical reads
    15612  redo size
    349  bytes sent via SQL*Net to client
    359  bytes received via SQL*Net from client
    2  SQL*Net roundtrips to/from client
    0  sorts (memory)
    0  sorts (disk)
    1  rows processed
    SQL>  select t.object_name,t.owner from t where UPPER(t.object_name) ||'AAA' ='T'||'AAA' and t.object_name IS NOT NULL ;
    執(zhí)行計劃
    ----------------------------------------------------------
    Plan hash value: 1601196873
    --------------------------------------------------------------------------
    | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |      |    51 |  4233 |   304   (1)| 00:00:04 |
    |*  1 |  TABLE ACCESS FULL| T    |    51 |  4233 |   304   (1)| 00:00:04 |
    --------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    1 - filter("T"."OBJECT_NAME" IS NOT NULL AND
    UPPER("T"."OBJECT_NAME")||'AAA'='TAAA')
    Note
    -----
    - dynamic sampling used for this statement (level=2)
    - SQL plan baseline "SQL_PLAN_au9a1c4hwdtb894ecae5c" used for this statement
    統(tǒng)計信息
    ----------------------------------------------------------
    30  recursive calls
    44  db block gets
    1210  consistent gets
    1091  physical reads
    15748  redo size
    408  bytes sent via SQL*Net to client
    359  bytes received via SQL*Net from client
    2  SQL*Net roundtrips to/from client
    0  sorts (memory)
    0  sorts (disk)
    1  rows processed
    SQL> select t.object_name from t where UPPER(t.object_name) ||'AAA' ='T'||'AAA' and t.object_name IS NOT NULL ;
    執(zhí)行計劃
    ----------------------------------------------------------
    Plan hash value: 3379870158
    ---------------------------------------------------------------------------------------
    | Id  | Operation            | Name           | Rows  | Bytes | Cost (%CPU)| Time     |
    ---------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT     |                |    51 |  3366 |   110   (1)| 00:00:02 |
    |*  1 |  INDEX FAST FULL SCAN| IND_OBJECTNAME |    51 |  3366 |   110   (1)| 00:00:02 |
    ---------------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    1 - filter("T"."OBJECT_NAME" IS NOT NULL AND
    UPPER("T"."OBJECT_NAME")||'AAA'='TAAA')
    Note
    -----
    - dynamic sampling used for this statement (level=2)
    - SQL plan baseline "SQL_PLAN_1gu36rnh3s2a318b0c28f" used for this statement
    統(tǒng)計信息
    ----------------------------------------------------------
    28  recursive calls
    44  db block gets
    505  consistent gets
    6  physical reads
    15544  redo size
    349  bytes sent via SQL*Net to client
    359  bytes received via SQL*Net from client
    2  SQL*Net roundtrips to/from client
    0  sorts (memory)
    0  sorts (disk)
    1  rows processed
    SQL>
      其實很好理解的,索引可以看成是小表,一般而言索引總是比表本身要小得多,如果select 后需要檢索的項目在索引中就可以檢索的到那么Oracle優(yōu)化器為啥還去大表中尋找數(shù)據(jù)呢?

    posted @ 2014-12-03 13:35 順其自然EVO 閱讀(586) | 評論 (0)編輯 收藏

    利用binlog進(jìn)行數(shù)據(jù)庫的還原

    前言:在學(xué)習(xí)mysql備份的時候,深深的感受到mysql的備份還原功能沒有oracle強(qiáng)大;比如一個很常見的恢復(fù)場景:基于時間點的恢復(fù),oracle通過rman工具就能夠很快的實現(xiàn)數(shù)據(jù)庫的恢復(fù),但是mysql在進(jìn)行不完全恢復(fù)的時候很大的一部分要依賴于mysqlbinlog這個工具運行binlog語句來實現(xiàn),本文檔介紹通過mysqlbinlog實現(xiàn)各種場景的恢復(fù);
      一、測試環(huán)境說明:使用mysqlbinlog工具的前提需要一個數(shù)據(jù)庫的完整性備份,所以需要事先對數(shù)據(jù)庫做一個完整的備份,本文檔通過mysqlbackup進(jìn)行數(shù)據(jù)庫的全備
      二、測試步驟說明:
      數(shù)據(jù)庫的插入準(zhǔn)備工作
      2.1 在時間點A進(jìn)行一個數(shù)據(jù)庫的完整備份;
      2.2 在時間點B創(chuàng)建一個數(shù)據(jù)庫BKT,并在BKT下面創(chuàng)建一個表JOHN,并插入5條數(shù)據(jù);
      2.3 在時間點C往表JOHN繼續(xù)插入數(shù)據(jù)到10條;
      數(shù)據(jù)庫的恢復(fù)工作
      2.4 恢復(fù)數(shù)據(jù)庫到時間點A,然后檢查數(shù)據(jù)庫表的狀態(tài);
      2.5 恢復(fù)數(shù)據(jù)庫到時間點B,檢查相應(yīng)的系統(tǒng)狀態(tài);
      2.6 恢復(fù)數(shù)據(jù)庫到時間點C,并檢查恢復(fù)的狀態(tài);
      三、場景模擬測試步驟(備份恢復(fù)是一件很重要的事情)
      3.1 執(zhí)行數(shù)據(jù)庫的全備份;
      [root@mysql01 backup]# mysqlbackup --user=root --password --backup-dir=/backup backup-and-apply-log //運行數(shù)據(jù)庫的完整備份
      3.2 創(chuàng)建數(shù)據(jù)庫、表并插入數(shù)據(jù)
    mysql> SELECT CURRENT_TIMESTAMP;
    +---------------------+
    | CURRENT_TIMESTAMP |
    +---------------------+
    | 2014-11-26 17:51:27 |
    +---------------------+
    1 row in set (0.01 sec)
    mysql> show databases; //尚未創(chuàng)建數(shù)據(jù)庫BKT
    +--------------------+
    | Database |
    +--------------------+
    | information_schema |
    | john |
    | mysql |
    | performance_schema |
    +--------------------+
    4 rows in set (0.03 sec)
    mysql> Ctrl-C --
    Aborted
    [root@mysql02 data]# mysql -uroot -p
    Enter password:
    Welcome to the MySQL monitor. Commands end with ; or \\g.
    Your MySQL connection id is 2
    Server version: 5.5.36-log Source distribution
    Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    Type \'help;\' or \'\\h\' for help. Type \'\\c\' to clear the current input statement.
    mysql> show master status;
    +------------------+----------+--------------+------------------+
    | File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
    +------------------+----------+--------------+------------------+
    | mysql-bin.000001 | 107 | | | //當(dāng)前數(shù)據(jù)庫log的pos狀態(tài)
    +------------------+----------+--------------+------------------+
    1 row in set (0.00 sec)
    mysql> SELECT CURRENT_TIMESTAMP; //當(dāng)前的時間戳 當(dāng)前時間點A
    +---------------------+
    | CURRENT_TIMESTAMP |
    +---------------------+
    | 2014-11-26 17:54:12 |
    +---------------------+
    1 row in set (0.00 sec)
    mysql> create database BKT; //創(chuàng)建數(shù)據(jù)庫BKT
    Query OK, 1 row affected (0.01 sec)
    mysql> create table john (id varchar(32));
    ERROR 1046 (3D000): No database selected
    mysql> use bkt;
    ERROR 1049 (42000): Unknown database \'bkt\'
    mysql> use BKT;
    Database changed
    mysql> create table john (id varchar(32));
    Query OK, 0 rows affected (0.02 sec)
    mysql> insert into john values(\'1\');
    Query OK, 1 row affected (0.01 sec)
    mysql> insert into john values(\'2\');
    Query OK, 1 row affected (0.01 sec)
    mysql> insert into john values(\'3\');
    Query OK, 1 row affected (0.00 sec)
    mysql> insert into john values(\'4\');
    Query OK, 1 row affected (0.01 sec)
    mysql> insert into john values(\'5\');
    Query OK, 1 row affected (0.01 sec)
    mysql> SELECT CURRENT_TIMESTAMP; //插入5條數(shù)據(jù)后數(shù)據(jù)庫的時間點B,記錄該點便于數(shù)據(jù)庫的恢復(fù)
    +---------------------+
    | CURRENT_TIMESTAMP |
    +---------------------+
    | 2014-11-26 17:55:53 |
    +---------------------+
    1 row in set (0.00 sec)
    mysql> show master status;
    +------------------+----------+--------------+------------------+
    | File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
    +------------------+----------+--------------+------------------+
    | mysql-bin.000001 | 1204 | | | //當(dāng)前binlog的pos位置
    +------------------+----------+--------------+------------------+
    1 row in set (0.00 sec)
     3.3 設(shè)置時間點C的測試
    mysql> insert into john values(\'6\');
    Query OK, 1 row affected (0.02 sec)
    mysql> insert into john values(\'7\');
    Query OK, 1 row affected (0.01 sec)
    mysql> insert into john values(\'8\');
    Query OK, 1 row affected (0.01 sec)
    mysql> insert into john values(\'9\');
    Query OK, 1 row affected (0.01 sec)
    mysql> insert into john values(\'10\');
    Query OK, 1 row affected (0.03 sec)
    mysql> show master status;
    +------------------+----------+--------------+------------------+
    | File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
    +------------------+----------+--------------+------------------+
    | mysql-bin.000001 | 2125 | | |
    +------------------+----------+--------------+------------------+
    1 row in set (0.00 sec)
    mysql> SELECT CURRENT_TIMESTAMP;
    +---------------------+
    | CURRENT_TIMESTAMP |
    +---------------------+
    | 2014-11-26 17:58:08 |
    +---------------------+
    1 row in set (0.00 sec)
      3.4 以上的操作完成之后,便可以執(zhí)行數(shù)據(jù)庫的恢復(fù)測試
    [root@mysql02 data]# mysqlbackup --defaults-file=/backup/server-my.cnf --datadir=/data/mysql --backup-dir=/backup/ copy-back
    MySQL Enterprise Backup version 3.11.0 Linux-3.8.13-16.2.1.el6uek.x86_64-x86_64 [2014/08/26]
    Copyright (c) 2003, 2014, Oracle and/or its affiliates. All Rights Reserved.
    mysqlbackup: INFO: Starting with following command line ...
    mysqlbackup --defaults-file=/backup/server-my.cnf --datadir=/data/mysql
    --backup-dir=/backup/ copy-back
    mysqlbackup: INFO:
    IMPORTANT: Please check that mysqlbackup run completes successfully.
    At the end of a successful \'copy-back\' run mysqlbackup
    prints \"mysqlbackup completed OK!\".
    141126 17:59:58 mysqlbackup: INFO: MEB logfile created at /backup/meta/MEB_2014-11-26.17-59-58_copy_back.log
    --------------------------------------------------------------------
    Server Repository Options:
    --------------------------------------------------------------------
    datadir = /data/mysql
    innodb_data_home_dir = /data/mysql
    innodb_data_file_path = ibdata1:10M:autoextend
    innodb_log_group_home_dir = /data/mysql/
    innodb_log_files_in_group = 2
    innodb_log_file_size = 5242880
    innodb_page_size = Null
    innodb_checksum_algorithm = none
    --------------------------------------------------------------------
    Backup Config Options:
    --------------------------------------------------------------------
    datadir = /backup/datadir
    innodb_data_home_dir = /backup/datadir
    innodb_data_file_path = ibdata1:10M:autoextend
    innodb_log_group_home_dir = /backup/datadir
    innodb_log_files_in_group = 2
    innodb_log_file_size = 5242880
    innodb_page_size = 16384
    innodb_checksum_algorithm = none
    mysqlbackup: INFO: Creating 14 buffers each of size 16777216.
    141126 17:59:58 mysqlbackup: INFO: Copy-back operation starts with following threads
    1 read-threads 1 write-threads
    mysqlbackup: INFO: Could not find binlog index file. If this is online backup then server may not have started with --log-bin.
    Hence, binlogs will not be copied for this backup. Point-In-Time-Recovery will not be possible.
    141126 17:59:58 mysqlbackup: INFO: Copying /backup/datadir/ibdata1.
    mysqlbackup: Progress in MB: 200 400 600
    141126 18:00:22 mysqlbackup: INFO: Copying the database directory \'john\'
    141126 18:00:23 mysqlbackup: INFO: Copying the database directory \'mysql\'
    141126 18:00:23 mysqlbackup: INFO: Copying the database directory \'performance_schema\'
    141126 18:00:23 mysqlbackup: INFO: Completing the copy of all non-innodb files.
    141126 18:00:23 mysqlbackup: INFO: Copying the log file \'ib_logfile0\'
    141126 18:00:23 mysqlbackup: INFO: Copying the log file \'ib_logfile1\'
    141126 18:00:24 mysqlbackup: INFO: Creating server config files server-my.cnf and server-all.cnf in /data/mysql
    141126 18:00:24 mysqlbackup: INFO: Copy-back operation completed successfully.
    141126 18:00:24 mysqlbackup: INFO: Finished copying backup files to \'/data/mysql\'
    mysqlbackup completed //數(shù)據(jù)庫恢復(fù)完成
      授權(quán)并打開數(shù)據(jù)庫
      [root@mysql02 data]# chmod -R 777 mysql //需要授權(quán)后才能打開
      [root@mysql02 data]# cd mysql
      [root@mysql02 mysql]# ll
      總用量 733220
    -rwxrwxrwx. 1 root root 305 11月 26 18:00 backup_variables.txt
    -rwxrwxrwx. 1 root root 740294656 11月 26 18:00 ibdata1
    -rwxrwxrwx. 1 root root 5242880 11月 26 18:00 ib_logfile0
    -rwxrwxrwx. 1 root root 5242880 11月 26 18:00 ib_logfile1
    drwxrwxrwx. 2 root root 4096 11月 26 18:00 john
    drwxrwxrwx. 2 root root 4096 11月 26 18:00 mysql
    drwxrwxrwx. 2 root root 4096 11月 26 18:00 performance_schema
    -rwxrwxrwx. 1 root root 8488 11月 26 18:00 server-all.cnf
    -rwxrwxrwx. 1 root root 1815 11月 26 18:00 server-my.cnf //沒有BKT數(shù)據(jù)庫
    [root@mysql02 mysql]# service mysqld start //啟動數(shù)據(jù)庫
      3.5 進(jìn)行數(shù)據(jù)庫的恢復(fù)到時間點B
      [root@mysql02 mysql2]# pwd //備份的時候,需要備份binlog日志,之前的binlog目錄為/data/mysql2
      /data/mysql2
      [root@mysql02 mysql2]# mysqlbinlog --start-position=107 --stop-position=1203 mysql-bin.000001| mysql -uroot -p //根據(jù)post的位置進(jìn)行恢復(fù),當(dāng)前的pos位置為107,恢復(fù)到pos位置到1203
    Enter password:
    [root@mysql02 mysql2]# mysql -uroot -p
    Enter password:
    Welcome to the MySQL monitor. Commands end with ; or \\g.
    Your MySQL connection id is 3
    Server version: 5.5.36-log Source distribution
    Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    Type \'help;\' or \'\\h\' for help. Type \'\\c\' to clear the current input statement.
    mysql> show databases;
    +--------------------+
    | Database |
    +--------------------+
    | information_schema |
    | BKT |
    | john |
    | mysql |
    | performance_schema |
    +--------------------+
    5 rows in set (0.02 sec)
    mysql> use BKT
    Database changed
    mysql> show tables;
    +---------------+
    | Tables_in_BKT |
    +---------------+
    | john |
    +---------------+
    1 row in set (0.00 sec)
    mysql> select * from john;
    +------+
    | id |
    +------+
    | 1 |
    | 2 |
    | 3 |
    | 4 |
    | 5 |
    +------+
    5 rows in set (0.01 sec) //查看數(shù)據(jù)庫恢復(fù)成功
      3.6 恢復(fù)數(shù)據(jù)庫到時間點C
    [root@mysql02 mysql2]# mysqlbinlog --start-date=\"2014-11-27 09:21:56\" --stop-date=\"2014-11-27 09:22:33\" mysql-bin.000001| mysql -uroot -p123456 //本次通過基于時間點的恢復(fù),恢復(fù)到時間點C
    Warning: Using unique option prefix start-date instead of start-datetime is deprecated and will be removed in a future release. Please use the full name instead.
    Warning: Using unique option prefix stop-date instead of stop-datetime is deprecated and will be removed in a future release. Please use the full name instead.
    [root@mysql02 mysql2]# mysql -uroot -p
    Enter password:
    Welcome to the MySQL monitor. Commands end with ; or \\g.
    Your MySQL connection id is 6
    Server version: 5.5.36-log Source distribution
    Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    Type \'help;\' or \'\\h\' for help. Type \'\\c\' to clear the current input statement.
    mysql> show databases;
    +--------------------+
    | Database |
    +--------------------+
    | information_schema |
    | BKT |
    | john |
    | mysql |
    | performance_schema |
    +--------------------+
    5 rows in set (0.00 sec)
    mysql> use BKT
    Database changed
    mysql> select * from john;
    +------+
    | id |
    +------+
    | 1 |
    | 2 |
    | 3 |
    | 4 |
    | 5 |
    | 6 |
    | 7 |
    | 8 |
    | 9 |
    | 10 |
    +------+
    10 rows in set (0.00 sec) //經(jīng)過檢查成功恢復(fù)到時間點C
      四、mysqlbinlog的其他總結(jié):以上是利用binlog文件進(jìn)行基于時間點和binlog的POS位置恢復(fù)的測試,mysqlbinlog的使用還有很多功能,運行mysqlbinlog --help可以查看相應(yīng)參數(shù);
      4.1 查看binlog的內(nèi)容:[root@mysql02 mysql2]# mysqlbinlog mysql-bin.000001
      4.2 mysqlbinlog的其他常用參數(shù):
      -h  根據(jù)數(shù)據(jù)庫的IP
      -P  根據(jù)數(shù)據(jù)庫所占用的端口來分
      -server-id 根據(jù)數(shù)據(jù)庫serverid來還原(在集群中很有用)
      -d  根據(jù)數(shù)據(jù)庫名稱
      例如: [root@mysql02 mysql2]# mysqlbinlog -d BKT mysql-bin.000001 //還原BKT數(shù)據(jù)庫的信息

    posted @ 2014-12-03 13:34 順其自然EVO 閱讀(1367) | 評論 (0)編輯 收藏

    探索Oracle之?dāng)?shù)據(jù)庫升級一 升級補(bǔ)丁修復(fù)概述

     一、 升級路線圖
      無論你是誰,要想做數(shù)據(jù)庫升級,我想一定離不開如下這張升級線路圖;企業(yè)中數(shù)據(jù)庫的升級是一個浩大的工程,但是卻又必不可少,小在打一個PSU解決一個簡單的問題或?qū)崿F(xiàn)某個功能,大到打安裝Patch對數(shù)據(jù)庫版本升級,都是作為一名合格的DBA必備的技能。再后面的幾篇博客當(dāng)中將詳細(xì)講述如何將數(shù)據(jù)庫從11.2.0.3.0升級到11.2.0.4并且打上最新的OPATCH之后再升級到Oracle 12c。
      二、 升級類型:
      11.2.0.1.0 ----------11.2.0.4.0---------11.2.0.4.4-----------12.2.0.1.0
      CPU                      PSU
      Update                             upgrade
      1. 什么是PSU/CPU?
      CPU: Critical Patch Update   (SPU: Security Patch Update)
      Oracle對于其產(chǎn)品每個季度發(fā)行一次的安全補(bǔ)丁包,通常是為了修復(fù)產(chǎn)品中的安全隱患。
      PSU: Patch Set Updates
      Oracle對于其產(chǎn)品每個季度發(fā)行一次的補(bǔ)丁包,包含了bug的修復(fù)。Oracle選取被用戶下載數(shù)量多的,并且被驗證過具有較低風(fēng)險的補(bǔ)丁放入到每個季度的PSU中。在每個PSU中不但包含Bug的修復(fù)而且還包含了最新的CPU。
      2. 如何查找最新的PSU
      每個數(shù)據(jù)庫版本都有自己的PSU,PSU版本號體現(xiàn)在數(shù)據(jù)庫版本的最后一位,比如最新的10.2.0.5的PSU是10.2.0.5.6,而11.2.0.3的最新PSU則是11.2.0.4.3。
      MOS站點中OracleRecommended Patches — Oracle Database [ID 756671.1] 文檔中查到各個產(chǎn)品版本最新的PSU。
      如果你記不住這個文檔號,那么在MOS中以“PSU”為關(guān)鍵字搜索,通常這個文檔會顯示在搜索結(jié)果的最前面。
      注意:必須購買了Oracle基本服務(wù)獲取了CSI號以后才有權(quán)限登陸MOS站點。
      Upgrade與Update
      首先,我們針對所使用的數(shù)據(jù)庫可能會進(jìn)行如下措施,版本升級或補(bǔ)丁包升級,那何為版本升級、何為補(bǔ)丁包升級呢?
      比如我的當(dāng)前數(shù)據(jù)庫是10GR2版本,但公司最近有個升級計劃,把這套數(shù)據(jù)庫升級到當(dāng)下最新的11GR2,這種大版本間升級動作即為Upgrade。根據(jù)公司計劃在原廠工程師和DBA共同努力下,數(shù)據(jù)庫已升級到11GR2,當(dāng)下版本為11.2.0.4.0。這時候原廠工程師推薦把最新的PSU給打上,獲得老板的批準(zhǔn)之后,我們又把數(shù)據(jù)庫進(jìn)行補(bǔ)丁包的升級,應(yīng)用了PSU Patch:18522509之后,數(shù)據(jù)庫版本現(xiàn)在成為11.2.0.4.3,這個過程即是Update。
      不得不再次提醒,Upgrade和Update都希望在獲得原廠的支持下進(jìn)行,尤其是Upgrade,這對于企業(yè)來說是個非常大的動作!
      PSR(Patch Set Release)和 PSU(Patch Set Update)
      8i、9i、10g、11g、12c這是其主要版本號,每一版本會陸續(xù)有兩至三個發(fā)行版,如10.1,10.2,和11.1,11.2分別是10g和11g的兩個發(fā)行版。對于每一個發(fā)行版軟件中發(fā)現(xiàn)的BUG,給出相應(yīng)的修復(fù)補(bǔ)丁。每隔一定時期,會將所有補(bǔ)丁集成到軟件中,經(jīng)過集成測試后,進(jìn)行發(fā)布,也稱為PSR(Patch Set Release)。以10.2為例,10.2.0.1.0是基礎(chǔ)發(fā)行版,至今已有三個PSR發(fā)布,每個PSR修改5位版本號的第4位,最新10.2的PSR為10.2.0.4.0。(11.1.0.6.0是11.1的基礎(chǔ)發(fā)行版,11.1.0.7.0是第一次PSR)。
      在某個PSR之后編寫的補(bǔ)丁,在還沒有加入到下一個PSR之前,以個別補(bǔ)丁(InterimPatch)的形式提供給客戶。某個個別補(bǔ)丁是針對Oracle公司發(fā)現(xiàn)的或客戶報告的某一個BUG編寫的補(bǔ)丁,多個個別補(bǔ)丁之間一同安裝時可能會有沖突,即同一個目標(biāo)模塊分別進(jìn)行了不同的修改。另外,即便在安裝時沒有發(fā)現(xiàn)沖突,由于沒有進(jìn)行嚴(yán)格的集成測試,運行過程中由于相互作用是否會發(fā)生意外也不能完全排除。
      除去修改功能和性能BUG的補(bǔ)丁,還有應(yīng)對安全漏洞的安全補(bǔ)丁。Oracle公司定期(一年四期)發(fā)布安全補(bǔ)丁集,稱之為CPU(Critical Patch Updates)。
      由于數(shù)據(jù)庫在信息系統(tǒng)的核心地位,對其性能和安全性的要求非常高。理應(yīng)及時安裝所有重要補(bǔ)丁。另外一個方面,基于同樣的理由,要求數(shù)據(jù)庫系統(tǒng)必須非常穩(wěn)定,安裝補(bǔ)丁而導(dǎo)致的系統(tǒng)故障和性能下降同樣不可接受。DBA經(jīng)常面臨一個非常困難的選擇:對于多個修復(fù)重要BUG的個別補(bǔ)丁是否安裝。不安裝,失去預(yù)防故障發(fā)生的機(jī)會,以后故障發(fā)生時,自己是無作為;安裝,如果這些補(bǔ)丁中存在著倒退BUG,或者相互影響,以后發(fā)生由于安裝補(bǔ)丁而造成的故障時,自己則是無事生非!而等待下一個PSR,一般又需要一年時間。因此,出了PSU(Patch Set Update)
      三、Oracle 版本說明
      Oracle 的版本號很多,先看11g的一個版本號說明:
      注意:在oracle 9.2 版本之后, oracle 的maintenance release number 是在第二數(shù)字位更改。而在之前,是在第三個數(shù)字位。
      1. Major Database ReleaseNumber
      第一個數(shù)字位,它代表的是一個新版本軟件,也標(biāo)志著一些新的功能。如11g,10g。
      2. Database MaintenanceRelease Number
      第二個數(shù)字位,代表一個maintenancerelease 級別,也可能包含一些新的特性。
      3. Fusion Middleware ReleaseNumber
      第三個數(shù)字位,反應(yīng)Oracle 中間件(Oracle Fusion Middleware)的版本號。
      4. Component-Specific ReleaseNumber
      第四個數(shù)字位,主要是針對組件的發(fā)布級別。不同的組件具有不同的號碼。 比如Oracle 的patch包。
      5. Platform-Specific ReleaseNumber
      第五個數(shù)字位,這個數(shù)字位標(biāo)識一個平臺的版本。 通常表示patch 號。

    posted @ 2014-12-03 13:33 順其自然EVO 閱讀(538) | 評論 (0)編輯 收藏

    僅列出標(biāo)題
    共394頁: First 上一頁 7 8 9 10 11 12 13 14 15 下一頁 Last 
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    導(dǎo)航

    統(tǒng)計

    • 隨筆 - 3936
    • 文章 - 404
    • 評論 - 179
    • 引用 - 0

    常用鏈接

    留言簿(55)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 欧洲乱码伦视频免费| 国产精品亚洲一区二区三区| 亚洲AV无码国产在丝袜线观看| 亚洲国产精品嫩草影院久久| 四虎国产精品免费久久影院| 成人免费无码大片A毛片抽搐| 成人免费a级毛片| 2021免费日韩视频网| 精品女同一区二区三区免费站| 最近2018中文字幕免费视频| 精品无码AV无码免费专区| 久久免费观看国产精品| 性色午夜视频免费男人的天堂| 99免费观看视频| 美女内射毛片在线看免费人动物| 最好看最新的中文字幕免费| 成年人网站免费视频| 欧洲精品成人免费视频在线观看 | 亚洲一区二区三区深夜天堂| 亚洲第一网站免费视频| 91亚洲视频在线观看| 亚洲一区精彩视频| 亚洲精品亚洲人成在线| 国产亚洲精品91| jizz中国免费| 日韩免费视频一区二区| 69视频免费在线观看| 91情侣在线精品国产免费| 大学生a级毛片免费观看| 免费人成在线观看网站视频 | 一区二区三区在线免费看| 亚洲成年人免费网站| 美女视频黄a视频全免费| 在线观看免费a∨网站| 亚洲国产一区视频| 亚洲日韩中文无码久久| 亚洲自偷精品视频自拍| 亚洲最大av资源站无码av网址| 爱情岛论坛亚洲品质自拍视频网站| 日韩毛片免费一二三| 免费国产99久久久香蕉|