软通动力月薪8K面试题解析
移动用户资费统计系统
===========================================================
PS: 这是朋友去面试的时候面到的题,做不出来了,让我帮帮忙,现在拿出来和大家一起分享一下
模拟实现简易的移动用户资费统计系统逻辑,具体需求如下:
- 移动运营商A设置两种类型的用户:普通用户及VIP用户,现该运营商已有5个VIP用户和15个普通用
- 户,共计20个用户。
- 普通用户资费标准如下(不考虑漫游和长途):
【基准资费】
无月租费用。
通话费:0.6元 / 分钟(仅拨打收费,接听免费)
短信费:0.1元 / 条
数据费:5元/ M
【优惠套餐】
话费套餐 :月功能费 20元,最多可拨打60分钟电话,超出时间按照
0.5元 / 分钟计费。
短信套餐 :月功能费10元,最多可发送200条短信,超出条数按照
0.1元 / 条计费。
数据套餐 :月功能费20元,最多可获50M的流量,超出流量按照
3元 / M 计费。
注:用户可以选择多种套餐,各功能(通话、短信、数据)计费时,如已选择对应套餐,则按套餐
标准计费;如未选择对应套餐,则按对应的基准资费计费。
- VIP用户资费标准如下(不考虑漫游和长途):
【基准资费】
月租费用:按天收取,2元 / 天
通话费:0.4元 / 分钟(仅拨打收费,接听免费)
短信费:0.1元 / 条
数据费:3元/ M
【优惠套餐】
套餐1 :月基本费用 100元(无月租费用),提供如下服务:
① 最多可拨打750分钟电话,超出部分按照0.3元 / 分钟计费。
② 最多可发送200条短信,超出条数按照0.1元 / 条计费。
③ 最多可获得100M数据流量,超出流量按照1元 / M计费。
套餐2 :月基本费用 200元(无月租费用),提供如下服务:
① 最多可拨打2000分钟电话,超出部分按照0.2元 / 分钟计费。
② 最多可发送500条短信,超出条数按照0.1元 / 条计费。
③ 最多可获得300M数据流量,超出流量按照0.5元 / M计费。
注:用户最多只能选择一种套餐,如未选择任何套餐,则按照基准资费计费。
- 各类型用户只能选择提供给本类型用户的套餐。
- 新用户入网。
① 对于新入网的普通用户,入网当月赠送如下服务:免费拨打60分钟
电话,免费发送200条短信,免费获得50M流量。超出赠送的部分
按照普通用户基准资费进行计费。
② 对于新入网的VIP用户,入网当月赠送如下服务:免费拨打200分
钟电话,免费发送200条短信,免费获得100M数据流量。超出赠送
的部分按照VIP用户基准资费进行计费(注意:需按入网天数计算月
租费用)。
- 每月为用户计算一次账单,用户订制的套餐信息和账单信息采用文件方式进行存储
- (提示:可使用java中的Properties API进行文件操作)。
- 用户可自由订制或退订所属用户类型的套餐,并从下月起生效。
- 异步随机生成客户操作如下:
① 拨打电话,每次拨打时长为1至10分钟不等(随机决定,以分钟为
单位)。
② 发送短信,每次发送条数为1至10条不等(随机决定)。
③ 上网获取数据,每次获取数据流量可为50K,100K,200K,
500K,1M(随机决定)。
④ 订制或退订相应套餐。
⑤ 新用户入网(随机决定用户类型)。
注:随机生成客户操作时间间隔自定,可设置。
- 不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。
=============================================================================================
这个题冒似很麻烦,其实想想无非就是用户来了给他安上服务,然后再对照用户类型收一收钱就OK了,我们用到了几个类 先看用户类
User.java
1 package user;
2
3 import java.util.Vector;
4
5 import javax.naming.ConfigurationException;
6
7 import config.Config;
8 import billing.Billing;
9 import time.Timer;
10
11 public class User {
12
13 private int accessUsersMonth;
14
15 private int phoneCallTime = 0;
16 private int msgValue = 0;
17 private int onLineStreamValue = 0;
18
19 private int needToPayphoneCallTime = 0;
20 private int needToPaymsgValue;
21 private int needToPayonLineStreamValue;
22
23 private Vector<Integer> types = new Vector<Integer>();
24
25 private int userType;
26 private int userService;
27 private boolean userIsNew = true;
28 private int userName;
29 private int needToPayMoney;
30 private int onlineDay ;
31 public User(int i, int type) {
32 this.userName = i;
33 this.userType = type;
34 this.accessUsersMonth = Timer.getInstance().getMonth();
35 onlineDay = Timer.getInstance().getDay();
36 System.out.println(toString() + getToday()+" 入网");
37 }
38
39 public static void main(String[] args) {
40 User user = new User(110, Config.commonUser_NewUser);
41 user.callPhone(200);
42 user.sendMsg(200);
43 user.accessNet(200000);
44
45
46 //
47 //
48 user.addService(Config.commonUser_moreCall);
49 user.addService(Config.commonUser_moreMsg);
50 user.addService(Config.commonUser_moreOnlineStream);
51 user.payment();
52 user.callPhone(60);
53 user.sendMsg(200);
54 user.accessNet(50000);
55 System.out.println(user.toString());
56 user.payment();
57 System.out.println(user.toString());
58 // user.callPhone(10);
59 // System.out.println(user.payment());
60 }
61
62 private void typeActive() {
63 if(this.userType==Config.VIP_NewUser) {
64 this.userType = Config.VipUser_commonServe;
65 }else{
66 this.userType = 0;
67 }
68 int typeSum = 0;
69 for (int i = 0; i < types.size(); i++) {
70 typeSum = typeSum+types.get(i);
71 this.userType = typeSum;
72 }
73 // 设置老用户信息
74 if(this.userType==Config.VIP_NewUser) {
75 this.userType = Config.VipUser_commonServe;
76 }
77 System.out.println("激活用户" + toString() + "状态号:"+userType);
78 setUserIsNew(false);
79
80 }
81
82 public int payment() {
83
84 needToPayMoney = Billing.getBilling(this);
85 int payMoney = needToPayMoney;
86 System.out.println(toString()+"缴费"+needToPayMoney+"分"+"当前时间:"+getToday());
87 typeActive();
88
89 setMsgValue(0);
90 setPhoneCallTime(0);
91 setOnLineStreamValue(0);
92
93
94 return payMoney;
95 }
96
97 public void accessNet(int i) {
98 // TODO Auto-generated method stub
99 onLineStreamValue = onLineStreamValue + i;
100 System.out.println(toString() + "上了" + i + "K的网");
101 }
102
103 public void sendMsg(int i) {
104 msgValue = msgValue + i;
105 System.out.println(toString() +getToday()+ "发了" + i + "条短信");
106 }
107
108 private String getToday() {
109 String today = Timer.getInstance().getMonth()+"月"+Timer.getInstance().getDay()+"日 ";
110 return today;
111 }
112
113 public void sendMsg() {
114 // TODO Auto-generated method stub
115 msgValue++;
116 System.out.println(toString() + "发了一条短信");
117 }
118
119 public String toString() {
120 String name = "老用户";
121 if (checkUserIsNew()) {
122 name = "新用户";
123 }
124 name = name + " " + userName;
125
126 name = name+Config.getType(getUserType());
127 name = name +"(入网时间"+getAccessUsersMonth()+"月"+getOnlineDayValue()+"日 )";
128 return name;
129 }
130
131 public int getPhoneCallTime() {
132 System.out.println(toString() + "一共打了" + phoneCallTime + "分钟电话");
133 return phoneCallTime;
134 }
135
136 public void setPhoneCallTime(int phoneCallTime) {
137 this.phoneCallTime = phoneCallTime;
138 }
139
140 public int getMsgValue() {
141 System.out.println(toString() + "一共发了" + msgValue + "条短信");
142 return msgValue;
143 }
144
145 public void setMsgValue(int msgValue) {
146 this.msgValue = msgValue;
147 }
148
149 public int getOnLineStreamValue() {
150 System.out.println(toString() + "一共上了" + onLineStreamValue + "K的网");
151 return onLineStreamValue;
152 }
153
154 public int getUserType() {
155 return userType;
156 }
157
158 public void addService(int userType) {
159 // 避免添加重复的
160 if (types.contains(userType)) {
161 System.out.println("不要添加重复状态: " + userType);
162 return;
163 }
164 // 如果要添加为新用户状态
165
166 if (userType == Config.commonUser_NewUser
167 || userType == Config.VIP_NewUser) {
168 System.out.println("当前用户不能添加为新用户状态");
169 return;
170 }
171 // 普通用户
172 if (checkUserIsCommenUser() && userType < Config.VIP_NewUser) {
173 types.add(userType);
174 System.out.println(toString()+"添加服务:"+Config.getType(userType));
175 return;
176 }
177 // VIP用户
178 if (!checkUserIsCommenUser() && userType > Config.VIP_NewUser) {
179 types.removeAllElements();
180 types.add(userType);
181 System.out.println(toString()+"添加服务:"+Config.getType(userType));
182 return;
183 }
184 }
185
186 public int getUserService() {
187 return userService;
188 }
189
190 public void setUserService(int userService) {
191 this.userService = userService;
192 }
193
194 public boolean checkUserIsNew() {
195
196 return userIsNew;
197 }
198
199 public void setUserIsNew(boolean userIsNew) {
200 this.userIsNew = userIsNew;
201 }
202
203 public void callPhone(int time) {
204 phoneCallTime = phoneCallTime + time;
205 System.out.println(toString() + "打了" + time + "分钟电话");
206 }
207
208 public int getAccessUsersMonth() {
209 return accessUsersMonth;
210 }
211
212 public void setAccessUsersMonth(int accessUsersMonth) {
213 this.accessUsersMonth = accessUsersMonth;
214 }
215
216 public boolean checkUserIsCommenUser() {
217 if (getUserType() < Config.VIP_NewUser) {
218 // System.out.println("当前用户为普通用户");
219 return true;
220 } else {
221 // System.out.println("当前用户为VIP用户");
222 return false;
223 }
224
225 }
226
227 public int getOnlineDayValue() {
228 return onlineDay;
229 }
230
231 public void setOnLineStreamValue(int onLineStreamValue) {
232 this.onLineStreamValue = onLineStreamValue;
233 }
234
235 }
236
Timer.java类控制时间erated catch block
1 package time;
2 public class Timer implements Runnable{
3 private static Timer timer = new Timer();
4 private int month = 1;
5 private int day = 1 ;
6
7 private Timer() {
8 new Thread(this).start();
9 }
10
11 public int getMonth() {
12 return month;
13 }
14 public void setMonth(int month) {
15 this.month = month;
16 }
17 public static Timer getInstance() {
18 return timer;
19 }
20 public static void main(String[] args) {
21 // TODO Auto-generated method stub
22 }
23 public int getDay() {
24 // TODO Auto-generated method stub
25 return day;
26 }
27 @Override
28 public void run() {
29 for(int i=1; i<10;i++)
30 {
31
32 month = i;
33
34 for(int j=1;j<=30;j++)
35 {
36 day = j;
37 try {
38 Thread.sleep(100);
39 } catch (InterruptedException e) {
40 // TODO Auto-generated catch block
41 e.printStackTrace();
42 }
43 }
44 }
45 System.out.println("Time is over");
46 System.exit(-1);
47 }
48 }
Billing.java类负责付款模块
1 package billing;
2 import config.Config;
3 import user.User;
4 public class Billing {
5 /**
6 * @param args
7 */
8 public static int getBilling(User user) {
9 int needToPay = 0;
10 int payMsgValue = user.getMsgValue();
11 int payCallTime = user.getPhoneCallTime();
12 int payOnlineStream = user.getOnLineStreamValue();
13
14 BillType[] allBillType = BillType.values();
15
16 for(BillType bt:allBillType) {
17 if(user.getUserType()==bt.getType()) {
18
19 payMsgValue = payMsgValue - bt.getFreeMsg();
20 payCallTime = payCallTime - bt.getFreeCall();
21 payOnlineStream = payOnlineStream - bt.getFreeOnline();
22
23 System.out.println(user.toString()+"freeCall "+bt.getFreeCall()+"--------needToPay"+payCallTime);
24 System.out.println(user.toString()+"freemsg "+bt.getFreeMsg()+"=========needToPay"+payMsgValue);
25 System.out.println(user.toString()+"freeonline "+bt.getFreeOnline()+"----------needTOpayOnline"+payOnlineStream);
26 if(payMsgValue>0){
27 needToPay = needToPay+ payMsgValue*bt.getMsgPrice();
28 // System.out.println("1"+needToPay);
29 }
30 if(payCallTime>0)
31 {
32 needToPay = needToPay+payCallTime*bt.getCallPrice();
33 // System.out.println(needToPay);
34 }
35
36 if(payOnlineStream>0)
37 {
38 needToPay = (int) (needToPay+(payOnlineStream)*bt.getOnlinePrice());
39 // System.out.println(needToPay);
40 }
41 needToPay = needToPay + bt.getDayMoney()*(31-user.getOnlineDayValue())
42 + bt.getMonthMoney();
43
44 // System.out.println(needToPay);
45 break;
46 }
47 }
48
49 return needToPay;
50 }
51 }
config类
1 package config;
2 import billing.BillType;
3 public class Config {
4 public static final int commonUser_NewUser = -1;
5 public static final int commonUser_commonServe = 0;
6
7 public static final int commonUser_moreCall = 2;
8
9 public static final int commonUser_moreMsg = 4;
10
11 public static final int commonUser_moreOnlineStream = 8;
12
13 public static final int VIP_NewUser = 16;
14
15 public static final int VipUser_commonServe =32;
16
17 public static final int VipUser_100Serve = 64;
18 public static final int VipUser_200Serve = 128;
19 public static final String getType(int i) {
20 String name = "无此服务类型";
21
22 if(i==Config.commonUser_NewUser) {
23 name = "(状态:普通新用户)";
24 }
25 if (i == Config.commonUser_commonServe) {
26 name = "(状态:普通用户)";
27 }
28 if (i == Config.commonUser_moreCall) {
29 name = "(状态:普通 电话优惠 用户)";
30 }
31 if (i == Config.commonUser_moreMsg) {
32 name = "(状态:普通 短信优惠 用户)";
33 }
34 if (i == Config.commonUser_moreOnlineStream) {
35 name = "(状态:普通 流量优惠 用户)";
36 }
37 if (i == Config.VipUser_commonServe) {
38 name = "(状态:VIP 普通用户)";
39 }
40 if (i == Config.VIP_NewUser) {
41 name = "(状态:VIP 普通新用户)";
42 }
43 if (i == Config.VipUser_100Serve) {
44 name = "(状态:VIP 100元 套餐用户)";
45 }
46 if (i == Config.VipUser_200Serve) {
47 name = "(状态:VIP 200元 套餐用户)";
48 }
49 if (i == Config.commonUser_moreCall
50 + Config.commonUser_moreMsg) {
51 name = "(状态:普通 电话与短信优惠 用户)";
52 }
53 if (i == Config.commonUser_moreCall
54 + Config.commonUser_moreOnlineStream) {
55 name = "(状态:普通 电话与流量优惠 用户)";
56 }
57 if (i == Config.commonUser_moreMsg
58 + Config.commonUser_moreOnlineStream) {
59 name = "(状态:普通 短信与流量优惠 用户)";
60 }
61 if (i == Config.commonUser_moreCall
62 + Config.commonUser_moreMsg
63 + Config.commonUser_moreOnlineStream) {
64 name = "(状态:普通 电话短信流量全开优惠 用户)";
65 }
66 return name;
67
68
69
70 }
71
72
73
74
75
76 }
主控制类
1 package test;
2 import java.util.Vector;
3 import billing.BillType;
4 import config.Config;
5 import time.Timer;
6 import user.User;
7 public class MobileCounter {
8 private Vector<User> users = new Vector<User>();
9 private int count = 1;
10
11 public static void main(String[] args) {
12 MobileCounter mc = new MobileCounter();
13 while (true) {
14 try {
15 Thread.sleep(50);
16 } catch (InterruptedException e) {
17 // TODO Auto-generated catch block
18 e.printStackTrace();
19 }
20
21 if(Timer.getInstance().getDay()==30) {
22 Vector<User> users = (Vector<User>)mc.getUsers();
23 for(int i=0;i<users.size();i++) {
24 User user = users.get(i);
25 user.payment();
26 }
27 while(Timer.getInstance().getDay()==30) {
28 //什么也不做
29 }
30 }
31 if(mc.getUsers().size()==0) {
32 mc.newUserAccess();
33 }
34 mc.doSomething();
35
36
37 }
38 }
39 private void doSomething() {
40 int i = (int) (Math.random() * 5.1);
41 while(i>5) {
42 i = (int) (Math.random() * 5);
43 }
44 // 新用户入网
45 if (i == 5) {
46 newUserAccess();
47
48 }
49 // 用户打电话
50 if (i == 2) {
51 userCallPhone();
52 }
53 // 用户发短信
54 if (i == 3) {
55 userSendMsg();
56 }
57 // 用户上网
58 if (i == 1) {
59 userOnline();
60 }
61 // 用户开通业务
62 if (i == 4) {
63 userJoinService();
64 }
65 }
66 // 用户开通业务
67 private void userJoinService() {
68 // TODO Auto-generated method stub
69 int i = getRandom(getUsers().size());
70 User u = users.get(i);
71 u.addService(getRandom(BillType.listAllType()));
72 }
73 private int getRandom(int[] listAllType) {
74 int i = getRandom(listAllType.length);
75 return listAllType[i];
76 }
77 private int getRandom(int scope) {
78 int i = (int)(Math.random()*scope);
79 return i;
80
81 }
82 // 用户上网
83 private void userOnline() {
84 // TODO Auto-generated method stub
85 getRandomUser().accessNet(getRandom(new int[]{50,100,200,500,1000}));
86 }
87 // 用户发短信
88 private void userSendMsg() {
89 // TODO Auto-generated method stub
90 getRandomUser().sendMsg(getRandom(new int[]{1,2,3,4,5,6,7,8,9,10}));
91
92 }
93 // 用户打电话
94 private void userCallPhone() {
95
96 getRandomUser().callPhone(getRandom(new int[]{1,2,3,4,5,6,7,8,9,10}));
97
98 }
99 private User getRandomUser() {
100 // TODO Auto-generated method stub
101 return (User)(users.get(getRandom(users.size())));
102 }
103 // 新用户入网
104 private void newUserAccess() {
105 // TODO Auto-generated method stub
106 int i = (int)(Math.random()*2);
107 User user = null;
108 if(i==1) {
109 user = new User(count, Config.commonUser_NewUser);
110 }else{
111 user = new User(count, Config.VIP_NewUser);
112 }
113
114 users.add(user);
115 setCount(getCount()+1);
116 }
117 public Vector<User> getUsers() {
118 return users;
119 }
120 public void setUsers(Vector<User> users) {
121 this.users = users;
122 }
123 public int getCount() {
124 return count;
125 }
126 public void setCount(int count) {
127 this.count = count;
128 }
129 }
我们的思路就是主控制类控制着不停的生成新用户,我们记下所有的新用户以及老用户,让他们随机的打电话,发短信,上网,然后我们再根据用户的情况进行付款运算
就是这么简单,大家对这道题感兴趣的话可以仔细看一下我的的代码