반응형
반응형

Arrays

  Array는 길이 고정 Array 객체를 생성한 후에는 Array의 길이를 마음대로 변경할 수 없다.

 

ArrayList

  ArrayList는 사이즈는 동적 만약 설정한 범위를 넘어 더 많은 크기가 들어오면 배열 크기를 1.5배 증가시킨다.

 

 

Arrays와 ArrayList는 요소를 추가하거나 가져올 때의 성능과 처리시간은 동일하지만 ArrayList의 경우 범위를 넘으면 1.5배 증가시키면서 시간 Resoucre와 Memory 를 더 차지하게 된다.

반응형
반응형

📝mysql(8버전 이상)

Driver Class com.mysql.cj.jdbc.Driver
URL jdbc:mysql://192.168.0.67:3306/DB명?characterEncoding=UTF-8&serverTimezone=UTC&allowPublicKeyRetrieval=true&useSSL=false

 

📝mariadb

Driver Class org.mariadb.jdbc.Driver"m.mysql.cj.jdbc.Driver
URL jdbc:mariadb://192.168.0.40:7001/search?servertimezone=UTC

 

반응형
반응형

공통

  • 자바는 기본적으로 카멜케이스를 따른다.
  • 통상적으로 자주 사용하는 약어는 사용해도 좋지만 약어 사전에 등록을 해놓아 다른 사람과 충돌이 안 생기게 한다.[ 이건 다들 작업을 시작 하기전에 미리 정의해야 할 사항 ]
  • 협업자와 함께 개발을 하는 경우에는 이름을 통해 그것이 무엇인지 나타내야 한다.
  • 로직이 끝나면 한 줄을 띄어준다 (보기 편하게 하는데 의의가 있음 너무 남발해도 좋지 않다.)
    def get_librosa_mfcc(filepath, n_mfcc = 40, del_silence = False, input_reverse = True):
        if filepath.split('.')[-1] == 'pcm':
            pcm = np.memmap(filepath, dtype='h', mode='r')
            sig = np.array([float(x) for x in pcm])
        elif filepath.split('.')[-1] == 'wav':
            sig, _ = librosa.core.load(filepath, sr=16000)
        else:
            raise ValueError("Invalid format !!")
        if del_silence:
            non_silence_ids = librosa.effects.split(sig, top_db=30)
            sig = np.concatenate([sig[start:end] for start, end in non_silence_ids])
        mfcc = librosa.feature.mfcc(sig, sr=16000, hop_length=160, n_mfcc=n_mfcc, n_fft=400, window='hamming')
        if input_reverse:
            mfcc = mfcc[:,::-1]
        return torch.FloatTensor( np.ascontiguousarray( np.swapaxes(mfcc, 0, 1) ) )​

 → 못된 사례

def get_librosa_mfcc(filepath, n_mfcc = 40, del_silence = False, input_reverse = True):
    if filepath.split('.')[-1] == 'pcm':
        pcm = np.memmap(filepath, dtype='h', mode='r')
        sig = np.array([float(x) for x in pcm])

    elif filepath.split('.')[-1] == 'wav':
        sig, _ = librosa.core.load(filepath, sr=16000)

    else:
        raise ValueError("Invalid format !!")

    if del_silence:
        non_silence_ids = librosa.effects.split(sig, top_db=30)
        sig = np.concatenate([sig[start:end] for start, end in non_silence_ids])

    mfcc = librosa.feature.mfcc(sig, sr=16000, hop_length=160, n_mfcc=n_mfcc, n_fft=400, window='hamming')

    if input_reverse:
        mfcc = mfcc[:,::-1]

    return torch.FloatTensor( np.ascontiguousarray( np.swapaxes(mfcc, 0, 1) ) )

 → 잘된 사례

 

 

클래스

  • 동사를 넣지 않는다.
  • 명사나 명사구로 작성한다.

 

메소드

  • 동사로 시작한다.
  • 카멜케이스 규정을 따른다.
  • 어떤 행동을 하는지에 대한 내용이 있어야한다.
  • 함수는 하나의 동작만 해야한다. → printBankName(String bankName)

 

 

변수명

  • 전치사를 최대한 생략한다. [ to는 자주 쓰이므로 괜찮다 ]
  • 굳이 관사를 넣지 않는다.
  • 단수와 복수를 구분한다
  • 상수는 모두 대문자 표시
  • 변수명이 길어지더라도 정확한 의미를 내포해야한다.
  • 동사를 넣지 않는다.
  • List와 같은 배열 타입일 경우 복수형으로 표시한다. → ArrayList<String> item(x) ArrayList<String> items(o)

 

Bool [참고]

  • isExecuting (실행 중인가?)
  • isShinhanBank (신한은행인가?)
  • isEditable (수정할 수 있는가?)
  • hasVideo (비디오를 가지고 있는가?)
  • canBecomeFirstResponder (첫번째 응답자가 될 수 있는가?)
  • shouldReinstallProduct (제품을 재설치해야 하는가?)
  • allowedAccess (허용된 엑세스인가?)

상수

  • 상수는 대문자로 표시한다 →  int MAIN_WIDTH = 1024

 

 

자바 메소드와 클래스명 주석 팁

@method  : 메소드명 or 클래스명
@brief      : 함수 or 클래스 설명
@detail     : 함수 or 클래스 상세 설명
@author   : 작성자
@since     : 작성일자
@param   : 인자(매개변수)
@return   : 반환값
@why      : 만든 이유

 

 

Interface 팁

1. 함수의 확장성(교체성)이 있다면 Interface로 만든다

   예) 피자 : 5000원, 햄버거 : 50000원 → 피자    5000

                                                    햄버거  50000   [출력기준이 바뀔 수 있는 경우]

 

2. 동일한 함수기능이(내용물은 살짝 달라도 동일한 기능) 여러 클래스에서 쓰이는 경우 Interface로 구성한다.

if (bank.equals("KB")){
  for(int i = 0 ; i < 10; i++){
    if()
  }
}else if (bank.equals("NH"){
  for(int i = 0 ; i < 10; i++){
    if()
  }
}else if (bank.equals("SH"){
  for(int i = 0 ; i < 10; i++){
    if()
  }
}

→  이런식이면 엄청 복잡하다

 

 

첫번째 if문, 두번째 else if , 세번째 else if
→  동일한 부분을 interface로 만든다.

interface BankImpl{
  public void print();
}

class KB{
    @Override
    public void printBankName() {
        System.out.println("KB!!");
    }
}

class NH{
    @Override
    public void printBankName() {
        System.out.println("KB!!");
    }
}

class SH{
    @Override
    public void printBankName() {
        System.out.println("KB!!");
    }
}
    Map<String, Alphabet> typeMap = new HashMap<>();

    typeMap.put("KB", new KB());
    typeMap.put("NH", new NH());
    typeMap.put("SH", new SH());

    String type = "NH";

    typeMap.get(type).printBankName();

이럴경우 들어온 값에 따라 은행이름을 출력하는구나 간단하게 알 수 있다.

 

 

 

 

반응형
반응형
package multi_thread.daemon_thread;

public class AutoSaveThread extends Thread {
	
	public void save() {
		System.out.println("작업 내용을 저장함");
	}
	
	@Override
	public void run() {
		while(true){
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				break;
			}
			save();
		}
		
	}

}
package multi_thread.daemon_thread;

public class DaemonExample {

	public static void main(String[] args) {
		
		AutoSaveThread autoSaveThread = new AutoSaveThread();
		autoSaveThread.setDaemon(true);
		autoSaveThread.start();
		
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {}

		System.out.println("메인 스레드 종료");
	}

}

데몬 스레드 주 스레드의 작업을 돕는 보조적인 역할을 수행하는 스레드입니다.

주 스레드 (메인 스레드) 가 종료되면 데몬 스레드는 강제적으로 자동 종료됩니다.

 

setDaemon(true)을 이용해 일반 스레드를 데몬 스레드로 만듭니다.

시작 하는 방법은 기본 스레드와 동일합니다.

 

 

 

 

반응형
반응형
package multi_thread.thread_stop_interrupt;

public class PrintThread1 extends Thread{
	private boolean stop;
	
	public void setStop(boolean stop) {
		this.stop = stop;
	}
	
	public void run() {
		while(!stop) {
			System.out.println("실행 중");
		}
		System.out.println("자원 정리");
		System.out.println("실행 종료");
	}
}
package multi_thread.thread_stop_interrupt;

public class StopFlagExample {

	public static void main(String[] args) {
		
		PrintThread1 printThread = new PrintThread1();
		printThread.start();
		
		try { Thread.sleep(1000);} catch (InterruptedException e ) {}

		printThread.setStop(true);
	}

}

스레드를 종료시키는 법에는 2가지 방법이 있다. 하나는 stop()과 interrupt() 메소드를 이용하는 방법

 

하지만 stop()메소드는 스레드가 갑자기 종료되면 스레드가 사용 중이던 자원이 불안정 상태로 남겨지기 때문에

안 쓰이게 됩니다. 그래서 stop플래그를 이용한 방법이 있습니다.

 

stop플래그란 무한 반복문을 돌고 있을 때 boolean을 이용해 안정적으로 run()을 종료로 이끌게 하는 역할입니다.

 

package runnable_jar;

public class PrintThread extends Thread {

	@Override
	public void run() {
		// 방법 1
//		try {
//			while (true) {
//				System.out.println("실행 중");
//				Thread.sleep(1); // sleep 있어야 main Thread에서 interrupt() 사용시 인식 함
//			}
//		} catch (InterruptedException e) {
//			e.printStackTrace();
//		}
		
		// 방법 2
		while(true) {
			System.out.println("실행중");
			if(Thread.interrupted()) { // sleep 없어도 사용 가능한 부분
				break;
			}
		}
		
		
		System.out.println("자원 정리");
		System.out.println("실행 종료");
	}

}
package runnable_jar;

public class InterruptExample {

	public static void main(String[] args) {

		Thread thread = new PrintThread();
		thread.start();

		try {
			Thread.sleep(1000);
		}catch(Exception e) {
			e.printStackTrace();
		}
		
		// 일시 정지 상태일 때 InterruptedException을 발생 시킴
		// 실행 대기 또는 실행 상태에서는 발생하지 않는다.
		thread.interrupt();
	}

}

interrupt 메소드는 스레드가 일시 정지일 때 InterruptedException 예외를 발생 시키는 역할을 합니다.

이것을 이용하면 run()메소드를 정상 종료시킬 수 있습니다.

 

지금 Thread.sleep(1)이라도 준 이유일시정지 일 때 예외를 발생시키기 때문입니다.

 

반응형
반응형
package multi_thread.thread_alternate;

public class WorkObject {
	public synchronized void methodA() { // 동기화 메소드에서만 사용 가능 (synchronized)

		System.out.println("ThreadA의 methodA() 작업 실행");
		notify(); // wait() 상태 스레드를 실행 대기로 변경 (실행 가능한 상태)
		try { wait(); } // 자기 자신 일시정지 상태로 변경
		catch (InterruptedException e) { }
	}

	public synchronized void methodB() { // 동기화 메소드에서만 사용 가능 (synchronized)

		System.out.println("ThreadB의 methodB() 작업 실행");
		notify();  // wait() 상태 스레드를 실행 대기로 변경 (실행 가능한 상태)
		try { wait(); }  // 자기 자신 일시정지 상태로 변경
		catch (InterruptedException e) { }
	}
}
package multi_thread.thread_alternate;

public class ThreadA extends Thread{
	private WorkObject workObject;
	
	public ThreadA(WorkObject workObject) {
		this.workObject = workObject;
	}
	
	@Override
	public void run() {
		for(int i = 0 ; i < 10; i++) {
			workObject.methodA();
		}
	}
}
package multi_thread.thread_alternate;

public class ThreadB extends Thread{

	private WorkObject workObject;
	
	public ThreadB(WorkObject workObject) {
		this.workObject = workObject;
	}
	
	@Override
	public void run() {
		for(int i = 0 ; i < 10; i++) {
			workObject.methodB();
		}
	}
}
package multi_thread.thread_alternate;

public class WaitNotifyExample {

	public static void main(String[] args) {
		WorkObject sharedObject = new WorkObject();
		
		ThreadA threadA = new ThreadA(sharedObject);
		ThreadB threadB = new ThreadB(sharedObject);
		
		threadA.start();
		threadB.start();

	}

}

두 개 스레드를 교대로 번갈아 실행 시키고 싶을 때 notify()와 wait()를 이용하면 됩니다.

 

자신의 작업을 시작하면 상대방 스레드(B)를 실행대기 상태를 걸고 자신(A)은 실행합니다.

그 후 자신의 작업이 끝나면(A)상대방 스레드(B)상대방(A)을 실행대기로 만들고 자기(B)는 실행합니다.

실행 끝난 후 자신(B)을 일시정지 상태로 만들어야합니다.

 

공유객체는 각 작업 내용을 동기화 메소드로 구분해야합니다.


notify() 같은 공유 객체동기화 메소드를 이용하는 상대방 스레드 실행대기상태로 만듭니다.
wait() 자신은 일시 정지 상태로 만듭니다.

 

이렇게 번갈아가면서 실행 되게 됩니다.

 

반응형
반응형
package multi_thread.thread_join;

public class SumThread extends Thread{
	private long sum;
	
	public long getSum() {
		return sum;
	}
	
	public void setSum(long sum) {
		this.sum = sum;
	}
	
	public void run() {
		for (int i = 1 ; i <= 100 ; i++) {
			sum += i;
		}
	}

}
package multi_thread.thread_join;

public class JoinExample {

	public static void main(String[] args) {
		
		SumThread sumThread = new SumThread();
		sumThread.start();
		
		try { 
			sumThread.join(); 
			// sumThread를 일시중지하는게 아니라 sumThread가 다 종료될 때까지 
			// 호출한 스레드(여기선 메인스레드)를 일시정지시킵니다.
		}catch (InterruptedException e) {
			
		}

		System.out.println("1 ~ 100 합 : " + sumThread.getSum());
	}

}

join이라는 메소드사용 스레드가 전부 끝날 때 까지 다른 스레드를 중지시키는 역할입니다.

 

스레드는 번갈아 실행 되기 때문에 메인 스레드를 멈추지 않으면 연산하기도 전에 Sum 값을 출력해버려 0이 나오게됩니다.

그래서 join을 걸어서 메인스레드를 멈추게 한 것입니다.

 

 

그리고 해당 스레드가 다 끝나면 모든 스레드를 다시 정상 실행시킵니다.

반응형
반응형
package multi_thread.thread_status;

public class ThreadA extends Thread{

	public boolean stop = false; // 종료 플래그
	public boolean work = true ; // 작업 진행 여부 플래그
	
	public void run() {
		while(!stop) {
			if(work) {
				System.out.println("ThreadA 작업 내용");
			} else {
				Thread.yield(); // 실행 대기 상태 만들기
			}
		}
		System.out.println("ThreadA 종료");
	}
}
package multi_thread.thread_status;

public class ThreadB extends Thread {
	
	public boolean stop = false; // 종료 플래그
	public boolean work = true ; // 작업 진행 여부 플래그
	
	public void run() {
		while(!stop) {
			if(work) {
				System.out.println("ThreadB 작업 내용");
			} else {
				Thread.yield(); // 실행 대기 상태 만들기
			}
		}
		System.out.println("ThreadB 종료");
	}
}
package multi_thread.thread_status;

public class YieldExample {

	public static void main(String[] args) {
		ThreadA threadA = new ThreadA();
		ThreadB threadB = new ThreadB();

		threadA.start();
		threadB.start();
		
		try {Thread.sleep(1000);} catch (InterruptedException e) {}
		threadA.work = false;
		
		try {Thread.sleep(1000);} catch (InterruptedException e) {}
		threadA.work = true;
		
		try {Thread.sleep(1000);} catch (InterruptedException e) {}
		threadA.stop = true; 
		threadB.stop = true;
		// thread.stop() 이라는 메소드가 존재하지만 강제로 종료하는 거이기 때문에 스레드가 살아있을 수가 있기 때문에 플래그값을 변경해 스레드 자체를 정상 종료시키는게 더 좋은 방법
		}
	}

yield() 메소드호출한 스레드를 실행 대기 상태로 돌아가 다른 스레드가 실행 기회를 가질 수 있게 도와줍니다.

(동일 또는 높은 우선순위의 스레드)

 

여기에서 ThreadA, B가 번갈아가면서 사용하지만 ThreadA의 work 값이 false가 되면 아무 이유 없는 무한루프를 반복합니다.

 

멀티스레드가 정말 병렬처리라면 상관 없는데 번갈아가면서 사용하는 거기 때문에(싱글코어 일시 = CPU1개) Thread A가 의미 없는 짓을 할 때 동안 ThreadB는 사용을 못하게 되는 것이죠 그걸 yield()메소드를 이용해 ThreadB가 계속적으로 사용될 수 있게  ThreadB가 의미 없는짓 할 땐 ThreadA가 쓰게 되면 번갈아 가면서 안 써도 되니까 속도가 더 빨라지겠죠?

 

 

반응형
반응형
package multi_thread.thread_synchronized;

public class Calculator {
	private int memory;
	
	public int getMemory() {
		return memory;
	}
	
	public synchronized void setMemory (int memory) {
		this.memory = memory;
		try {
			Thread.sleep(2000);
		}catch(InterruptedException e) {}
		System.out.println(Thread.currentThread().getName() + " : " + this.memory);
	}
	/* 임계구역 설정 안 한 메소드
	public void setMemory (int memory) {
		this.memory = memory;
		try {
			Thread.sleep(2000);
		}catch(InterruptedException e) {}
		System.out.println(Thread.currentThread().getName() + " : " + this.memory);
	}
	*/
}
package multi_thread.thread_synchronized;

public class User1 extends Thread{
	private Calculator calculator;
	
	public void setCalculator(Calculator calculator) {
		this.setName("User1");
		this.calculator = calculator;
	}
	
	public void run() {
		calculator.setMemory(100);
	}
}
package multi_thread.thread_synchronized;

public class User2 extends Thread{
	private Calculator calculator;
	
	public void setCalculator(Calculator calculator) {
		this.setName("User2");
		this.calculator = calculator;
	}
	
	public void run() {
		calculator.setMemory(50);
	}
}
package multi_thread.thread_synchronized;

public class MainThreadExample {

	public static void main(String[] args) {
		
		Calculator calculator = new Calculator();
		
		User1 user1 = new User1();
		user1.setCalculator(calculator);
		user1.start();
		
		User2 user2 = new User2();
		user2.setCalculator(calculator);
		user2.start();

	}

}

 

스레드가 2개가 실행 될 때 동시에 같은 객체(calculator)를 이용한다면 번갈아 실행 됩니다.

User1스레드에서 calculator 에서 memory 라는 변수의 값을 100으로 바꾸고

User2스레드로 넘어가서 User2스레드에서 memory 변수 값을 다시 50으로 바꿉니다. 

원래는 바로 User1스레드에서의 memory가 100일텐데 Thread.sleep이 2초로 설정되어 있기 때문에

User2스레드가 진행하면서 이미 memory값을 50으로 바꿨기 때문에 둘다 출력값이 50이 나오게 됩니다.

 

이러한 스레드가 사용 중인 객체다른 스레드가 변경할 수 없도록 하려면 잠금을 걸어서

다른 스레드가 사용할 수 없게 해야합니다. 그 코드의 영역을 임계 영역이라고 합니다.

 

자바는 임계 영역을 지정하기 위해 동기화메소드와 동기화 블록을 제공합니다.

동기화 메소드를 만드는 법synchronized를 붙이면 됩니다.

 

동기화 메소드인 setMemory는 임계영역이라서 한 번에 한 스레드만 실행할 수 있고 다른 스레드는 실행할 수 없게 됩니다.

 

반응형