반응형

표준프레임워크는 maven으로
라이브러리가 관리가 되고 있습니다.

maven을 통한 jar 라이브러리 파일들이
알수 없는 이유로 제대로 내려오지 않은 문제가 발생할수가 있는데요.

pom.xml에 보면 전자정부 레포지토리는 다음을 추천드립니다.
<repository>
<id>egovframe</id>
http://maven.egovframe.kr:8080/maven/
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>

메이븐 레파지토리를 초기화할 필요도 있는데요.
프로젝트 우클릭 > Maven > Update Project를 선택하시고
Force Update ~~~에 체크후 OK선택하여
저장소를 초기화후에 재기동해 보시기 바랍니다.

728x90
반응형
반응형

1. T1 반송시스템을 통하여 음성신호를 PCM으로 전송할 때 다음에 대하여 설명하시오.

PCM : 아날로그 정보를 디지털 펄스코드로 바꾸어 전송하고 다시 아날로그 정보로 되돌리는 방식

표본화 : 대역 제한된 아날로그 입력신호를 입력신호의 최고주파수의 2배 이상의 주파수로 샘플링(샤논의 정리)하여 PAM 신호를 얻는 과정

양자화 : 표본화된 PAM 신호를 가장 가까운 이산적인 양자화레벨에 근사화시키는 과정

부호화 : 양자화된 레벨 값을 1과 0의 펄스열로 변환하는 과정

다중화 : 각 채널의 신호를 하나의 고속채널에 많은 량의 동시에 전송할 수 있는 기술(TDMA, FDMA, CDMA, W-CDMA)

나이퀴스트 정리 : fs = 2fm  
샤논의 정리 : fs >= 2fm (aliasing(표본화 오차)를 방지하기 위함)

2. 디지털 중계기에는 아날로그 중계기에 없는 재생 기능이 있다. 기능 3가지를 적으시오.

Reshaping, Regeneration, Retiming

 3. 샤논의 정리를 통한 채널 용량을 구하는 공식을 정의하시오.

4. 나이키스트 정리를 통한 채널 용량을 구하는 공식을 정의하시오.

5. 토폴로지에 따른 분류 5가지를 기술하시오.

성형, 트리형, 망형, 링형, 버스형

6. 패킷교환방식의 종류에는 가상회선, 데이터그램 방식 2가지가 있다. 이를 기술하시오.

가상회선방식이란 송신노드와 수신노드 간에 데이터를 전달하기 위하여 사용자가 호 요청을 하면 노드 간에 연결하는 전용 통신로인 가상회선이 설립된다. 가상회선이 설립되면 해당호가 종료될 때까지 선택된 경로만을 따라 패킷 전송이 이루어지고, 모든 패킷 전송이 종료되면 가상회선은 종료되는 방식이다.

데이터그램방식은 송신노드와 수신 노드 간에 데이터를 전달하기 위하여 패킷 스위치는 현 상태의 패킷 전송 부하에 따라서 패킷의 경로를 동적으로 설정하고, 일련의 데이터를 패킷 단위로 분할하여 전송하고, 목적지 노드에서는 패킷의 재순서화 조립 과정이 필요한 방식이다. 왜냐하면, 각각의 패킷은 스위치마다 최선의 경로를 선택하므로 패킷의 도착순서가 바뀔 수 있다.

728x90
반응형
반응형

Build의 순서는 아래와 같다.

소스코드 -> 전처리 -> 컴파일 -> 링크 -> 실행

C언어를 처음 공부할 때, #define을 사용하지 않으면 전처리 과정을 거치지 않는다고 생각한 적이 있다.

#으로 시작하는 문장은 전부 전처리기 지시자임에도 #include는 전처리기라고 생각하지 않았다. 항상 C언어를 실습할 때, 의무적으로 #inlcude <stdio.h>를 작성한 폐해이다.

전처리란 무엇인가?

컴파일 전에 처리해야 하는 일이고 전처리를 수행하는 장치를 전처리기라고 한다.

전처리기는 헤더 파일을 불러오거나, 소스 파일 내부의 특정 문자열을 상수 또는 문자로 치환하거나, 조건에 따라서 코드의 일부를 컴파일하거나 컴파일하지 못하게 하는 선택 기능을 제공한다.

궁금증이 하나 발생한다.

#define은 왜 사용하는가? 단순히 변수나 함수를 선언 및 호출하면 되지 않는가? 일반 변수 및 함수와 매크로(#define)의 차이는 무엇인가?

이를 이해하기 위해선 컴파일 단계를 이해할 필요가 있다.

컴파일이란 무엇인가? 기계어로 번역하는 번역기이다. 왜 기계어로 번역하는가? 소스 코드는 사람이 이해하기 쉬운 문장이며, 기계는 이해할 수 없다. 그러므로 기계가 이해할 수 있는 문장으로 번역해줘야 한다.

C언어가 생기기 이 전, 개발자들은 기계(컴퓨터, CPU)를 직접 제어하기 위해 기계어(어셈블리어)를 직접 작성하였다. 하지만 CPU는 다양했고, CPU의 종류에 따라 어셈블리어 작성하는 방법도 각기 달랐다고 하며, 간단한 프로그램에도 코드가 굉장히 길어졌다. 

이 문제점을 해결하기 위해, 기계어를 직접 사람이 작성하지 않아도 되는 번역기를 개발했는데 그것이 컴파일러이다. 개발자들은 더 이상 기계의 종류를 상관하지 않아도 된다.


C언어는 소스코드 중복을 줄이고 코드의 재사용성을 높이기 위해서 함수를 제공한다. 하지만, 함수는 호출될 때 *스택 프레임이 일어나기 때문에 속도가 느려지는 단점이 있다. 따라서 코딩할때는 매크로를 함수와 같은 기능으로 작성하지만 실제 기계어로 번역될 때는 직접 코딩한 것처럼 처리(치환, 전처리 단계에서 매크로가 소스코드로 변환)된다.

함수 호출 시, 스택이라는 메모리 공간에 매개 변수, 반환 포인터 값, 지역 변수 순서로 저장되는 값을 스택 프레임이라고 한다.

즉, 저장 공간인 스택을 메모리 낭비를 줄이고 실행 속도를 높이기 위해 매크로를 사용한다. 하지만 매크로는 소스코드로 바로 변환되므로 실행 파일 크기가 커지며, 재귀호출을 할 수 없다는 단점을 가지므로 적절하게 사용하는 것이 중요하다. 

요즘엔 컴퓨터의 메모리가 굉장히 넉넉하기 때문에 메모리 걱정을 하지 않을 때가 많지만, 메모리 공간이 넉넉치 않은 임베디드 시스템과 같은 환경에서는 매크로를 많이 사용한다.


아래 매크로 함수와 일반 함수 예시를 보겠다.

#include <stdio.h>

#define MUL(x, y) x*y

int mul(x, y)
{
	return x*y;
}
int main()
{
	int a, b;
    
    scanf("%d %d", &a, &b);
    printf("%d", MUL(a+1, b+1));
    printf("%d", mul(a+1, b+1));
}

// result
// a=3, b=4 입력
// 8
// 20

왜 결과값이 8, 20으로 다른 값이 나올까?  매크로는 전처리 단계에서 소스 코드로 변경된다고 했다. 

MUL(a+1, b+1)을 소스 코드로 치환되면 a+1*b+1 이다.

그러므로 3+1*4+1로 계산되어 8이라는 결과가 출력된다. mul과 같은 결과를 내기 위해선, 

#define MUL(x, y) ((x) * (y)) 로 변경하면 된다. 소스코드로 치환하게 되면, ((a+1)*(b+1))이다.

728x90
반응형
반응형

/ : 루트 디렉터리

리눅스는 언제나 시스템 전체에 단 하나의 트리만을 가진다.

첫 번째 디스크는 루트 디렉터리에 마운트, 그 이후의 디스크는 var 디렉터리에 마운트된다.

리눅스의 디렉터리 구조는 FHS(Filesystem Hierachy Standard)라는 표준 사양을 따른다.

  • /bin : 일반 사용자 및 관리자가 사용하는 명령어의 실행 파일이 배치되어 있는 디렉터리. 특히 시스템과 관련된 중요한 명령어를 포함하고 있다. 
  • /dev : 디바이스 파일이 배치되어 있는 디렉터리. 디스크, 키보드 등 주변기기를 다루기 위한 디렉터리이다.
  • /etc : 리눅스에서 돌아가는 다양한 어플리케이션의 설정 파일이 /etc 아래에 배치된다. 애플리케이션뿐만 아니라 리눅스 자체의 설정 파일도 배치된다.
  • /home : 사용자별로 할당되는 홈 디렉터리가 배치되는 디렉터리. 홈 디렉터리란 사용자별로 할당되는 개인용 디렉터리를 말한다. 사용자 이름이 디렉터리 이름으로 사용된다. 
  • /sbin : /bin과 비슷하게 실행 파일을 포함하는 디렉터리. 이 디렉터리에는 관리자용 명령어가 포함되어 있다.  
  • /tmp : 임시 파일이 들어 있는 디렉터리. 애플리케이션 실행 중 임시로 작업 결과를 파일로 보관할 때 보통 이 디렉터리에 저장된다. 정기적으로 이 디렉터리 안의 파일을 삭제하도록 설정된 배포판도 있으므로 중요한 파일을 /tmp에 보관하면 안된다.
  • /usr : 설치한 애플리케이션의 실행 파일, 문서, 라이브러리 등을 포함하는 디렉터리. /usr 아래에는 bin, sbin, etc 등이 있어 루트 디렉터리와 비슷한 구조이다.
  • /var : 변화하는 데이터를 저장하기 위한 디렉터리. 애플리케이션 실행 중에 만들어진 데이터나 로그, 메일 등이 이곳에 저장된다. 

 

728x90
반응형
반응형
Class
void main()
{
  // constructor
  Idol blackPink = const Idol(
    name:'블랙핑크',
    members:['지수', '제니', '리사', '로제']);
  
  blackPink.sayHello();
  blackPink.introduce();
  
  // named constructor
  Idol blackPink2 = Idol.fromList([
    ['지수', '제니', '리사', '로제'],
    '블랙핑크'
    ]);
  
  blackPink2.sayHello();
  blackPink2.introduce();
  
}
 
class Idol
{
  final String name;
  final List<String> members;
  
  // constructor
  const Idol({
    required this.name, 
    required this.members});
  
  // named constructor
  Idol.fromList(List values)
    : this.members = values[0], 
      this.name= values[1];
  
  // function
  void sayHello() {print('안녕하세요. ${this.name}입니다.');}
  
  void introduce() {print('저희 멤버는 ${this.members}가 있습니다.');}
  
  // getter, setter 굳이 사용 X, 기능적 차이 없음
}

클래스는 java와 똑같다.

  • 다만 클래스의 접근자가 private, public만 있다. 굉장히 마음에 든다.
  • private은 변수 앞에 (_)를 붙이면 된다. public은 안붙여도 됨.
  • getter, setter 굳이 사용해도 되지 않을 것 같다.

void main()
{
  Idol apink = Idol(name:'에이핑크', membersCount:5);
  
  apink.sayName();
  apink.sayMembersCount();
  
  print("--------------");
  
  BoyGroup bts = BoyGroup('BTS', 7);
  
  bts.sayMembersCount();
  bts.sayName();
}

class Idol{
  String name;
  int membersCount;
  
  Idol(
    {
      required this.name,
      required this.membersCount
    });
  
  void sayName() { print('저는 ${this.name}입니다.'); }
  
  void sayMembersCount()
  { print('${this.name}은 ${this.membersCount}명의 멤버가 있습니다.');}
}

class BoyGroup extends Idol
{
  BoyGroup(
    String name,
    int membersCount
  ) 
  : super(name:name, 
          membersCount:membersCount);
  
}

상속도 java와 똑같다. override, implement도 똑같으니 굳이 안따라해보고 넘어 간다.

void main()
{
  Idol apink = Idol(name:'에이핑크', membersCount:5);
  
  apink.sayName();
  apink.sayMembersCount();
  
  print("--------------");
  
  BoyGroup bts = BoyGroup('BTS', 7);
  
  bts.sayMembersCount();
  bts.sayName();
}

class Idol{
  String name;
  int membersCount;
  
  Idol(
    {
      required this.name,
      required this.membersCount
    });
  
  void sayName() { print('저는 ${this.name}입니다.'); }
  
  void sayMembersCount()
  { print('${this.name}은 ${this.membersCount}명의 멤버가 있습니다.');}
}

class BoyGroup extends Idol
{
  BoyGroup(
    String name,
    int membersCount
  ) 
  : super(name:name, 
          membersCount:membersCount);
  
}

 

Static

Class 귀속, Instance 귀속.

void main()
{
  Employee seulgi = Employee('슬기');
  Employee chorong = Employee('초롱');
  
  // instance 귀속
  seulgi.printNameAndBuilding();
  chorong.printNameAndBuilding();
  print("--------------------------");
  // class 귀속 : static
  Employee.building = '모르는';
  seulgi.printNameAndBuilding();
  chorong.printNameAndBuilding();
  Employee.printBuilding();
}

class Employee
{
  static String? building;
  final String name; 
  
  Employee(this.name);
  
  void printNameAndBuilding()
  {
    print('제 이름은 $name입니다. $building 건물에서 근무하고 있습니다.');
  }
  
  static void printBuilding()
  {
    print('저는 $building 건물에서 근무 중입니다.'); 
  }
}

 

Generic

외부에서 타입을 받아서 사용할 수 있음.

void main()
{
  Lecture<String> lecture1 = Lecture('123', 'lecture1');
  lecture1.printIdType();
  
  Lecture<int> lecture2 = Lecture(123, 'lecture1');
  lecture2.printIdType();
  
}


class Lecture<T>
{
  final T id;
  final String name;
  
  Lecture(this.id, this.name);
  
  void printIdType() {print(id.runtimeType);}
}
 

 

728x90
반응형

'Flutter > Dart' 카테고리의 다른 글

Dart Study #1 기본 문법  (0) 2022.08.04
Dart Study #3 futures, async, await  (0) 2022.07.23

+ Recent posts