문제 설명

수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다.

마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.

제한사항

  • 마라톤 경기에 참여한 선수의 수는 1명 이상 100,000명 이하입니다.
  • completion의 길이는 participant의 길이보다 1 작습니다.
  • 참가자의 이름은 1개 이상 20개 이하의 알파벳 소문자로 이루어져 있습니다.
  • 참가자 중에는 동명이인이 있을 수 있습니다.

 

import java.util.HashMap;

class Solution {
    public String solution(String[] participant, String[] completion) {
        String answer = "";
        
        HashMap<String, Integer> map = new HashMap<String, Integer>();
        
        for(String player : participant) map.put(player, map.getOrDefault(player, 0)+1);
        for(String winner : completion) map.put(winner, map.get(winner)-1);
            
        for( String key : map.keySet() ) {
            if(map.get(key) != 0){
                answer = key;
                break;
            }
        }
        
        return answer;
    }
}

 

entrySet()은 key 와 value 반환하고,

keySet()은 key값을 반환.

Iterator()는 순서에 상관없이 하나씩 접근.

 

public static void main(String[] args) { 
	Map<string, string> map = new HashMap<string, string>(); 
    map.put("key1", "value1"); 
    map.put("key2", "value2"); 
    map.put("key3", "value3"); 
    map.put("key4", "value4"); 
    
    
    // entrySet 
    for( Map.Entry<string, string> elem : map.entrySet() ){
    	System.out.println( "key : " + elem.getKey() + ", value : " + elem.getValue()) ); 
    } 
    
    // keySet
    for( String key : map.keySet() ){ 
    	System.out.println( "key : " + key + ", value : " + map.get(key)) ); 
    } 
    
    // Iterator
    Iterator<string> keys = map.keySet().iterator();
    while( keys.hasNext() ){ 
    	String key = keys.next(); 
        System.out.println( "key : " + key + ", value : " + map.get(key)) );
    } 
}

'Java' 카테고리의 다른 글

자바 람다(Lamda) 기초  (0) 2021.02.13
자바 스트림(Stream)  (0) 2021.02.09
자바 Primitive Type과 Reference Type  (0) 2020.02.26
자바 [getOrDefault, putIfAbsent]  (0) 2020.01.22
자바 예외처리 [Exception]  (0) 2020.01.22

pageshow 와 pagehide이벤트를 위한 이벤트 객체 

 

브라우저는 문서를 처음 로드할 때 load 이벤트 다음에 pageshow 이벤트를 발생 시키며, 

문서를 벗어날 때는 pagehide 이벤트를 발생시킨다. 

 

pageshow와 pagehide 이벤트는 window 객체에서 발생하며,

PageTransitionEvent 객체는 두 이벤트와 조합된다. 

 

pageshow와 pagehide는 버블링되지 않고, 취소 가능한 기본 동작도 존재하지 않는다.

(크롬에서 pageshow, pagehide는 디버깅이 안타지던데 이 때문인가..)

 

해당 이벤트 객체의 persisted 프로퍼티의 값은 페이지가 로드 또는 새로고침이 아니라 복원되었을 경우에 true이다.

페이지가 네트워크 또는 디스크 캐시로부터 로드 또는 새로고침 될 때는 false의 값을 가진다.

 

persisted 프로퍼티는  pagehide에선 항상 true이고, pageshow에서만 true/false의 값을 가진다.

 

 

 


load

- 문서와 해당 문서의 외부 리소스들이 모두 로드되었을 때

 

pagehide

- 페이지가 캐시되어 있으며 다른 페이지에 의해 교체되었을 때

 

pageshow

- 페이지가 처음 로드되면 load이벤트 직후에 pageshow이벤트가 발생한다. 해당 이벤트에는 persisted 값이 false이지만, 페이지가 브라우저의 메모리 캐시로부터 복구되었다면 load이벤트가 발생하지 않으며(캐시된 페이지가 이미 loaded상태이기 때문), persisted 프로퍼티 값이 true로 설정된 이벤트객체와 함께 pageshow 이벤트가 발생한다.

 

unload

- 브라우저가 페이지로부터 다른 곳으로 벗어날 때. 페이지의 onunload 핸들러를 등록하면, 페이지가 캐시되지 않는다는 사실에 주의하자. 사용자가 새로고침엇ㅂ이 빠르게 현재 페이지로 되돌아오게 하려면, onpagehide를 대신 사용하는 편이 낫다.

 

 

출처 : 자바스크립트 완벽 가이드 / 데이비드 플레너건 

 

 

 

기존 소스상 beforeunload 이벤트를 이용해 web에서 이전 화면으로 이동 시, 스크롤 유지를 시키고 있었다. 

 

그런데 왠걸 IOS web(safari)에선 스크롤 유지가 되지 않고, history back 시 계속 페이지가 리로딩되며 이전에 보고있던 스크롤 위치를 유지하지 못하고 스크롤이 최상단으로 올라가는 현상이 발생. 

 

검색해보니 beforeunload 이벤트 자체를 IOS safari에선 지원해주지 않는 것이였다.

 

아래 MDN에서도 아예 IOS safari는 지원이 되지 않는다고 명시되어 있다.

참고URL: developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event

 

Window: beforeunload event - Web APIs | MDN

The beforeunload event is fired when the window, the document and its resources are about to be unloaded. The document is still visible and the event is still cancelable at this point. Bubbles No Cancelable Yes Interface Event Event handler property onbefo

developer.mozilla.org

기존 AOS 의 경우 페이지를 벗어나려고 할 때, beforeunload 이벤트에서 스크롤 위치값을 sessionStorage에 저장시켰다가, 로딩 콜백함수에서 sessionStorage에 담은 값을 되찾아 스크롤을 위치시켜 왔다.

 

IOS safari에서도 동일한 기능 적용을 위해 여러 검색과 시도 결과 

'pagehide'라는 이벤트가 정상 작동하는 것을 알게되었다.

window.addEventListener('pagehide', function(e){
	sessionStorage.setItem('historyScrollTop' , document.documentElement.scrollTop);
});

document.documentElement.scrollTop //  현재 스크롤 위치를 가져오며 모든 브라우저에서 지원.

 

 

 

[Oracle] 조회수/시청수 계산, 숫자 소수점 찍기

 

개발업무 도중 영상의 시청건수를 노출해야 하는데 100건 이상부터 노출해야하고,

-천단위 쉼표 표기 ex)1,000회

-만단위 소수점 표기 ex)1.1만회, 10.1만회...

-억단위 소수점 표기 ex)1.1억회... 

 

를 각각 적용해서 노출할 수 있게 해달라는 니즈가 있었다.

 

아래 처럼 구현할 수 있었다.

TO_CHAR함수 내에 'FM'은 자리수가 모자를 경우 앞에 공백을 제거하도록 도와준다. 

 

SELECT CASE WHEN &1 >= 100000000 THEN TO_CHAR (TRUNC(&1/100000000), 'FM999,990')||'.'|| SUBSTR(&1, -8, 1)||'억회' 
            WHEN &1 >= 10000 THEN TO_CHAR (TRUNC(&1/10000), 'FM999,990')||'.'|| SUBSTR(&1, -4, 1)||'만회' 
            WHEN &1 >= 100 THEN ''||TO_CHAR (&1, 'FM999,990')||'회' 
            ELSE '' END VIEW_CNT_STR 
  FROM DUAL;

'Oracle' 카테고리의 다른 글

오라클 [select 기본 구분, 주요 내장함수, 집계함수]  (0) 2020.01.19

배포를 위한 Job을 만들 때,

Tomcat Down > source build/packing > Tomcat Start 이후

정상적으로 배포가 완료되었는지? 혹은 서비스에 이상이 없는지? 이에 대한 검증 절차가 필요하다. 

 

검증 방법은 단순히 url을 콜 했을 때, 200 return 이 떨어지는지 확인하면 된다.

만약 서비스가 정상적으로 올라가지 않았다면 404 Error를 던질것이고

서비스는 정상이지만 페이지 자체에 이상이있다면 500 Error를 던질 것이다.

 

검증방법 추가를 위해 Jenkins의 Job 구성에서 Execute shell  단계를 추가한다.

그리고 Command란에 해당 웹 서비스를 체크할 쉘스크립트 파일의 경로와 대상 IP정보를 인자로 전달해주면 된다. 

 

 

Execute shell

Command

/home/workspace/jenkins_shell/web_check.sh 10.112.2.xxx

web_check.sh 파일은 아래와 같이 작성하면 된다. 

#! /bin/sh

CURL='which curl'

if [ -z "$CURL" ]; then
	echo "curl not found"
    exit 1
fi

echo "Start Web Check"
for i in {0..3}
do
	loop=0
    surl=http://$1:808$i
    http_status="FAIL"
    
    while [ ${loop} - le 20 ];do
    	result='curl -s -o /dev/null -w "%{http_code}" ${surl}/main | awk '{print $0}''
        
        if [ "$result" == "200" ]; then
        	http_status="TRUE"
            
            echo ${surl}" - web check success"
            break
        fi
        
        loop=$((loop + 1))
        sleep 1
    done
    
    if [ "FAIL" == ${http_status} ]; then
    	echo "fail - "${surl}" http_code : "${result}
        echo "End Web Check\n"
        exit 1
    fi
done
echo "End Web Check"

for문 안에서

10.112.2.xxx IP에 대해 

8080 포트부터 8083 포트까지 web Check를 수행

'Linux' 카테고리의 다른 글

df 명령어 허가 거부  (0) 2020.02.04
리눅스에서 tomcat 로그파일 위치  (0) 2020.02.04

 

React 공부 시작하려는데, React페이지에서 JavasScript를 다시 보고 올 수 있는 링크를 주는 친절함을 베풀었다.

타고 넘어가 보니 한 페이지에 보기쉽게 JavaScript 정리가 되어있어 한번 쭈욱~ 훑어보고 왔다ㅎㅎ 

 

developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript

 

A re-introduction to JavaScript (JS tutorial)

Why a re-introduction? Because JavaScript is notorious for being the world's most misunderstood programming language. It is often derided as being a toy, but beneath its layer of deceptive simplicity, powerful language features await. JavaScript is now us

developer.mozilla.org

 

--------------------------------------------
표준 내장객체 및 메소드 

Number
String
Boolean
Symbol (new in ES2015)
Object
ㄴ Function
ㄴ Array
ㄴ Date
ㄴ RegExp
null
undefined 

--------------------------------------------

javascript에서 var와 let/const와의 차이점 

일반적으로 자바스크립트에서 var를 이용해서 변수 선언시 블록 범위에 제한이 없지만, 
ECMAscript2015 부터 let과 const 선언을 사용하면 블록 범위 변수를 만들 수 있음. 

--------------------------------------------
제공하는 for 사용법 

for (var i = 0; i < 5; i++) {
  // Will execute 5 times
}

for (let value of array) {
  // do something with value
}

for (let property in object) {
  // do something with object property
}

--------------------------------------------

&& 및 || 연산자는 단락 논리를 사용하므로 두 번째 피연산자를 실행할지 여부는 첫 번째 피연산자에 따라 다릅니다. 
이는 속성에 액세스하기 전에 null 개체를 확인하는 데 유용합니다.

var name = o && o.getName();

--------------------------------------------
switch 문은 숫자 또는 문자열을 기반으로 여러 분기에 사용할 수 있습니다.

--------------------------------------------
Object 
JavaScript 객체는 이름-값 쌍의 단순한 모음으로 생각할 수 있습니다. 따라서 다음과 유사합니다.

Dictionaries in Python.
Hashes in Perl and Ruby.
Hash tables in C and C++.
HashMaps in Java.
Associative arrays in PHP.

객체 생성 방법 두가지.
var obj = new object();
var obj = {}; // *****별이 다섯개 ~

두 방법은 의미상 동일함. 두 번쨰는 객체 리터럴 구문이라고 하며 더 편리하고. JSON 형식의 핵심이며 항상 선호되어야 함. 

접근할때는 .을 이용하여 값에 접근. 

--------------------------------------------

Array 
Array는 특별한 유형의 객체. 객체와 달리 []로 선언. 

var a = new Array();
a[0] = 'dog';
a[1] = 'cat';
a[2] = 'hen';
a.length; // 3

혹은 
var a = ['dog', 'cat', 'hen'];
a.length; // 3

var a = ['dog', 'cat', 'hen'];
a[100] = 'fox';
a.length; // 101

존재하지 않는 인덱스에 접근시 undefined를 반환. 
type of a[90]; // undefined


Array 요소에 접근시, 

for (var i = 0; i < a.length; i++) {
  // Do something with a[i]
}

아래 표기법은 ECMA2015 부터 가능해짐. 
for (const currentValue of a) {
  // Do something with currentValue
}

for..in 루프를 사용하면 배열을 반복할 수도 있지만 배열 요소가 아니라 배열 인덱스를 반복한다.

 

제공하는 메소드 

a.pop() // 마지막 요소를 Remove and returns.
a.push(item) // 마지막에 요소를 추가.
a.shift() // 첫번째 요소를 Remove and returns.
a.unshift(item) // 배열의 시작부분에 요소를 추가.
a.reverse()  // Reverses the arrays.
a.sort([cmpfn]) // 선택적 비교를 이용한 정렬
이외에 slice, concat, 등


----------------------------------------

Funciton

function makePerson(first, last) {
  return {
    first: first,
    last: last,
    fullName: function() {
      return this.first + ' ' + this.last;
    },
    fullNameReversed: function() {
      return this.last + ', ' + this.first;
    }
  };
}

var s = makePerson('Simon', 'Willison');
s.fullName(); // "Simon Willison"
s.fullNameReversed(); // "Willison, Simon"

----------------------------------------

prototype  

Java 가 class를 이용해 객체를 생성한다면, JavaScript는 prototype을 이용해 객체를 생성한다.


prototype을 이용하면 runtime에 기존 객체에 메서드를 추가할 수 있음.

-----------------------------------------

prototype을 이용한 문자열 거꾸로 출력.

 

var s = 'Simon';
s.reversed(); // TypeError on line 1: s.reversed is not a function

String.prototype.reversed = function() {
  var r = '';
  for (var i = this.length - 1; i >= 0; i--) {
    r += this[i];
  }
  return r;
};

s.reversed(); // nomiS

-----------------------------------------

클로저 ..? 너는 다음 기회에 

 

 

업무 중 이벤트 이미지를 특정 일자까지만 노출시키고 이후로는 비노출 시키기위해 new Date 함수를 이용하여 

조건문을 만들었다. 

 

그런데 PC의 크롬과 안드로이드에선 정상적으로 동작하는데,

아이폰 사파리나 크롬에서는 동작하지 않는 것이였다. 

 

당시 내가 구현했던 소스는

var exDate= new Date('2020/07/12/23:59:59'); // 2020년 7월 12일 23:59:59
var currDate = new Date();

if(exDate > currDate) {
...
}

위와 같다. 

 

 

 

디버깅 결과, 아이폰에서 exDate가 invalid Date 로 확인되고 있었다.

크로스 브라우징 이슈였고, 구글링 결과 moment.js라는 외부 라이브러리를 이용하면 해결 가능하다는 글들이 꽤 많았으나 표준 표기법을 이용하니 정상 인식되었다. 

 

표준 표기법은 아래와 같다. 

var exDate = new Date(2020,06,12,23,59,59); // 2020년 7월 12일 23:59:59

 

월 표기시 -1하여 사용해야 한다는것에 주의가 필요하다. 

+ Recent posts