1. 程式人生 > >面試中各個型別專案講解

面試中各個型別專案講解

一、ERP進銷存專案

1.說說你最近做的這個專案的背景?

這個專案是為××(名稱自己構思,為防止同學們面試期間撞車,此處不提供公司名稱,但是此名稱需要同學們調查一下這個公司是否真實存在,在百度上搜索一下,例如武漢商貿公司,列出來一些名字,不要找第一頁的名字,最好向後翻幾頁)商貿公司做的,公司原有的專案是一個覆蓋地區為省的平臺,現在公司規模擴張,全國各地建分公司,省內管理相對來說比較有侷限性,加上全國全聯網,採購、銷售、貨運、倉儲、配貨、財務核算各方面發生了很大的變化,所以重新起了一套新的平臺。

這個專案可以說算是二次開發,但是業務里程變化蠻大的。尤其是加上了一些資料分析,資料探勘的東西,而且報表的統計資料量也比之前的大很多,複雜度高很多。這個專案開發主要是從CRM、進銷存、倉儲、財務四個方面做了大的改動,基礎平臺方面多添加了一些功能,比如像合同啊,報銷啊這些東西不再以網點為單位了,改成全國統一編排。

2.你的表結構是如何設計的?為什麼這麼設計?

表結構方面初期受原始專案的影響,一直想著在原始專案基礎上進行修改,後來發現原始專案的庫設計有問題,進行改造相對來說工程量很大,而且關聯關係新設計中發生了比較大的變化,最後推翻了重做的,原始資料做了個數據遷移。

比如說省內業務時,供應商A處採購,到貨運中心後,然後發貨給B客戶,但是改造成全國業務後,供應商A處採購如果再到貨運中心可能會造成成本的提升,需要直接發往B客戶處,這個過程中運單就在走單過程中原始專案無法處理了。這裡供應商A的單號是採購單號,但是到客戶B那邊應該是供貨單號,需要做單號的更改處理。最後設計的將原來的分銷業務擴充套件成了分銷和直銷兩種。表結構方面也做了調整,將原始的業務擴充套件成分銷表與直銷表,分開管理。同時也會後期資料探勘降低一些工作難度。

設計方面比較獨特的幾個地方我說一下

第一個是供應商採購價格這個欄位,原始設計中是一個商品對一個價錢,基於原材料漲價,人工漲價導致的價格變化直接對商品採購價格進行修改。做成全國專案後,採購來源就更多了,為了輔助後期的資料探勘,比對價格漲幅與預計增長量,配合貨運成本計算,需要對所有的價格變化波動進行資料分析,所以添加了價格波對錶,同時原始表中也儲存目前的最終價格。雖然資料微量冗餘,最後價格兩個表中儲存,但是整體執行效能方面得到了很大的提升,而且這樣設計才能配合多組資料,計算採購差價,核算最終成本。簡單來說,A地的貨物便宜,但是到達客戶的運輸成本高,B地的貨物貴,到達客戶的運輸成本低,總體核算需要配合很多資料。但是又不能單純的從價格方面放棄某一個供應商,所以需要監控其價格波動量,必須做相應的表設計調整。

第二個是採購運輸方面的調整比較大。省內專案的中的設計允許出現一次採購途徑A,B,C,D四個地方,一次完成若干個運單,也就是車務排程與採購單是一對多的關係,但是全國專案中,由於發車地點多了,若干個採購任務可以從不同地點發車,運輸成本反而降低了,畢竟第一個採購完成的貨物在路上跑了很久。再有,不同地點的車務組規模不同,不一定能完成一個採購任務。所以設計方面做了很大的調整。一個採購單可以允許拆分成若干的子任務單,而每個車務排程只對應一個子任務單。簡單的說就是原始車務排程對採購單是一對多,改成了採購單對子任務單一對多,車務排程對子任務一對多。降低了原始任務中一個運單運輸時間成本過高的問題。

第三個是採購執行單的修訂。原始設計中採購計劃單與採購執行單就是一個單據,稽核中就執行。全國專案中,一份採購計劃對應的採購如果一個供應商不能滿足,需要從多個供應商處進行調配,這樣採購執行單對採購計劃由原始的一對一,變成了多對一。實際執行時,所有的採購單說的都是執行單。

還有很多此類的設計更改,我就不一一說明了。

3.這個專案為使用者提供了哪些服務?包括哪些模組?

從大的方面來說包含有4個系統,CRM系統、進銷存系統、財務系統、基礎平臺。公司的基本辦公在基礎平臺中,CRM系統做供應商管理、客戶管理、委託運輸客戶管理和政府部門相關管理,進銷存系統包含採購、銷售、庫存、合同、任務委託、還有幾個我涉及的不多,記不清了,財務系統包含內部結算、外部結算兩大塊。本來建議客戶買一套用友的財務系統的,後來沒有談成,最後這一塊外包出去了。其實系統中讓我來看比較特色的是風險評估和資料探勘後的預算決算處理。但是這一塊不是我所在的組做的,瞭解不是特別多,就知道個大概,就是資料分析後,為客戶直接出多個方案,供使用者選擇最終的執行方案。

4.你承擔這個專案的哪些核心模組

我開始在CRM組,做了大概兩個月左右,後來調到進銷存那邊去了。在進銷存這邊做了有將近4個月。進銷存的主核心我都參與開發了。

我說說採購吧

首先採購發起可以從4個任務開始。1,需求採購,2被動採購,3,計劃採購,4,預警採購。需求採購就是主動提出的採購,由採購部業務人員主動發起,沒有前置條件;被動採購是銷售那邊如果遇到庫存不足,自動轉入一個採購申請的流程,進入到採購主線上;計劃採購是ERP系統執行過程中,根據歷年的採購資料、銷售資料、庫存資料動態計算出來,生成一份採購計劃,這個只是個採購建議,然後轉入採購主線,就是交給採購部業務人員那邊進行確認;預警採購是庫存量超過當時的預設臨界點後發出一個採購申請計劃。不管哪一種最終都彙總到需求採購那邊,只不過轉入方式不同。

採購申請單下好後,根據採購內容劃分2級審批還是3級審批。如果是公司內部使用消耗品採購轉入採購主管審批,然後行政主管審批;如果是公司業務採購,走3級審批。訂單如果超過設定值,比如50萬,需要4級審批。

審批完以後生成任務單號,轉入後勤。後勤主管根據採購內容分派跟單人,跟單人根據採購單據和發貨方式選擇聯絡對方發貨或者轉入車輛排程或者委派第三方完成。如果對方發貨,記錄傳真號,語音資訊,交貨時間這些資訊;如果使用第三方運輸,根據採購單據選擇航空、鐵路,轉入CRM系統進行運單跟蹤;如果公司內部組織運輸任務,轉入車務組調車和司機還有隨行人員。運輸任務跟單人可以進行更換。

運輸任務完成後轉入驗收流程,驗收完成後,給每個批次的貨物分配一個內部管理的貨物編號。

如果這個貨是第三方到第三方的,也就是不經由公司倉儲的話,需要對貨物再進行一個出貨編號的分配,採購流程結束。如果不是第三方到第三方的運輸,貨物編號分配完轉入入庫流程,入庫以訂單為單位。一個訂單中所有貨物入庫完成,採購流程結束。上面說的這個事分銷的採購流程,還有直銷的採購流程,就是在中間有一個分任務單的地方不同,然後就是入庫結算方式不同,按子任務入庫的,而不是整個訂單入庫。

5.你碰到了哪些問題?你是怎麼解決的?

最大的問題還是設計問題,實現方面都還好,設計比較頭疼。如果沒有前期的專案恐怕還好一些,受影響太大了。剩下的比較突出的問題就是頁面的東西了,業務只要需求理解了問題都不大,頁面的指令碼控制應該說是消耗時間比較多的地方。整個專案做了半年多,現在的頁面jquery比以前強多了。指令碼方面就是多使用firebug這樣的工具吧,次數多了慢慢就知道問題定位如何快速準確了。

6.專案最大支援多少併發量?

組內測試的時候併發大概到100左右還算穩定,到200丟包率很高,能達到40%,到300時丟包基本上在90%以上。這個專案的受眾群體大概平均線上1000人左右,最大併發量大概在秒70到120左右,效能要求不是很高。

7.做完這個專案你有哪些收穫?

應該說的比較日常的東西,就是指令碼寫的比以前好多了,剩下就是設計思路方面有了一個不小的提升,再有就是客戶自定義欄位以前沒做過,這個專案的商品展示方面用了一次,感覺雖然很繁瑣,但是很有意思。

l  專案課程介紹

專案涉及前期課程知識點

l  Struts2(包括攔截器,檔案上傳下載)

l  Hibernate3(單表資料基本操作、關聯關係資料操作、延遲載入)

l  Spring3(Bean配置與管理,團隊開發模式,AOP)

l  ajax(非同步請求獲取資料)

l  jquery(頁面指令碼動作+頁面動態表格操作)

l  mysql(資料庫基本操作)

l  SSH整合

l  反射(反射的應用)

l  Maven構建專案

專案追加知識點

1.  反射泛型型別(製作通用類)

2.  檢視值與真實值應用

3.  報表工具(java讀寫Excel、jfreechart工具)

4.  Spring計時器任務

5.  Spring整合JavaMail(郵件傳送)

6.  jquery(jquery-struts2-json整合)

專案實用技巧

1.  通用類抽取製作

2.  程式碼自動生成器

3.  long型日期時間處理+頁面日期元件

4.  統一的異常處理方案

5.  全域性國際化應用

6.  頁面動態表現

7.  遮罩層應用

8.  許可權校驗系統

9.  通用分頁元件製作與使用(自定義標籤)

10. 動態資料庫表結構

l  專案介紹

ERP:http://baike.baidu.com/subview/109408/7177679.htm?from_id=22997&type=syn&fromtitle=ERP&fr=aladdin

   案例演示

l  主線流程分析

前置模組:主線流程製作需要滿足以下單元模組製作完成為基礎條件:

員工管理、許可權校驗系統、供應商管理、供應商商品列別管理、商品管理

採購流程

下采購單→採購審批→判定供應商是否送貨→轉入運輸部門→運輸任務指派→運輸任務完成→按採購訂單任務入庫→流程結束

銷售流程

下銷售單→銷售審批→判定庫存是否足夠→轉入分支採購流程→判定商家是否上門提貨→轉入運輸部門→運輸任務指派→按銷售訂單任務出庫→運輸任務完成→流程結束

(圖略)

採購退貨流程

下采購退貨單→採購退貨審批→判定商家是否上門提貨→轉入運輸部門→運輸任務指派→按採購退貨單任務出庫→運輸任務完成→流程結束

(圖略)

銷售退貨流程

下銷售退貨單→銷售退貨審批→判定商家是否上門送貨→轉入運輸部門→運輸任務指派→運輸任務完成→按銷售退貨單任務入庫→流程結束

(圖略)

l  子線流程分析

許可權管理

   許可權管理是所有管理類系統中必不可少的一部分,許可權管理通過資料的設定完成整體系統的操作能力控制,避免使用者進行非法操作。

本專案中許可權管理要進行具體的實現

CRM專案對接

CRM(Customer Relationship Management)即客戶管理系統,用於對客戶資訊,客戶關係進行維護。CRM是一套獨立的系統,各種大企業均擁有自主的客戶關係管理系統。使用該系統對老客戶進行關係維護,對新客戶的發展進行實時跟蹤,保持良好的發展態勢。

本專案中採購對應的供應商和銷售對應的客戶實際製作均採用CRM專案進行管理。

WebService介面對接

企業級應用中,每個企業的管理系統均採用獨立控制,獨立管理的方式進行。由於各個公司間系統存在有差異,不能進行良好的資料互動。例如A公司給B公司下了一份採購訂單,但是B公司並不知情,在B公司的管理系統中也無法即時呈現對應的資料,造成管理系統只為企業管理完成了一半的任務,沒有真正意義上的將資料流進行到底。基於此現象,為B公司製作對外的服務介面,A公司給B公司下訂單的同時,呼叫B公司的對外服務介面,這樣A公司內部的資料管理維護為正確的,同時B公司也接到的響應的資訊,只需要將對外介面進行一定的安全管理就可以輕鬆實現兩個系統間資料互動的模型。

本專案中不涉及WebService介面的適用,希望學員在對應課程學習完畢後,將對應知識新增到專案介紹與簡歷製作過程中。

l  專案類圖分析

l  專案如何服務於企業面試

專案在簡歷中的描述方式

LYMS是為藍源公司定製的一套企業ERP系統,包含供應鏈管理、銷售與市場管理、物流控制管理、財務管理、基礎平臺五個子系統,下轄分銷、客戶服務、財務管理、庫存管理、人力資源、報表、工作流服務、企業資訊系統、質量管理、運輸管理、專案管理、法規與標準和過程控制等四十多個功能。

本人蔘與設計並實現了LYMS中的許可權控制、採購與採購退貨管理、銷售與銷售退貨管理、運輸管理、倉庫出入庫管理及相關功能的報表製作。

專案在面試中描述的幾點注意

先從專案總體進行概括性描述,然後介紹4個主線任務,重點突出專案的業務流程,而不是實現技術,儘量迴避技術實現方式,以介紹業務為主。從四個核心業務中抽取一個業務為例,給面試官呈現業務流程的複雜度及個人思路的清晰程度。使面試官第一反應認為該專案你全程參與了,並且進行了相應的設計與開發。

由於該專案涉及內容過多,需要學員在下面課程的學習中,將後期所學知識與本專案聯絡起來,例如WebService和工作流。在這些知識學習完畢後,需要融會貫通到此專案中。這樣才能做到不被面試官在技術層面問倒。

關於實現方式方面的問題,面試時不要強調細節,會給對方一種露怯的感覺,不知道說什麼,只能拿技術實現方式向專案上堆砌,給人一種只做了這個功能的印象,應該儘量以大的方面來描述。如果被面試官問到具體細節,剖析需求,而不是實現方式。除非被問到如何實現,才從技術層面迴應對方,在迴應時一步到位,將所用的每個技術完成的任務是什麼,為什麼用這個技術描述給對方,讓對方相信你的選型是經過考慮的,而不是隻會用這一個技術,對於不能進行技術間的優缺點比對的學員,以專案經理技術選型為該技術為理由,將問題丟擲。

儘量不要總結通過該專案收穫了什麼,這樣會給人一種初入行的感覺,本套ERP系統不適合描述為新手所能完成的任務。該專案的進入,基本上奠定了你的開發能力與開發經驗至少在兩到三年,如果描述收穫,給人一種新手上路的感覺。

把這個專案支援起來需要的經驗不低於兩年的開發經驗,切勿犯低階錯誤,讓人感覺話語間不是一個有經驗的開發人員。

本專案中沒有太多過新的技術,該專案的亮點在於業務流程的複雜度,沉穩應對才是上策。由於專案中業務過於複雜,能不回答的問題儘量不要主動向外丟擲,避免給自己面試帶來不必要的麻煩。

l  專案計劃

週期

任務

具體內容

第一天

專案需求分析

Maven環境搭建

登入

未登入使用者校驗

專案介紹

主線流程分析

專案類圖分析

專案如何服務於企業面試

專案構建:Maven環境搭建(操作)

靜態頁面匯入(操作)

登入功能(操作)

未登陸使用者校驗(理解+操作)

第二天

部門管理

員工管理

部門管理(操作)

遮罩層應用(操作Q)

統一的異常處理方式(理解+操作)

國際化標準制作方案(操作)

按條件查詢通用設計(理解+操作)

通用分頁(操作Q)

通用基類抽取(理解)

員工管理(操作)

程式碼生成器製作(操作)

第三天

許可權系統分析設計實現

許可權模型設計分析(理解)

資源模型實現(操作Q)

角色模型實現(操作Q)

員工管理二次開發(操作Q)

許可權設定(操作)

許可權訪問過濾(理解+操作)

第四天

許可權樹製作

許可權樹模型分析(操作)

許可權樹製作(操作Q)

第五天

供應商管理

商品類別管理

商品資訊管理

供應商維護(操作)

商品類別維護(操作)

商品資訊維護(理解+操作Q)

第六天

採購申請

採購流程複習(理解)

狀態欄位設計(理解)

訂單生成(操作QQQ)

第七天

採購稽核、商品運輸

採購稽核(理解+操作)

商品運輸任務指派(理解+操作)

商品運輸任務完成(理解+操作)

第八天

倉庫管理

入庫

倉庫管理(操作)

訂單商品入庫(理解+操作QQQ)

倉庫商品明細管理(操作)

倉庫出入庫日誌管理(操作)

第九天

報表

報表設計思想(理解)

報表製作(理解+操作QQQ)

Jfreechart(操作Q)

jxl(操作)

第十天

專案總結

Spring定時器(操作)

常用資料頻度維護(操作)

庫存預警功能(操作)

JavaMail(操作)

專案總結

二、廣西移動電商

1.說說你最近做的這個專案的背景?

隨著中國通訊行業競爭程度的加劇,競爭的形態也發生了巨大的變化,從以產品、價格為主的競爭轉向以服務為主的競爭,服務成為主導競爭格局的重要因素。渠道作為企業完成客戶溝通、產品/服務交換過程以及實現價值、產生效益的重要載體,發揮了採集、傳達客戶和競爭對手等市場資訊,為買賣雙方提供便利,協調供需矛盾,為客戶提供合適的產品與服務,向客戶傳遞產品/服務資訊,實現營銷/服務目標等重要的功能。

廣西移動上線移動商城,一方面可以帶動傳統業務績效提升,增強客戶滿意度和粘性,另一方面,也為基於網際網路的商務模式創新奠定基礎。

針對上述行業環境變化和業務戰略目標,廣西移動在網上終端預約銷售基礎上,即將啟動網上商城建設專案,用於建立網上終端、營銷案線上銷售及相關輔助功能,包含商品管理、訂單管理、類目管理、客戶管理、合作商管理、客服管理、購物平臺、內容管理等,很大程度上分擔了人工的壓力,對提高客戶服務效率和客戶滿意度能夠起到較好的作用。

基於此,廣西移動提出建設網上商城建設專案工程。

廣西移動是按省進行管理(那麼寫的時候可以按各個省進行說)

電商的兩種運營模式:

B2C:商家對使用者

B2B:商家對商家,再對使用者

手機、營銷案(移動BOSS)、卡號三種商品!此外還有團購和秒殺活動(需要系統性能比較好來進行支撐)

除了內部系統,一般的系統都有邊界,它都會與其他的專案有交叉。電子渠道(電商專案與其他專案的合集!)

Boss系統是電商商城的核心,所有的營銷案都在這裡面。所有的功能交給統一的管理平臺,這裡需要具備單點登陸的功能。

CMS內容管理系統,主要做系統的頁面靜態化管理,文字、關鍵字、敏感詞的管理,這裡歸併到了後臺管理裡面了。

2.整個專案的功能架構如何?

系統前臺

單品頁面(終端+營銷案)

購物車(面試經常被問到)

首頁

使用者中心

系統後臺對賬管理:每天都要進行下單與銀行的錢是否一致

訂單管理:使用activiti工作流進行處理

靜態釋出:

商品管理

3.這個專案為使用者提供了哪些服務?包括哪些模組?

網上商城專案,用於建立網上終端、營銷案和號卡線上銷售及相關輔助功能,後臺包含商品管理、訂單管理、類目管理、客戶管理、合作商管理、客服管理、支付平臺、內容管理等,很大程度上分擔了人工的壓力,前臺包括個人中心購物車商城首頁,頻道頁,商品詳情頁(靜態化)提交訂單頁,支付頁面等頁面構成,對提高客戶服務效率和客戶滿意度能夠起到較好的作用。

4.你承擔這個專案的哪些核心模組

u  商品管理模組:其中包括品牌管理,屬性管理商品錄入/上下架管理,商品新增稽核,靜態頁面釋出

u  訂單模組:其中包括使用activiti工作流訂單的查詢和訂單的流轉,定時作廢

u  商品前臺首頁:其中主要負責首頁商品列表篩選,首頁上動態展示篩選條件,點選每一個篩選條件下面的商品列表要做聯動

u  單品頁面:採用freemarker來實現頁面靜態化,展示商品詳情資訊和商品購買,該頁面採用靜態化以減輕系統壓力,使用了cxf框架釋出服務

u  提交訂單頁面:提交使用者的訂單資訊, 處理併發問題。

u  個人中心,包括使用者的登入,個人資訊的管理,收貨地址的管理,使用者所下的訂單的管理

u  購物車:把購物車的資訊存在cookie裡面管理

5.這些模組的實現思路說一下

①商品管理模組

品牌管理:

主要掌握的核心是品牌的新增

l  圖片伺服器的搭建,

l  上傳圖片到圖片伺服器

l  表單的驗證,離開焦點的驗證,點選完成時的驗證,後臺伺服器的ajax驗證,表單規範

l  防止表單的二次提交

l  編輯時不需要修改品牌名,區別readOnly和disabled

l  刪除時的二次確認

注意:

自定義屬性必須掌握:html中自定義的屬性可以幫助索引元素

圖片伺服器的搭建

1.建立一個maven的web工程,在工程中建立一個存放資源的目錄

2.把tomcat的web.xml中DefaultServlet的只讀屬性改成false

3.編寫上傳到圖片伺服器的程式碼

由於應用伺服器與圖片伺服器出於不同的兩臺機器之中,所以可以提高系統的效能,能起到負載均衡的作用。上傳圖片時使用Jersey 客戶端 API 呼叫 REST 風格的 Web 服務,  Jersey 1 是一個開源的、可以用於生產環境的 JAX-RSRESTful Web Services  Java API 規範,JSR-311)實現。通過 Jersey 可以很方便的使用 Java 來建立一個 RESTful Web Services

byte[] fileByte = commFile.getBytes();
      //建立客服端,基於webservice
      Client client = Client.create();
      //指定資源路徑
   WebResource webResource = client.resource(Constants.picPath+fileName);
      //使用put的請求方式把資原始檔放到資源伺服器上
    webResource.put(String.class, fileByte);
前臺使用ajax提交表單,需要使用jquery的jquery.form.js外掛
$("#form").ajaxSubmit({
      url:url,
      type:"post",
      dataType:"text",
      data:{
          ...
      },
      //beforeSubmit:validate,
      success:function(responseText){
          var obj = $.parseJSON(responseText);
          
      },
      error:function(){
          
      }
});

4.  圖片伺服器中Upload資料夾中隨便建立一個檔案,防止空資料夾的情況下發布後upload消失

表單驗證

1.  提交時做驗證

做好約定,每個文字中設定reg屬性和tip自定義的屬性,reg存放正則表示式,tip中存放不合法時的提示資訊,還有品牌名稱重複的驗證。

reg2,tip屬於自定義的屬性,這種定義方式方便使用jquery的屬性選擇器

<p>
<label><samp>*</samp>品牌名稱:</label>
<input type="text" id="brandName" name="brandName" class="text state" reg2="^[a-zA-Z0-9\u4e00-\u9fa5]{1,20}$" tip="必須是中英文或數字字元,長度1-20"/>
      <span></span>
</p>

2.  在表單提交時做驗證使用$(“form”).submit(function(){ return false });,必填欄位和非必填的欄位需要區別對待

$("#form111").submit(function(){
      var isSubmit = true;
      $(this).find("[reg2]").each(function(){
          var regStr = $(this).attr("reg2");
          //剪掉值中的兩側的字串
          var value = $.trim($(this).val());
          var tip = $(this).attr("tip");
          //建立正則表示式的物件
          var reg = new RegExp(regStr);
          if(!reg.test(value)){
             $(this).next("span").html(tip);
             isSubmit = false;
             //跳出迴圈,在jquery的each語句之中跳出迴圈使用return false; 如果在原生js裡面可使用break;, return;:代表終止執行程式
             return false;
          }
      });
      
      $(this).find("[reg1]").each(function(){
          
          var regStr = $(this).attr("reg1");
          var value = $.trim($(this).val());
          var tip = $(this).attr("tip");
          var reg = new RegExp(regStr);
          if(value != null&& value != ""){
             if(!reg.test(value)){
                $(this).next("span").html(tip);
                isSubmit = false;
                return false;
             }
          }
          
      }); 
      return isSubmit;
});

3.  使用離焦事件做友好的提示

$("input[reg2]").blur(function(){
      var regStr = $(this).attr("reg2");
      var value = $.trim($(this).val());
      var tip = $(this).attr("tip");
      var reg = new RegExp(regStr);
      if(!reg.test(value)){
          $(this).next("span").html(tip);
      }else{
          $(this).next("span").html("");
      }
});

4.  表單的二次提交處理

l  鎖屏

l  鎖按鈕

②商品的查詢

商品查詢需要組合條件加分頁查詢

l  組合條件:品牌,稽核狀態,商品名稱,需要動態sql

<select id="queryItemByCondtion" resultMap="BaseResultMap" parameterType="map">
  
  select *
  from (select a.*, rownum rm
          from (
                select *
                  from eb_item ei
                  <where>
                     <if test="brandId != null">
                         ei.brand_id = #{brandId}  
                     </if>
                     <if test="auditStatus != null">
                        and ei.audit_status = #{auditStatus}  
                     </if>
                     <if test="showStatus != null">
                        and ei.show_status = #{showStatus}  
                     </if>
                     <if test="itemName != null">
                        and ei.item_name like '%${itemName}%'
                     </if>
                  </where>
                order by ei.item_id desc) a
             <![CDATA[
             where rownum < #{endNum}) b
   where b.rm > #{startNum}
             ]]>
  </select>
--查詢大於當前頁首行號,主要解決oracle的rownum不支援大於號的問題
select *
  from (
       --查詢小於當前最大行號的資料
       select rownum rm,a.*
          from (
          --第一個select查詢所有的業務資料
          select * from eb_item
          
          ) a
         where rownum < 21) b
 where b.rm > 10

l  分頁查詢

1.  查詢結果集的sql,傳入開始行數和結束的行數

select *
  from (select a.*, rownum rm
    from (
       ...
      內部sql
      ...
) a where rownum < #{endNum}) b
   where b.rm > #{startNum}

2.  使用內部sql查詢結果集的總條數

3.  使用分頁工具類,建立page物件更換每次的資料總條數和當前頁數和每頁的條數,查詢出結果集後把結果集註入到page物件之中

public class Page {
   int totalCount = 0;
   int pageSize = 10;
   int currentPageNo = 1;
   int startNum = 0;
   int endNum = 11;
   public Page(int totalCount, int pageSize, int currentPageNo) {
      super();
      this.totalCount = totalCount;
      this.pageSize = pageSize;
      this.currentPageNo = currentPageNo;
   }
   
   public int getStartNum(){
      return (currentPageNo - 1) * pageSize;
   }
 
   public int getEndNum(){
      return currentPageNo * pageSize + 1;
   }
   
   public int getTotalPage(){
      int totalPage = totalCount/pageSize;
      if(totalPage == 0 || totalCount%pageSize != 0){
          totalPage ++;
      }
      return totalPage;
   }
   
   public int getNextPage(){
      if(currentPageNo> = getTotalPage()){
          return currentPageNo;
      }else{
          return currentPageNo + 1;
      }
   }
   
   public int getPrePage(){
      if(currentPageNo< = 1){
          return currentPageNo;
      }else{
          return currentPageNo - 1;
      }
   }
   
   List<?> list;
 
   public List<?> getList() {
      return list;
   }
 
   public void setList(List<?> list) {
      this.list = list;
   }
 
   public int getTotalCount() {
      return totalCount;
   }
 
   public void setTotalCount(int totalCount) {
      this.totalCount = totalCount;
   }
 
   public int getPageSize() {
      return pageSize;
   }
 
   public void setPageSize(int pageSize) {
      this.pageSize = pageSize;
   }
 
   public int getCurrentPageNo() {
      return currentPageNo;
   }
 
   public void setCurrentPageNo(int currentPageNo) {
      this.currentPageNo = currentPageNo;
   }
 
   public void setStartNum(int startNum) {
      this.startNum = startNum;
   }
 
   public void setEndNum(int endNum) {
      this.endNum = endNum;
   }  
}

4. 製作前端樣式

var currentPageNo = parseInt($("#currentPageNo").val());
       var totalCount = parseInt($("#totalCount").val());
       var totalPage = parseInt($("#totalPage").val());
       $("#pagePiece").html(totalCount);
       $("#pageTotal").html(currentPageNo+"/"+totalPage);
        if(currentPageNo <= 1){
          $("#previous").hide();
       }else{
          $("#previous").show();
       }
       if(currentPageNo >= totalPage){
          $("#next").hide();
       }else{
          
          $("#next").show();
       } 
       $("#next").click(function(){
          $("#pageNo").val(parseInt(currentPageNo)+1);
          $("#form1").submit();
       });
       $("#previous").click(function(){
          $("#pageNo").val(parseInt(currentPageNo)-1);
          $("#form1").submit();
       });

Oracle  分頁sql的描述:

  1.最內層的寫查詢當前表的全量即可

  2.對於oracle資料庫分頁需要依賴於rownum,但是rownum不支援大於號,但是支援小於號,可以rownum小於結束行號查詢出來一個結果集(在全量的外層套一個select,它的結果集需要把rownum作為結果返回)

  3.在第二步的結果集基礎上再做一次查詢,查詢條件以第二步查詢出來的rownum的值作為條件大於開始行號即可

③商品釋出

Console和portal是分開部署在兩臺伺服器上,釋出需要在console端去控制,但是生成的靜態化的檔案要釋出到portal的工程之中,所以釋出的服務要在portal上,但是要在console中來呼叫,異構之間的呼叫要使用webservice。

1.  採用cxf的webservice框架來整合spring

2.  在web.xml中來配置cxf的核心servlet

<servlet>
       <servlet-name>cxfServlet</servlet-name>
 <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
       <!-- <init-param>
          <param-name>config-location</param-name>
          <param-value>classpath:cxf-servlet.xml</param-value>
       </init-param>
       <load-on-startup>1</load-on-startup> -->
 </servlet>
 <servlet-mapping>
       <servlet-name>cxfServlet</servlet-name>
       <url-pattern>/services/*</url-pattern>
</servlet-mapping>

3.  建立服務的介面和介面的實現類,注意介面上加上@WebService註解

4.  建立cxf的核心配置檔案cxf-servlet.xml,配置帶有介面的webservice服務使用

<jaxws:server>標籤

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"
   xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/core"
   xsi:schemaLocation="http://www.springframework.org/schema/beans 
          http://www.springframework.org/schema/beans/spring-beans.xsd
            http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
            http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
            http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd">
   <!-- 引入CXF Bean定義如下,早期的版本中使用 -->
   <import resource="classpath:META-INF/cxf/cxf.xml" />
   <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
   <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
   
   <jaxws:server id="publish" address="/publish" serviceClass="cn.itcast.ecps.ws.service.EbItemWSService">
      <jaxws:serviceBean>
          <bean class="cn.itcast.ecps.ws.service.impl.EbItemWSServiceImpl"></bean>
      </jaxws:serviceBean>
      <!-- 輸入輸出的攔截器 -->
      <jaxws:inInterceptors>
          <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean>
      </jaxws:inInterceptors>
      <jaxws:outInterceptors>
          <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean>
      </jaxws:outInterceptors>
   </jaxws:server>
</beans>

5.  修改cxf-servlet.xml的位置,在spring的listener中載入

<listener>
   <listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<context-param>
   <param-name>contextConfigLocation</param-name>
   <param-value>classpath*:beans.xml,classpath*:cxf-servlet.xml
</param-value>
</context-param> 

6.  啟動伺服器釋出webservice的服務,使用wsdl2java生成客戶端的程式碼

Wsdl2java –d . –p cn.itcast.ecps.ws.stub http://.........wsdl?

7.  在客戶端呼叫。

④訂單管理模組

1) 流程設計

2) 訂單整合activiti工作流

1.activiti流程和spring整合

建立activiti-context.xml檔案

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
   <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
       <!-- 資料來源 -->
      <property name="dataSource" ref="dataSource" />
      <!-- 配置事務管理器,統一事務 -->
      <property name="transactionManager" ref="txManager" />
      <!-- 設定建表策略 -->
      <property name="databaseSchemaUpdate" value="true" />
   </bean>
 
   <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
      <property name="processEngineConfiguration" ref="processEngineConfiguration" />
   </bean>
   
   <bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService" />
   <bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService" />
   <bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" />
   <bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" /> 
</beans>

1.  畫流程圖

2.  建立流程服務類

package cn.itcast.service.impl;
import java.io.File;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.DeploymentBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.itcast.service.IWorkFlowService;
 
//@Service
public class WorkflowServiceImpl implements IWorkFlowService {
 
   @Autowired
   RepositoryService repositoryService;  
 
   /*public RepositoryService getRepositoryService() {
      return repositoryService;
   }
 
   public void setRepositoryService(RepositoryService repositoryService) {
      this.repositoryService = repositoryService;
   }*/
 
   public void deployFlow() {
      //建立釋出流程配置物件
      DeploymentBuilder builder = repositoryService.createDeployment();
      //指定流程資源路徑
      builder.addClasspathResource("activit-orderflow.bpmn")
      .addClasspathResource("activit-orderflow.png");
      
      builder.deploy();
   }
}

1.  部署流程

2.  查詢業務任務

3.  辦理任務

6.專案中哪些功能模組涉及了大資料量訪問,怎麼解決

系統前臺是網際網路上的使用者訪問的,會有大量使用者來訪問。

假定有1w個人開啟你的網站來訂商品,問你如何解決併發問題(可擴充套件到任何高併發網站要考慮的併發讀寫問題)

 問題,1w個人來訪問,商品沒出去前要保證大家都能看到有商品,不可能一個人在看到商品的時候別人就不能看了。到底誰能搶到,那得看這個人的運氣(網路快慢等)

 其次考慮的問題,併發,1w個人同時點選購買,到底誰能成交?總共只有一張商品。

Update eb_sku t sett.stock = t.stock – 1 where t.sku_id = #{skuId} and t.stock > 0

Update eb_sku t set t.sale = t.sale +1 where t.sku_id = #{skuId} 

 首先我們容易想到和併發相關的幾個方案 : 鎖 同步

 同步更多指的是應用程式的層面,多個執行緒進來,只能一個一個的訪問,java中指的是syncrinized關鍵字。鎖也有2個層面,一個是java中談到的物件鎖,用於執行緒同步;另外一個層面是資料庫的鎖;如果是分散式的系統,顯然只能利用資料庫端的鎖來實現。

假定我們採用了同步機制或者資料庫物理鎖機制,如何保證1w個人還能同時看到有商品,顯然會犧牲效能,在高併發網站中是不可取的。使用hibernate後我們提出了另外一個概念:樂觀鎖(一定要用)悲觀鎖(即傳統的物理鎖);採用樂觀鎖即可解決此問題。樂觀鎖意思是不鎖定表的情況下,利用業務的控制來解決併發問題,這樣即保證資料的併發可讀性又保證儲存資料的排他性,保證效能的同時解決了併發帶來的髒資料問題。

 hibernate中如何實現樂觀鎖:

 前提:在現有表當中增加一個冗餘欄位,version版本號, long型別
 原理:

1)只有當前版本號》=資料庫表版本號,才能提交
 2)提交成功後,版本號version ++

 實現很簡單:在ormapping增加一屬性-lock="version"