이번 추석에도 시스템 장애가 없는 명절을 보내고 싶은 어피치는 서버를 증설해야 할지 고민이다. 장애 대비용 서버 증설 여부를 결정하기 위해 작년 추석 기간인 9월 15일 로그 데이터를 분석한 후 초당 최대 처리량을 계산해보기로 했다. 초당 최대 처리량은 요청의 응답 완료 여부에 관계없이 임의 시간부터 1초(=1,000밀리초)간 처리하는 요청의 최대 개수를 의미한다.
- 특정 시간에서 탐색할 때 시작점에서 +0.999초를 더한 곳 까지 비교한다.
- 비교하는 로그의 시작점과 끝점이 기준 시작점보다 앞서거나 끝점보다 뒤에 있으면 제외한다.
java를 연습하기 위해 예전에 풀어보던 문제들을 다시 풀어보고 있다. Python으로는 참 쉬웠는데 말이지...
특정 1초 구간에 가장 처리가 많았던 구간의 로그 양을 출력해주면 된다.
나는 이 문제를 String -> 스플릿 후 계산 -> String 이 형태로 복잡하게 풀긴했지만....
다른 사람들의 풀이를 확인해보니 그냥 년,월,일,시간,분 을 모두 초로 바꿔버리고 풀어도 된다.
사실 그렇게 푸는 게 더 간단할 것이다.
다만, 로그의 크기가 다 다르고 시작점도 시간 순서가 아니기 때문에
시간 효율성을 잡겠다고 중간에 break는 걸면 안 된다.
# python
import decimal
def solution(lines):
result = 0
time_line = []
for time in lines:
part = time.split()
part[1] = part[1].split(':')
part[2] = part[2][:-1]
right = ""
for i in part[1]:
right += i
right = float(right)
part[2] = float(part[2])
left = right - part[2]
if int(left)%100 > 90:
left -= 40
if int(left)%10000 > 9000:
left -= 4000
left = decimal.Decimal(str(left))+decimal.Decimal('0.001')
time_line.append([left,right])
for time in time_line:
left,right = time[1],decimal.Decimal(str(time[1]))+decimal.Decimal('0.999')
if int(right)%100 >= 60:
right -= 60
right += 100
if int(right)%10000 >= 6000:
right -= 6000
right += 10000
count = 0
for log in time_line:
if left <= log[0] <= right or left <= log[1] <= right or (log[0] <= left and right <= log[1]):
count += 1
if result < count:
result = count
return result
// java
import java.util.*;
import java.io.*;
class Solution {
public static String timeToString(int year,int month,int day,int hour,int min, double sec){
String start = ""+year+"-";
if(month < 10) start += "0"+month+"-"; else start += month+"-";
if(day < 10) start += "0"+day+" "; else start += day+" ";
if(hour < 10) start += "0"+hour+":"; else start += hour+":";
if(min < 10) start += "0"+min+":"; else start += min+":";
if(sec < 10) start += "0"+sec; else start += sec;
return start;
}
public static String startTime(String[] log){
String[] date = log[0].split("-");
int year=Integer.parseInt(date[0]),month=Integer.parseInt(date[1]),day=Integer.parseInt(date[2]);
String[] time = log[1].split(":");
int hour=Integer.parseInt(time[0]),min=Integer.parseInt(time[1]);
double sec=Double.parseDouble(time[2]);
String[] cost = log[2].split("s");
double csec=Double.parseDouble(cost[0]) - 0.001;
sec -= csec;
if(sec < 0){ sec += 60; min -= 1; }
if(min < 0){ min += 60; hour -= 1;}
if (hour < 0){ hour += 24; day -= 1;}
if(day < 0){
month -= 1;
if(month == 2) day += 28;
else if (month == 4 || month == 6 || month == 9 || month == 11) day += 30;
else day += 31;
}
if(month < 0){ month += 13; year -= 1;}
return timeToString(year,month,day,hour,min,sec);
}
public String oneSecond(String t){
String[] log = t.split(" ");
String[] date = log[0].split("-");
int year=Integer.parseInt(date[0]),month=Integer.parseInt(date[1]),day=Integer.parseInt(date[2]);
String[] time = log[1].split(":");
int hour=Integer.parseInt(time[0]),min=Integer.parseInt(time[1]);
double sec=Double.parseDouble(time[2]);
sec += 0.999;
if(sec > 60) {sec -= 60; min += 1; sec = Math.floor(sec * 1000) / 1000.0;}
if(min > 60) {min -= 60; hour += 1;}
if(hour > 24) {hour -= 24; day += 1;}
if(month == 2 && day > 28) {month += 1; day -= 28;}
else if((month == 4 || month == 6 || month == 9 || month == 11) && day > 30) {month += 1; day -= 30;}
else if(day > 31) {month += 1; day -= 31;}
if(month > 12) {month -= 12; year += 1;}
return timeToString(year,month,day,hour,min,sec);
}
public static boolean compare(String start,String end,String s,String e){
if(start.compareTo(s) > 0 && start.compareTo(e) > 0) return false;
else if(end.compareTo(s) < 0 && end.compareTo(e) < 0) return false;
else return true;
}
public int solution(String[] lines) {
String[] start = new String[lines.length];
String[] end = new String[lines.length];
int answer = 0;
for(int i=0;i<lines.length;i++){
String[] log = lines[i].split(" ");
start[i] = startTime(log);
end[i] = log[0]+" "+log[1];
}
for(int i=0;i<start.length;i++){
int cnt = 1;
for(int j=i+1;j<start.length;j++)
if(compare(start[i],oneSecond(start[i]),start[j],end[j])) cnt++;
answer = Math.max(answer,cnt);
cnt = 1;
for(int j=i+1;j<start.length;j++)
if(compare(end[i],oneSecond(end[i]),start[j],end[j])) cnt++;
answer = Math.max(answer,cnt);
}
return answer;
}
}
과거에 풀던 문제들을 다시 풀어보니 막막할 때가 있는 거 같다.
내가 부족했던 부분들을 한 번씩 확인해봐야겠다.
뭣보다 java가 python에 비해 속도가 정말 월등하게 빠르다는 것을 느낀다.