網際網路公司2019年初年會Java程式設計師編寫抽獎代碼思維邏輯

2021-01-11 享學峰子

我有一個徒弟在一家公司做Java,

小組在做一個抽獎系統,現在給我分配到了抽獎邏輯這方面的實現。

EMMM,拿到分配的時候是懵B的。

老大給的需求圖

給的關鍵表結構DROP TABLE IF EXISTS `dd_annual_meeting_check`;CREATE TABLE `dd_annual_meeting_check` ( `check_id` int(255) NOT NULL AUTO_INCREMENT COMMENT '主鍵', `check_prize_id` varchar(255) NOT NULL COMMENT '抽獎Id', `emp_id` int(10) NOT NULL COMMENT '中獎員工id', `emp_prize_time` varchar(255) NOT NULL COMMENT '中獎時間', `check_receive` varchar(100) NOT NULL COMMENT '核銷 0-已經核銷 1-未核銷', `check_user_id` int(10) DEFAULT NULL COMMENT '核銷工作人員(對於員工id)', `check_time` varchar(255) DEFAULT NULL COMMENT '核銷時間', PRIMARY KEY (`check_id`)) ENGINE=InnoDB AUTO_INCREMENT=158 DEFAULT CHARSET=utf8 COMMENT='中獎池信息表';DROP TABLE IF EXISTS `dd_annual_meeting_prize`;CREATE TABLE `dd_annual_meeting_prize` ( `prize_id` varchar(255) NOT NULL COMMENT '主鍵', `prize_name` varchar(100) NOT NULL COMMENT '抽獎名稱', `prize_num` varchar(100) NOT NULL COMMENT '抽獎總人數', `prize_count` varchar(100) NOT NULL COMMENT '每次中獎人數', `prize_range` varchar(100) DEFAULT NULL COMMENT '抽獎範圍: 0-all 1-未中獎', `prize_state` varchar(100) DEFAULT NULL COMMENT '狀態: 0-待抽 1-抽中 2-已抽', `prize_date` varchar(255) DEFAULT NULL COMMENT '狀態時間', `leader_id` int(10) NOT NULL COMMENT '抽獎領導Id', `giver_id` int(10) DEFAULT NULL COMMENT '加獎人Id', `prize_detial` varchar(100) NOT NULL COMMENT '抽獎詳情', `giver_state` varchar(255) DEFAULT '0' COMMENT '是否加獎 0-否 1-是', PRIMARY KEY (`prize_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='抽獎池信息表';DROP TABLE IF EXISTS `dd_annual_meeting_user`;CREATE TABLE `dd_annual_meeting_user` ( `u_id` int(10) NOT NULL AUTO_INCREMENT, `user_id` varchar(100) NOT NULL COMMENT '員工工號', `user_name` varchar(100) NOT NULL COMMENT '員工姓名', `user_time` varchar(255) DEFAULT NULL COMMENT '掃碼時間', `user_type` varchar(100) DEFAULT NULL COMMENT '身份: 0-普通員工 1-領導 2-工作人員', `user_state` varchar(100) DEFAULT NULL COMMENT '狀態: 1-已領取0-未領取', `state_date` varchar(255) DEFAULT NULL COMMENT '狀態時間', `user_prize` varchar(255) NOT NULL COMMENT '獎票號', PRIMARY KEY (`u_id`)) ENGINE=InnoDB AUTO_INCREMENT=3423 DEFAULT CHARSET=utf8 COMMENT='人員信息表';追加:

-- ---

-- Table structure for dd_annual_meeting_record

-- ---

DROP TABLE IF EXISTS `dd_annual_meeting_record`;

CREATE TABLE `dd_annual_meeting_record` (

`record_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵',

`record_prize_id` int(10) NOT NULL COMMENT '抽獎id',

`record_times` int(10) NOT NULL COMMENT '第幾輪',

`record_over` int(10) NOT NULL COMMENT '剩餘次數',

`record_count` int(10) NOT NULL COMMENT '每次中獎數',

`record_state` varchar(100) NOT NULL COMMENT '進行狀態 0-未開始 1-已結束',

PRIMARY KEY (`record_id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ---

-- Records of dd_annual_meeting_record

-- ---

沒有多餘講解,就一句話,「需求是這樣,怎樣實現我不管。」這是老大的座右銘。

可我特麼的是新手啊,難受啊,馬飛!

好吧,其實是說業務流程和其他表結構並沒有最終確定,先做個大概的抽獎邏輯出來,咱就按照表結構和自己的意思做一把思想上的巨人。

先從第一個開始(一二三等獎不能重複獲得)

分析下表結構:

一共三張表,中獎池信息表dd_annual_meeting_check,這個比較容易理解,就是將得到的中獎人的id和獎 項id插入這張表。抽獎池信息表dd_annual_meeting_prize,這張表看來是獲取抽獎信息的來源。人員信息表dd_annual_meeting_user,這個就是用來得到抽獎人集合的表了。

分析下抽獎的過程:

抽獎池信息表裡面信息已經定好了不用我管 ,假設人員信息表有100個人參與活動。

第一次抽獎(一等獎) 從100人中抽5個人來中獎,但是要分5次抽完,每次抽1人。第二次抽獎(二等獎)從95人(中了一次獎的人,不參與抽獎)中抽10個人來中獎,每次抽5人出來,要抽2次。第三次抽獎(二等獎)從85人(中了一次獎的人,不參與抽獎)中抽5個人來中獎,每次抽1人,抽5次。來個圖:

思路圖實現邏輯大致思路:

1.從人員信息表獲得所有參與人員的數量

2.根據頁面數據判斷抽的什麼獎勵

3.從抽獎池信息表中獲得抽獎主鍵id(prize_id),抽獎總人數(prize_num),每次中獎人數(prize_count),抽獎人領導id(leader_id)

4.進行抽獎,從人數中抽出對應的數字,根據數字去人員表中得到對應的人員信息

5.將中獎人信息與獎項信息綁定,添加到中獎池信息表

簡單的分析後,有了大致思路,細節什麼的就在代碼中完成:

一,先弄兩個頁面出來,一個是顯示中獎信息的頁面,另外一個是發送抽獎指令的頁面(因為是領導來點擊抽獎,所以有一個領導信息需要發送過來)。

<html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"/> <title>抽獎頁面</title> <script src="http://how2j.cn/study/jquery.min.js"></script> </head> <body> <div> <div id="showData" name="showData"> <p>獎品列表!!!!!!!!!!!!</p> </div> <input type="hidden" name="poe" id="poe" /></div> <script type="text/javascript">var psel = document.getElementById("poe"); window.onload=function (){ websocket = new WebSocket("ws://127.0.0.1:8080/websocket"); websocket.onmessage = function(msg) { console.log(msg.data); $.ajax({ url:"test2", type:"POST", data:{ msg:msg.data, peo:psel.value }, dataType : "json", success : function (rtn) { console.log("Successfully"); console.log(rtn); if(rtn.list != null){ var inf = '<table class=table>'; inf += "<tr><th>獲獎人id</th><th>獲獎人姓名</th><th>獲獎人獎券號</th></tr>" /*<![CDATA[*/ for(var i=0; i<rtn.list.length;i++){ /*]]>*/ var stu = rtn.list[i]; inf += "<tr><td>"+stu.user_id+"</td><td>"+stu.user_name+"</td><td>"+stu.user_prize+"</td></tr>" } inf += "</table>" $("#showData").html(inf); } if(rtn.poe != null){ psel.value = rtn.poe; } } }); } }</script> </body> </html>//發送消息測試頁面<html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"/> <title>發送消息測試頁面</title> <script th:src="@{js/sockjs.min.js}"></script> <script th:src="@{js/stomp.min.js}"></script> <script src="http://how2j.cn/study/jquery.min.js"th:src="@{js/jquery/2.0.0/jquery.min.js}"></script> </head> <body> <noscript><h2 style="color: #e80b0a;">Sorry,瀏覽器不支持WebSocket</h2></noscript> <div> <div> <button id="disconnect" onclick="send()" onclike="send()">發送</button> <input id="text" type="text"/> </div> </div> <script type="text/javascript"> var websocket=null; window.onload=function (){ if ('WebSocket' in window) { console.log("1"); websocket = new WebSocket("ws://127.0.0.1:8080/websocket"); } else if ('MozWebSocket' in window) { console.log("2"); websocket = new MozWebSocket("ws://127.0.0.1:8080/websocket"); } else { websocket = new SockJS("ws://127.0.0.1:8080/websocket"); } //websocket = new WebSocket("ws://127.0.0.1:8080/websocket"); websocket.onmessage = function(msg) { console.log(msg.data); } } function send() { var message = document.getElementById('text').value; console.log(message); websocket.send(message); }</script> </body> </html>這是之前寫的用websocket來實時傳值的兩個頁面,稍微改了改。

二,寫Controller層代碼

先把兩個頁面的請求寫出來

@Controller@RequestMapping("/hello")public class WsController { //測試頁面 @RequestMapping("/test1") public String test() throws IOException{ return "showlist"; } //消息發送頁面 @RequestMapping("/test3") public String test2() throws IOException{ return "ws2"; } 剩下的就是抽獎邏輯代碼 和資料庫腳本代碼了,細節如何構思的就不說了,腦殼疼,一邊想著怎麼做,然後老大那邊又說這個流程這麼走,不不不,那麼走,嗯嗯嗯,還是這麼走。

//抽獎測試 @Autowired private TestDao testDao; @ResponseBody @RequestMapping("/test2") public Map test(@RequestParam("msg") String msg,@RequestParam("peo") List<Integer> peo) throws IOException { String prize_name = "第一輪抽獎"; //收到頁面傳來數據msg(抽獎人id),prize_name(抽取的獎項)獲得抽獎信息 Map<String,String> priz_info = testDao.findPrizinfo(msg,prize_name); //定義一個最終傳回值的集合 Map m1 = new HashMap(); if(priz_info != null) { //判斷peo數據如果沒人數數據 添加數據 if(peo.isEmpty()) { //n為人員總數 int n = testDao.findAll(); for(int i = 0; i < n;i++) { peo.add(i); } } System.out.println("當前抽獎總人數為:"+peo); //定義一個最終獲獎人id的集合 ArrayList<Integer> dIdList = new ArrayList<Integer>(); //定義一個獲取抽獎結果的集合 Map m2 = new HashMap(); //得到抽獎次數 int count = Integer.parseInt(priz_info.get("prize_num")) / Integer.parseInt(priz_info.get("prize_count")) ; for(int i = 0; i < count;i++) { //進行抽獎並獲得結果集 m2 = luck(peo,Integer.parseInt( priz_info.get("prize_count"))); //得到中獎人id集合 dIdList.addAll((List)m2.get("eidList")); //得到剩餘人數 peo = (List<Integer>) m2.get("idList"); //將每一次抽獎的狀態改變 testDao.update(priz_info.get("prize_id"), i+1); } System.out.println("獲獎id:"+dIdList); System.out.println("最後人數:"+peo); //循環獲得LIST<USER> 中獎人信息 ArrayList<User> infoList = new ArrayList<User>(); for(int i = 0;i < dIdList.size();i++) { infoList.add(testDao.findById(dIdList.get(i))); } //為返回值傳入參數 //獲獎信息 m1.put("list", infoList); //未中獎人 m1.put("poe", peo); } return m1;} //抽獎 傳參 1.總人數 3,幾人中獎 Map luck(List<Integer> idList,int n) { //取得中獎人id ArrayList<Integer> a = makeRandom(0,idList.size(), n); System.out.println("中獎的數字為"+a); //獲獎id臨時存儲集合 ArrayList<Integer> eidList = new ArrayList<Integer>(); //排序 Object[] b = a.toArray(); Arrays.sort(b); //定義一個中獎人數據集合 List t = new ArrayList(); for(int i = 0; i < b.length;i++) { eidList.add(idList.get((int) b[i])); System.out.println("中獎的id為"+idList.get((int) b[i])); t.add(idList.get((int) b[i])); } //總人數中移除中獎人數據 idList.removeAll(t); //寫到Map集合回傳 Map m = new HashMap(); //剩餘id m.put("idList", idList); //獲獎id m.put("eidList", eidList); return m; } //從x-y 取num個隨機數 ArrayList<Integer> makeRandom(int x, int y, int num) { //創建一個integer的動態數組 ArrayList<Integer> a = new ArrayList<Integer>(); int index = 0; //往數組裡面逐一加取到不重複的元素 while(index < num) { //產生x-y的隨機數 Random r = new Random(); int temp = r.nextInt(y-x)+x ; //設置是否重複的標記變量為false boolean flag = false; for(int i =0; i<index;i++) { if(temp == a.get(i)) { flag = true; break; } } if(flag==false) { a.add(temp); index++; } } return a; }}Dao

@Mapperpublic interface TestDao { //查詢抽獎人數 @Select("select count(*) from dd_annual_meeting_user where user_state = 1") int findAll(); //查詢中獎人信息 @Select("select * from dd_annual_meeting_user where user_state = 1 limit ${id},1") User findById(@Param("id") int id); //修改中獎人與獎池練聯繫(暫時不寫) @Insert("INSERT INTO dd_annual_meeting_check VALUES ( #{check_prize_id}, #{emp_id},curdate(),'1')") void inset(@Param("check_prize_id") String check_prize_id,@Param("emp_id") int emp_id); //獲取抽獎信息 @Select("select prize_id,prize_num,prize_count from dd_annual_meeting_prize where leader_id=#{msg} and prize_name=#{prize_name} and prize_state=0") Map findPrizinfo(@Param("msg") String msg, @Param("prize_name") String prize_name); //更改抽獎狀態 @Update("update dd_annual_meeting_record set record_state=1 where record_prize_id = #{prize_id} and record_times = #{record_times}") void update(@Param("prize_id") Object prize_id, @Param("record_times") int record_times);}現在來測試效果:

點擊前

這邊自己在資料庫中添加了數據,傳1後會進行抽獎

第一次點擊

第二次點擊

點了兩次 共抽了10人出來,並沒有重複。

講真,全程靠著表結構自己想邏輯,真的皮,有些欄位都不確定是來幹什麼的,去問同組做這個的人,她說她不清楚,我服了,然後知道了個大概的流程,把這個簡單的邏輯弄完給她看了看,她說差不多了,好吧,我不管了,後面都做完了我再修改細節。現在可以摸魚了,摸個兩三天再交差。

最後,我這邊整理了一套Java架構進階的技術知識體系,方便大家系統學習

以上視頻資料是我結合自己和身邊朋友的面試經歷而整理的,希望對面試的朋友或者在找工作的程式設計師們有所幫助。大家對技術感興趣的朋友也可以來Java資源分享群:(805685193),資料會不定期更新。獲取Dubbo、Redis、設計模式、Netty、zookeeper、Spring cloud、分布式、高並發等架構技術視頻教程資料,架構思維導圖,和BATJ面試題及答案。

相關焦點

  • Java程式設計師必備基礎:Java代碼是怎麼運行的?
    前言 作為一名Java程式設計師,我們需要知道Java代碼是怎麼運行的。最近複習了深入理解Java虛擬機,做了一下總結,希望對大家有幫助,如果有不正確的地方,歡迎提出,感激不盡。
  • 程式設計師編程入門必知!程式設計師需要學什麼
    編程就是讓計算機為解決某個問題而使用某種程序設計語言編寫程序代碼,並最終得到結果的過程。資訊時代的大背景下,計算機的應用顯得舉足輕重,精通計算機的人才對於龐大的市場需求量來說還是顯得很匱乏,因此計算機行業的前景是很可觀的,但是也有不少人對於編程處於一竅不通的狀態,那編程該從何入手呢?
  • 盤點2019年各大公司年會~年終獎
    每到各大公司年會即成同事間,朋友間議論的話題,2019不同尋常,各項支出都在縮減,幾家歡喜幾家愁。還是先讓我們回顧一下之前的各種盛況吧。年終獎盤點年會這個事有些公司土豪演,有些公司奇葩演,有些噁心演,有些甚至都不演了例如美團和滴滴,他們的員工等到花兒都謝了也沒等來今年的年會。除了要上臺表演的倒黴蛋和要上臺講話的領導,所有員工都是衝著抽獎的環節來的。
  • 利用隨機數完成公司年會抽獎過程
    同樣請朋友們參考我的《VBA數組與字典解決方案》這套教程:2 利用隨機數完成公司年會抽獎過程很多公司都用年會抽獎的傳統,為了達到公平,公正的原則,我們也可以利用隨機數進行操作,做一個簡單的小程序即可以實現抽獎的過程。
  • 2020年3月全國程式設計師工資出爐,平均工資13820元,Java「錢」景看好!
    特別是當下的薪資變化趨勢,本文達妹為大家總結了2020年2月份中國程式設計師的薪資狀況,讓你入行前,心裡有數。2020年3月,中國大陸程式設計師平均工資13820元,比上個月增加。具體趨勢如圖:整體趨勢各主要程式設計師城市工資變化職能代碼:https://github.com/juwikuang/china_job_surveyIT行業持續火爆,各大計算機程式語言的前景,卻又各不相同。
  • (提高Java代碼質量)|25個優化Java代碼的小技巧
    應該使用 Collection.isEmpty() 檢測空使用 Collection.size() 來檢測空邏輯上沒有問題,但是使用 Collection.isEmpty() 使得代碼更易讀,並且可以獲得更好的性能。
  • 網際網路公司都有哪些職位?程式設計師都做些什麼工作?
    大概是這兩年移動網際網路的興起,導致了很多2C端的APP產品出現,普通人接觸的最多的軟體或者程序就是裝在手機裡的APP了,和這些APP的相處時間甚至超過了戀人和愛人! 所以,在程式設計師身邊的朋友問他們,程式設計師這個職業到底是做什麼的時候,程式設計師們為了解釋方便就會拿開發APP來舉例。於是在很多人心中,就給程式設計師扣上了APP開發的帽子。
  • 世界排行第一的程式語言:java迎來25歲生日
    面向對象的Java以其「一次編寫,隨處運行」的可移植性而聞名,因為Java虛擬機支持多種硬體平臺和作業系統以及Java applet可以從網頁上運行。Java小程序多年來提供號稱優於JavaScript的性能,但後者最終受到瀏覽器製造商的青睞,並於 2018 年將Java從瀏覽器中刪除。
  • 中國第一代程式設計師裡的「四大天王」,30年前敲代碼,現狀如何?
    網際網路來中國的時間不長,平時接觸的程式設計師敲代碼超過十年以上的也是少數,在為自己擔心的時候,不妨看一下中國的第一代程式設計師們的現狀,他們從1988年開始敲代碼,如今也已經有了三十年的經驗當時的他們名震世界,如今卻差距太大,有的人身價千億、有的人財務自由瀟灑過生活、有的人卻被掃地出門黯然離場。
  • Android被指抄襲Java代碼引爭議
    Mueller仔細檢查了Android的代碼,除了甲骨文在訴訟中提到的一個文件之外,他還發現了六個與Java文件非常相似的文件。這些文件是在Android 2.2版和2.3版中發現的。此外,Mueller指出,在Android的代碼中有三十七個文件包含一些提示,稱這個代碼是Sun專有的代碼。
  • 程式設計師最愛的8款代碼遊戲 邊玩遊戲邊擼代碼
    如果有這麼一款遊戲,能在放鬆的同時鞏固學到的代碼、學到新代碼,就再好不過了。W3Cschool精選8款熱門遊戲,趕緊來邊玩遊戲邊擼代碼吧!1.Hack Run、Hack Run Zero、Hack Time這是黑客入侵解謎遊戲系列遊戲,相信不少程式設計師並不陌生。在這個遊戲中,你將化身黑客,接受很多不一樣的任務,比如說你要入侵別人帳號,去破解密碼或者竊取信息。
  • 早在蓋茨或賈伯斯之前,有6位女性編寫了第一臺數字計算機
    但這篇文章,將還原真相,重述六位堅強獨立女性編寫第一臺計算機的故事。計算機的故事電子計算機,又稱電腦,這是一種利用數字電子技術,根據一系列指令指示其自動執行任意算術或邏輯操作序列的設備。而世界上第一臺通用計算機是電子數值積分計算機(英文:Electronic Numerical Integrator And Computer),簡稱為 ENIAC,中文又稱伊尼亞克。
  • 被嫌棄的35歲程式設計師
    在國內科技公司,大齡程式設計師想要一直做研發需要運氣和實力。公司得提供這樣的崗位,還要有足夠的開放度允許他們長期寫代碼。而 35+ 程式設計師也要證明自己寫的代碼對公司有利,年輕人還替代不了。另一方面,技術做久了,升到管理層,也是正常的職場晉升流程。
  • 跟我學java編程—Java邏輯運算符
    例如:假設一個數值取值範圍為0到100,設該數值為x,不等式0<x<100給出了x的取值範圍,在Java程序語言中,邏輯運算符可以實現類似數學中的不等式。下表列出了Java語言支持的邏輯運算符,表中假設布爾變量A為真,變量B為假。
  • Java 反射:框架設計的靈魂
    ,但是「正向」代碼在編譯前,就已經明確了要運行的類是什麼(ArrayList),而第二段代碼,只有在代碼運行時,才知道運行的類是 java.util.ArrayList。當然有聰明的程式設計師會想到設置一個開關配置,讓開關決定走哪段代碼邏輯,如果領導哪天想變成亞馬遜雲的服務,繼續寫 if-else 就好了:faceRecognition(Object faceImg){ if("AL".equals(configStr)){     }else if("TX".
  • 用經典案例來幫助初學者解析Java的「多態」
    我這裡還是用我13年前給我們公司新員工做內部培訓時用到的看起來似乎有點老掉牙的、但是仍然十分經典的案例來重新給有需要的java愛好者呈現一下「多態」的奧秘所在!形狀不同,當然求面積和求周長的方法內的實現邏輯也不同啦!若需要使用子類的或是實現類的構造方法為某屬性傳值,那麼構造方法要具備的,具體細節不是這篇文章主題要闡述的,就不多言。
  • 企業的1000種死法:程式設計師鎖死伺服器,網際網路公司如何應對?
    我們先回顧下一個事件:日前,深圳市螃蟹網絡科技有限公司創始人尹柏霖發文控訴,前員工燕某在遊戲上線測試當天(2017年12月15日),鎖死伺服器與電腦,並惡意失蹤,致公司損失慘重。尹柏霖稱,「我們上線不了也測試不了,等新員工到職後熟悉新代碼又是幾個月過去了。」他表示,時隔這麼久才曝光燕某是覺得項目敗了無所謂了,正準備走法律程序。
  • 【暢言】首先為人編寫程序,其次才是計算機
    當代碼排版工整時,我們很容易找出其條理和邏輯,會很快理解其到底要實現什麼功能;而排版不工整的時候,我們的眼睛會覺得很累,進而影響了我們的思維。命名規範 VS 命名不規範在看完排版之後,我們就會看到每個函數和變量的命名。由於一般項目的代碼行數都比較多,我們不可能花很多時間去理解每個函數和變量到底是何用意,到底是拿來做什麼的。
  • Java8 lambda表達式
    編寫第一個lambda表達式swing是一個平臺無關的gui庫,在該庫中,有很多常見的習慣,比如為了知道用戶點點擊了什麼,註冊一個事件監聽器,這個事件監聽器可以執行一些操作響應用戶的輸入。匿名內部類是為了讓java程式設計師傳遞行為和傳遞數據一樣容易,不幸的是,他們並不容易,為了調用處理邏輯的代碼仍然有四行模板代碼,重複的模板代碼並不是唯一的問題,這種代碼也難以閱讀,我們並不想傳遞一個對象,而僅僅只需要傳遞某種行為,在java8中我們可以寫得更簡潔不同於傳遞一個實現某個接口的對象,我們傳遞了一段沒有命名函數的代碼
  • 公司年會抽獎,兼職員工抽到2000元的手機,隔天大家
    導語:公司年會抽獎,兼職員工抽到2000元的手機,隔天讓大家愣了 現如今,馬上就要過年了,很多公司也是在紛紛舉行大大小小的年會來犒賞員工,在舉行年會的時候,相信很多員工都會發現公司會設置一些抽獎的環節,讓大家來抽獎,只是抽獎的時候,很多員工也會發現,公司在對待管理人員或者是普通員工的時候有所區別