2022년 10월 25일
이번 추석에도 시스템 장애가 없는 명절을 보내고 싶은 어피치는 서버를 증설해야 할지 고민이다. 장애 대비용 서버 증설 여부를 결정하기 위해 작년 추석 기간인 9월 15일 로그 데이터를 분석한 후 초당 최대 처리량을 계산해보기로 했다. 초당 최대 처리량은 요청의 응답 완료 여부에 관계없이 임의 시간부터 1초(=1,000밀리초)간 처리하는 요청의 최대 개수를 의미한다.
임의의 한 구간을 선택해서 1s안에 몇 개의 타임라인이 지나가는지 구하는 문제이다.
임의라는게 가장 헷갈리는 부분인데, 단순하게 생각해보면 이미 종료시점에 맞춰서 데이터가 정렬되어서 내려온다.
즉, 데이터를 반복문 돌렸을 때 다음 데이터의 종료시점은 무조건 나보다 뒤에 있다. 그렇다면 시작 시간이 현재 데이터 구간 안에 다음 데이터가 포함되는 지를 확인하면 되고 그게 1s가 된다.
이게 설명을 하려니까 어려운데, 소스코드 내에서 설명하는 편이 편할 것 같다.
function solution(lines) {
let maxCount = 0;
const workingTime = lines.map((item) => {
const reg = item.match(/(\d{2})\:(\d{2})\:([\d\.]{6})\s(.*)s$/);
const endTime = (reg[1] * 3600 + reg[2] * 60 + parseFloat(reg[3])) * 1000;
const startTime = endTime - reg[4] * 1000 + 1;
return [startTime, endTime];
});
workingTime.forEach((item, index) => {
let count = 1;
const [_, endTime] = item;
for (let i = index + 1; i < workingTime.length; i++) {
if (endTime > workingTime[i][0] - 1000) {
count++;
}
}
maxCount = Math.max(maxCount, count);
});
return maxCount;
}
solution(["2016-09-15 01:00:04.001 2.0s", "2016-09-15 01:00:07.000 2s"]);
solution([
"2016-09-15 20:59:57.421 0.351s",
"2016-09-15 20:59:58.233 1.181s",
"2016-09-15 20:59:58.299 0.8s",
"2016-09-15 20:59:58.688 1.041s",
"2016-09-15 20:59:59.591 1.412s",
"2016-09-15 21:00:00.464 1.466s",
"2016-09-15 21:00:00.741 1.581s",
"2016-09-15 21:00:00.748 2.31s",
"2016-09-15 21:00:00.966 0.381s",
"2016-09-15 21:00:02.066 2.62s",
]);
처음 작업하면서 3, 18번 테스트가 실패했는데, 반복문 내에서 다음 데이터가 조건에 일치하지 않는 경우 break문을 사용했다. 생각해보니 다음 데이터의 시작시간이 해당 안되더라도 그 뒤의 데이터 로딩이 더 길어서 시작시간이 조건에 맞을 수도 있다. 그래서 해당 조건을 삭제했다.
이후 3번 테스트가 계속 실패했는데, 처음에는 parseFloat 사용하고 부동소수점을 날리는 방식으로 진행했었다. 해당 부분에서 오차가 발생했는지 1000을 곱해서 자연수로만 연산하니 정상적으로 통과했다.
2023년 01월 23일
일을 잘하는 법을 배운다기보다, 일을 잘하는 사람들을 관찰하고 평가하는 내용이다. 내용에 100% 동의하지 않지만, 여러 사례를 통해 다시 한번 생각해보고 배울 부분들이 존재한다. ## 리뷰 나를 어필하는 자리나 프론트엔드 개발자에게 가장 중요한 것을 무엇이냐는 질문이 항상 어려웠다. 당장 생각나는 건 ‘이해관계자들과 커뮤니케이션을 잘해야 하고 미리 캐치할 수 있는 오류를 잡아내야 하며, UI 영역을 담당하기에 사용성을 생각하면서 기획 의견을 내야 한다.’ 정도인데, 실제 업무를 하다 보면 이 정도는 작은 파편이라고 느껴진다. 그러다 보니 어느 순간부터 “프론트엔드 개발자에게 ‘센스’가 가장 중요하다”라고 얘기하고 다녔는데, 책의 도입부부터 일을 잘한다는 것을 ‘감각(sense)’으로 표현하여 놀라움과 함께 공감하면서 읽을 수 있었다. **“오늘날 시대가 요구하는 인재상은 자신의 눈으로 세상을 똑바로 바라보면서, 무엇을 해야 하고 하지 말아야 할지 스스로 판단해 실천할 수 있는 리더십을 지닌 인물이다.”** 책에서는 ‘감각’있는 사람에 대해서 설명하면서, 두 명의 컨설턴트가 만담하는 형태로 이어간다. 중점은 기술적인 부분이 높아진 요즘 감각적으로 상황에 대응하고 있는지와 그에 대한 사례를 설명하는 구조이다. 예시로 프로그래밍에 대해서도 나오는데, 프로그래밍 기술이 뛰어난데도 실적...
2022년 11월 20일
React Native에서 텍스트 에디터로 제작된 공지사항을 그대로 보여주기 위해 html을 렌더링하려고한다. ## 시행착오 처음에는 `react-native-htmlview`를 사용하여 html을 출력했다. ```bash yarn add react-native-htmlview ``` ```js import HTMLView from 'react-native-htmlview'; ... const StyledContentWrap = styled(View)` h1 { font-size: xxx; } h2 { font-size: xxx; } ` ``` html 태그에 맞는 css를 보여주기 위해 styled-components에 태그에 맞는 스타일링을 적용했는데, 여기서 문제가 발생했다. `Node of type rule not supported as an inline style StyledNativeComponent` react-native에서는 html 태그를 지원하지 않기 때문에 styledComponent 영역에서 작성이 불가능하다고 warning이 계속 뜨는 것이였다. 사용은 가능하지만 다른 방법으로 변경하기로 했다. ## react-native-render-html npm trends에서도 react-native-htmlview과는 엄청난 차이를 보이는 `react-native-render-html`를 사용하기로 했다. ```bash yarn add react-native-render-html ``` ```js import HTML from 'react-native-render-html'; import { View, useWindowDimensions } from "react-native"; ... const contentWidth = useWindowDimensions().width; ... ``` `contentWidth`를 주지 않으면 warn이 뜬다. 라이브러리 Readme를 보니 `useWindowDimensions`로 width를 가져와 채워주는 코드가 있어서 그대로 가져왔다. 스타일은 아래와 같이 StyleSheet처럼 스타일링하여 tagsStyles로 넣어주면 된다. ```js...
2022년 10월 25일
Level3 문제 2n명의 사원들을 두 팀으로 나누고 사원마다 무작위 자연수를 받았을 때, B팀이 승리하는 횟수 해결방법 큰 수가 이기는 규칙이기에 내림차순으로 정렬하는게 효율적이다. 게임으로 단순하게 생각하면 A팀의 가장 큰 숫자를 이기지 못하는 상황일 때, B팀의 가장 작은 숫자를 버리는 방향으로 진행하면 된다. ex) A팀 [11, 9, 8, 7], B팀 [10, 9, 8, 7]이라면 B팀에서 11을 이길 수 있는 카드가 없으니까 가장 작은 수를 버리면서 B팀의 가장 큰 수를 유지할 수 있다. 해당 방식으로 tail이라는 변수를 놓고 B팀이 뒤에서 카드를 몇장 버렸는 지 체크하면서 값을 비교한다. 소스코드 function solution(A, B) { const sortA = A.sort((a, b) => b - a); const sortB = B.sort((a, b) => b - a); let tail = 0; let count = 0; sortA.forEach((a, index) => { if (a >= sortB[index - tail]) { tail++; return; } count++; }); return count; } solution([6, 8, 7, 9], [7, 9, 8, 6]); solution([5, 1, 3, 7], [2, 2, 6,...