Actual width and height in modern browsers

Modern browsers (including IE9) provide naturalWidth and naturalHeight properties to IMG elements. These properties contain the actual, non-modified width and height of the image.

var nWidth = document.getElementById('example').naturalWidth;
var nHeight = document.getElementById('example').naturalHeight;

Actual width and height in IE8 and IE7

The naturalWidth and naturalHeight properties are not supported in IE8 or lower. The height and width property will give the apparent width and height after stylesheet and inline styles, inline width and height attributes, and the display property of the image and the image's parent elements have been applied. The simplest way to get the unmodified width and height is to create a new image element, and use its width and height property.

function getNatural (DOMelement) {
  var img = new Image();
  img.src = DOMelement.src;
  return {width: img.width, height: img.height};
}

var natural = getNatural(document.getElementById('example')),
  nWidth = natural.width,
  nHeight = natural.height;

jQuery naturalWidth() and naturalHeight()

Here is a short jQuery (any version) plugin that adds two methods: naturalWidth() and naturalHeight(). It uses branching to determine if naturalWidth and naturalHeight are supported by the browser. If supported, the method just becomes a getter for the naturalWidth or naturalHeight property. If not supported, the method creates a new unstyled image element and returns that element's actual width and height.

// adds .naturalWidth() and .naturalHeight() methods to jQuery
// for retreaving a normalized naturalWidth and naturalHeight.
(function($){
  var
  props = ['Width', 'Height'],
  prop;

  while (prop = props.pop()) {
  (function (natural, prop) {
    $.fn[natural] = (natural in new Image()) ? 
    function () {
    return this[0][natural];
    } : 
    function () {
    var 
    node = this[0],
    img,
    value;

    if (node.tagName.toLowerCase() === 'img') {
      img = new Image();
      img.src = node.src,
      value = img[prop];
    }
    return value;
    };
  }('natural' + prop, prop.toLowerCase()));
  }
}(jQuery));

// Example usage:
var nWidth = $('img#example').naturalWidth();
var nHeight = $('img#example').naturalHeight();

Hey,

Follow me on Twitter and Github, that's where I'm most active these days. I welcome email (), but I'm afraid I no longer have time to answer personal requests for help regarding my plugins or posts. Thanks!

 

출저 : http://www.jacklmoore.com/notes/naturalwidth-and-naturalheight-in-ie/,

'자바스크립트' 카테고리의 다른 글

promise 강의  (0) 2017.05.10

팩토리 패턴 (factory pattern)


팩토리 메소드 패턴 : 객체를 생성하기 위한 인터페이스를 정의하는데, 어떤 클래스의 인스턴스를

                                 만들지는 서브클래스에서 결정하게 만든다. 즉 팩토리 메소드 패턴을 이용하면

                                 클래스의 인스턴스를 만드는 일을 서브클래스에게 맡기는 것.


추상 팩토리 패턴 : 인터페이스를 이용하여 서로 연관된, 또는 의존하는 객체를 구상 클래스를 지정하지 않고도 생성.


new를 사용하는 것은 구상 클래스의 인스턴스를 만드는 것이다.

당연히! 인터페이스가 아닌 특정 구현을 사용하게 되어버리는 것.

일련의 구상 클래스들이 있을때는 어쩔수 없이 다음과 같은 코드를 만들어야 하는 경우가 있음.


 Duck duck;

 if ( type == picnic ) duck = new MallardDuck();

 else if ( type == hunting ) duck = new DecoyDuck();

 else if ( type == inBathTub) duck = new RubberDuck();


이런 코드가 있다는 것은, 뭔가 변경하거나 확장해야 할 때 코드를 다시 확인하고 추가 또는 제거해야 한다는 것을 의미함.


인터페이스에 맞춰서 코딩을 하면 시스템에서 일어날 수 있는 여러 변화를 이겨낼 수 있다. 왜냐하면..

다형성 덕분에 어떤 클래스든 특정 인터페이스만 구현하면 사용할수 있기 때문.

반대로. 구상 클래스를 많이 사용하면 새로운 구상 클래스가 추가될 때마다 코드를 고쳐야 하기때문에 많은 문제가 생길수 있다.

즉 변화에 대해 닫혀 있는 코드가 되어버리는 것.


디자인 원칙으로 봤을때 구상 클래스를 바탕으로 코딩을 하면 나중에 코드를 수정해야 할 가능성이 높아지고, 유연성이 떨어진다는걸 다시한번 확인했는데 그렇다면 회피할수 있는 방법은??

- 바뀔 수 있는 부분을 찾아내서 바뀌지 않는 부분하고 분리시켜야 한다는 원칙.




피자 가게를 운영하고 있고 피자가게 클래스를 만들어야 된다고 가정할때.



 Pizza orderPizza(String type) {

       Pizza pizza;


       if(type.equals("cheese")) pizza = new CheesePizza();

       else if(type.equals("greek")) pizza = new GreekPizza();

       else if(type.equals("pepperoni")) pizza = new PepperoniPizza();       


       pizza.prepare();

       pizza.bake();

       pizza.cut();

       pizza.box();

       return pizza;

 } 


굵게 표시된 부분이 매번 바뀌는 부분.. 글엄 객체 생성 부분을 캡슐화 해보자.

그리고 새로 만들 객체에는 팩토리(Factory) 라는 이름을 붙이기로 한다.


간단한 피자 팩토리를 만든다.


 public class SimplePizzaFactory {

public Pizza createPizza(String type){ //이런 경우에는 static메소드로 선언하는 경우가 종종 있음.

Pizza pizza = null;

if(pizza.equals("cheese")) pizza = new CheesePizza();

if(pizza.equals("pepper")) pizza = new PepperoniPizza();

if(pizza.equals("clam")) pizza = new ClamPizza();

if(pizza.equals("veggie")) pizza = new VeggiePizza();

return pizza;

}

 }



워밍업. 간단한 팩토리 (Simple Factory)

 

 public class PizzaStore{

SimplePizzaFactory simplePizzaFactory;

public PizzaStore(SimplePizzaFactory simplePizzaFactory) {

this.simplePizzaFactory = simplePizzaFactory;

}

public Pizza orderPizza(String type){

Pizza pizza;

pizza = simplePizzaFactory.createPizza(type);

pizza.prepare();

pizza.bake();

pizza.cut();

pizza.box();

return pizza;

}

 }


간단한 팩토리는 디자인 패턴이라고 할 수는 없다.

프로그래밍을 하는데 있어서 자주 쓰이는 관용구에 가깝다고 할 수 있다.





피자 가게가 사업이 확장되어 여러 지역별로 각각의 다른 스타일의 피자를 만들어 내야하는 문제가 생겼다.

모든 프랜차이즈 분점에서 PizzaStore 코드를 사용하여 진행을 한다.


간단한 팩토리를 사용한다면 ???

SimplePizzaFactory 를 빼고 세가지 서로 다른 팩토리 (NYPizzaFactory, ChicagoPizzaFactory, CalifornizPizzaFactory)를 만들어서 적용한다면?




 PizzaStore nyStore = new PizzaStore(new NYPizzaFactory());

 nyStore.order("cheese");

 

 PizzaStore chicagoStore = new PizzaStore(new ChicagoPizzafactory());

 chicagoStore.order("cheese");


이런식으로 구현을 해보니.. 각 팩토리를 가진 피자가게 체인점들이 서로의 구현방식이 달라지는 일이 발생할수도 있게 됬음. (PizzaStore이 각각 있다보니 굽는 방식이 달라진다거나 피자를 자르는 단계를 빼먹거나 하는..)




1. 팩토리 메소드 패턴


피자가게와 피자 제작 과정 전체를 하나로 묶어주는 프레임워크를 만들어야 된다는 결론!!

파자를 만드는 활동 자체는 전부 PizzaStore 클래스에 국한시키면서도 분점마다 고유의 스타일을 살리수 있는 방법은 ??



 public abstract class PizzaStore{

public Pizza orderPizza(String type){

Pizza pizza;

pizza = createPizza(type);

pizza.prepare();

pizza.bake();

pizza.cut();

pizza.box();

return pizza;

}

abstract Pizza createPizza(String type); //Pizza 인스턴스를 만드는 일은 팩토리 역할을 하는 메소드에서 맡아 처리

 }


이제 각 분점을 위한 지역별로 서브클래스를 만들어줘야 한다. 피자의 스타일은 각 서브클래스에서 결정.



이제 ChicagoPizzaStore, NYPizzaStore 에는구상 피자클래스를 분기해주는 각각의 createPizza 메소드가 있음.



 public class NYPizzaStore extends PizzaStore{

@Override

public Pizza createPizza(String type){

Pizza pizza = null;

if(type.equals("cheese")) pizza = new NYStyleCheesePizza();

if(type.equals("peper")) pizza = new NYStylePepperoniPizza();

if(type.equals("clam")) pizza = new NYStyleClamPizza();

if(type.equals("veggie")) pizza = new NYStyleVeggiePizza();

return pizza;

}

 } 



 public class ChicagoPizzaStore extends PizzaStore{

@Override

public Pizza createPizza(String type){

Pizza pizza = null;

if(type.equals("cheese")) pizza = new ChicagoStyleCheesePizza();

if(type.equals("peper")) pizza = new ChicagoStylePepperoniPizza();

if(type.equals("clam")) pizza = new ChicagoStyleClamPizza();

if(type.equals("veggie")) pizza = new ChicagoStyleVeggiePizza();

return pizza;

}

 } 




 public abstract class Pizza{
String name;
String dough;
String sauce;
ArrayList<String> toppings = new ArrayList<>();
public void prepare(){
System.out.println("Preparing : "+name);
System.out.println("Tossing dough...");
System.out.println("Adding source");
System.out.println("Adding toppings");
for (String topping : toppings) {
System.out.println("\ttopping : "+topping);
}
}
public void bake(){
System.out.println("Bake for 25 minutes at 350");
}
public void cut(){
System.out.println("Cutting the pizza into diagonal slices");
}
public void box(){
System.out.println("Place pizza in official PizzaStore box");
}
public String getname(){
return this.name;
}
 }


 public class NYStyleCheesePizza extends Pizza{

public NYStyleCheesePizza() {

this.name = "NY Style CheesePizza";

this.dough = "Thin Crust Dough";

this.sauce = "Marinara Sauce";

this.toppings.add("Grated Reggiano Cheese");

}

 }



 public class ChicagoStyleCheesePizza extends Pizza{

public ChicagoStyleCheesePizza() {

this.name = "Chicago Style CheesePizza";

this.dough = "Extra Thick Crust Dough";

this.sauce = "Plum Tomato Sauce";

this.toppings.add("Shredded mozzarella Cheese");

}

@Override

public void cut() {

System.out.println("Cutting the pizza into square slices");

}

 }

 


 public class PizzaTestDrive {

public static void main(String[] args) {

PizzaStore nyStore = new NYPizzaStore();

PizzaStore chicagoStore = new ChicagoPizzaStore();

Pizza nySytpePizza = nyStore.orderPizza("cheese");

System.out.println(nySytpePizza.getname());

System.out.println();

Pizza chicagoStypePizza = chicagoStore.orderPizza("cheese");

System.out.println(chicagoStypePizza.getname());

}

 } 



모든 팩토리 패턴에서는 객체 생성을 캡슐화 한다.

팩토리 메소드 패턴에서는 서브 클래스에서 어떤 클래스를 만들지를 결정하게 함으로써 객체 생성을 캡슐화 한다.



객체를 생산하는 생산자 클래스




제품을 생산하는 제품 클래스



위의 클래스 아이어 그램을 보면 생산을 담당하는 PizzaStore 추상 클래스에서 객체를 만들기 위한 메소드, 즉 팩토리 메소드를 위한 인터페이스를 제공한다는 것을 알수있다. PizzaStore에 구현되어 있는 다른 메소드 orderPizza 에서는 팩토리 메소드에 의해 생산된 제품을 가지고 필요한 작업을 처리한다. 하지만 실제 팩토리 메소드를 구현하고 제품(객체 인스턴스)을 만들어 내는 일은 서브클래스에서만 할수 있다.




이로써 구상 클래스에 대한 의존성을 줄이는 것이 좋다는 것은 이제 확실해졌다.

이런 내을 정리해  놓은 객체지향 디자인 원칙이 바로 의존성 뒤집기 원칙 (Dependency Inversion Principle) 이다.


디자인 원칙


추상화된 것에 의존하도록 만들어라. 구상 클래스에 의존하도록 만들지 않도록 한다.


왜 의존성 뒤집기 원칙이냐면...


PizzaStore -> NYStyleCheesePizza

PizzaStore -> ChicagoStypeCheesePizza

PizzaStore -> NYStyleVeggiePizza


이런식으로 의존이 되던 좋지않은 디자인이


PizzaStore -> Pizza

Pizza <- NYStyleCheesePizza

Pizza <- ChicagoStyleCheesePizza

Pizza <- NYStyleVeggiePizza


이런식으로 의존관계게 뒤집어지는 형상.


팩토리 메소드 패턴을 적용하고 나면 고수준 구성요소(PizzaStore)와 저수준 구성요소(NYStyleCheesePizza, ChicagoStylePizza, ..) 들이 모두 추상 클래스인 Pizza에 의존하게됨. (고수준 모듈과 저수준 모듈이 둘다 하나의 추상 클래스에 의존)

팩토리 메소드 패턴이 의존성 뒤집기 원칙을 준수하기 위해 쓸 수 있는 유일한 기법은 아니지만 가장 적합한 벙법 가운데 하나. 



의존성 뒤집기 원칙에 위배되는 객체지향 디자인을 피하는데 도움이 되는 가이드.


 1. 어떤 변수에도 구상 클래스에 대한 레퍼런스를 지정하지 않는다.

     - new 연산자를 사용하면 레퍼런스를 사용하게 되는 것.


 2. 구상 클래스에서 유도된 클래스를 만들지 않는다.

     - 구상클래스에서 유도된 클래스를 만들면 특정 구상 클래스에 의존하게됨, 추상화 된것을 사용해야 함.


 3. 베이스 클래스에 이미 구현되어 있던 메소드를 오버라이드 하지 않는다.

     - 이미 구현되어 있는 메소드를 오버라이드 한다는 것은 애초부터 베이스 클래스가 제대로 추상화 된것이 아니었다고

        볼수있다. 베이스 클래스에서 메소드를 정의할 때는 모든 서브 클래스에서 공유할 수 있는 것만 정의해야함.



위의 가이드 라인은 다른 원칙들과 마찬가지로 항상 지켜야 하는 규칙이 아니라. 지향해야하는 바를 밝히는 것.

String 인스턴스는 사실 별생각 없이 쓰는데 엄밀히 말하자면 이것도 원칙에 위배되는 것이지만 별문제가 되지않는다. 왜냐하면 String 클래스가 바뀌는 일의 거의 없을테니까. 하지만 자신이 만들고 있는 클래스가 바뀔 가능성이 있다면 팩토리 메소드 패턴 같은 기법을 써서 변경될 수 있는 부분을 캡슐화 하여야 한다.



이렇게 PizzaStore 디자인이 모양새를 갖췄다. 유연한 프레임워크도 만들어 졌고, 디자인 원칙도 충실하게 지켰다.

각각 체인점들이 미리 정해놓은 절차를 잘 따르고 있지만 몇몇 체인점들이 자잘한 재료를 더 싼 재료로 바꿔서 원가를 절감해 마진을 남기고 있다. 원재료의 품질까지 관리하는 방법이 있을까??

     - 원재료 군을 만들어 파악하자.

       제품에 들어가는 재료군(반죽, 소스, 치즈, 야채, 고기)은 같지만, 지역마다 재료의 구체적인 내용이 조금씩 다르다.



2. 추상 팩토리 패턴



원재료 공장을 만들어보자.


1. 지역별로 팩토리를 만들어 각 생성 메소드를 구현하는 PizzaingredientFactory 클래스를 만들어야 함.

2. ReggianoCheese, RedPeppers, ThickCrustDough와 같이 팩ㄴ토리에서 사용할 원재료 클래스들을 구현한다.

3. 만든 원재료 공장을 PizzaStore 코드에서 사용하도록 함으로써 모든 것을 하나로 묶어준다. 



 public interface PizzaIngredientFactory {

public Dough createDough();

public Sauce createSauce();

public Cheese createCheese();

public Veggies[] createVeggies();

public Pepperoni createPepperoni();

public Clams createClams();

 } 




 public class NYPizzaingredientFactory implements PizzaIngredientFactory{

@Override

public Dough createDough() {

return new ThinCrustdough();

}


@Override

public Sauce createSauce() {

return new MarinaraSauce();

}


@Override

public Cheese createCheese() {

return new ReggianoCheese();

}


@Override

public Veggies[] createVeggies() {

Veggies veggies[] = { new Farlic(), new Onion(), new Mushroom(), new RedPepper() };

return veggies;

}


@Override

public Pepperoni createPepperoni() {

return new SlicedPepperoni();

}


@Override

public Clams createClams() {

return new Freshclams();

}

 }



 public class ChicagoPizzaingredientFactory implements PizzaIngredientFactory{
@Override
public Dough createDough() {
return new ThickCrustDough();
}

@Override
public Sauce createSauce() {
return new PlumTomatoSauce();
}

@Override
public Cheese createCheese() {
return new MozzarellaCheese();
}

@Override
public Veggies[] createVeggies() {
Veggies veggies[] = { new BlackOlives(), new Spinach(), new EggPlant()};
return veggies;
}

@Override
public Pepperoni createPepperoni() {
return new Slicedpepperoni();
}

@Override
public Clams createClams() {
return new FrozenClam();
}
 }
 

 public abstract class Pizza{
String name;
Dough dough;
Sauce sauce;
Veggies veggies[];
Cheese cheese;
Pepperoni pepperoni;
Clams clams;
public abstract void prepare(); //추상 메소드로 변경됨.
public void bake(){
System.out.println("Bake for 25 minutes at 350");
}
public void cut(){
System.out.println("Cutting the pizza into diagonal slices");
}
public void box(){
System.out.println("Place pizza in official PizzaStore box");
}
public String getname(){
return this.name;
}
 } 



 


 public class CheesePizza extends Pizza{

PizzaIngredientFactory ingredientFactory;

public CheesePizza(PizzaIngredientFactory ingredientFactory) {

this.ingredientFactory = ingredientFactory;

}


@Override

public void prepare() {

this.dough = ingredientFactory.createDough();

this.sauce = ingredientFactory.createSauce();

this.cheese = ingredientFactory.createCheese();

}

 } 




 public class ClamPizza extends Pizza{

PizzaIngredientFactory ingredientFactory;

public ClamPizza(PizzaIngredientFactory ingredientFactory) {

this.ingredientFactory = ingredientFactory;

}


@Override

public void prepare() {

this.dough = ingredientFactory.createDough();

this.sauce = ingredientFactory.createSauce();

this.cheese = ingredientFactory.createCheese();

this.clams = ingredientFactory.createClams();

}

 }



 public class NYPizzaStore extends PizzaStore{

@Override

public Pizza createPizza(String type){

Pizza pizza = null;

PizzaIngredientFactory ingredientFactory = new NYPizzaingredientFactory();

if(type.equals("cheese")){

pizza = new CheesePizza(ingredientFactory);

pizza.setName(ingredientFactory.NY_STYLE+" Cheese Pizza");

}else if(type.equals("peper")){

pizza = new PepperoniPizza(ingredientFactory);

pizza.setName(ingredientFactory.NY_STYLE+" Pepperoni Pizza");

}else if(type.equals("clam")){

pizza = new ClamPizza(ingredientFactory);

pizza.setName(ingredientFactory.NY_STYLE+" Clam Pizza");

}else if(type.equals("veggie")){

pizza = new VeggiePizza(ingredientFactory);

pizza.setName(ingredientFactory.NY_STYLE+" Veggie Pizza");

}

return pizza;

}

 } 






이제 전체적인 흐름은.


1. 뉴욕 피자가게를 만든다.

     - PizzaStore nyPizzaStore = new NYPizzaStore();


2. 주문을 한다.

     - nyPizzaStore.orderPizza("cheese");


3. orderPizza 메소드에서는 우선 createPizza() 메소드를 호출한다

     - Pizza pizza = createPizza("cheese");


4. createPizza() 메소드가 호출되면 원재료 공장이 돌아가기 시작한다.

     - Pizza pizza = new CheesePizza(nyIngredientFactory);


5. 피자를 준비하는 prepare()메소드가 호출되면 팩토리에 원재료 주문이 들어간다.

     - void prepare(){

            dough = nyIngredientFactory.createDough();

            sauce = nyIngredientFactory.createSauce();

            cheese = nyIngredientFactory.createCheese();

       }


6. 준비단계가 끝나고 orderPizza() 메소드에서는 피자를 굽고, 자르고, 포장한다.





다시 한번 정리를 해보면..



 추상 팩토리 패턴 : 제품군을 생성하기 위한 인터페이스를 생성 그 인터페이스를 구성하여 사용할수 있게끔 하는것.


 추상 메소드 패턴 : 하나의 추상클래스에서 추상 메소드를 만들고 서브클래스들이

                          그 추상메소드를 구현하여 인스턴스를 만들게끔 하는것.



출처: http://jusungpark.tistory.com/14 [정리정리정리]

apache configure 시 (특히 2.4 버전 이상을 설치 할 경우)


configure: error: APR not found.  Please read the documentation


와 같은 오류 메시지가 나오면


yum install apr apr-devel apr-util


와 같이 apr 관련 util 을 설치 해 줌으로서 해결해 준다. 


(밑에서 다루겠지만 pcre 라는 것도 설치 해 줘야 한다.)


yum 을 쓸 수 없는 경우


http://apr.apache.org/download.cgi


에 접속 하여 apr 과 apr-util 을 1.4 이상의 버전을 download 받아서 설치하길 바란다


나의 경우 두 개 다 1.5.1 버전을 download 받아 설치 하였다.


tar xvfz apr-1.5.1.tar.gz

cd apr-1.5.1

./configure --prefix=/usr/local/apr

make

make install


apr configure 시 나의 경우 (Cent OS)


rm: cannot remove ‘libtoolT’: No such file or directory


와 같은 오류 메시지가 나왔는데 이럴 경우


cp -arp libtool libtoolT


와 같이 해결해 줄 수 있다.



tar xvfz apr-util-1.5.1.tar.gz

cd apr-util-1.5.1

./configure --with-apr=/usr/local/apr --prefix=/usr/local/apr-util

make

make install


와 같이 설치 해 주면 된다.


또한 pcre 라는 것도 설치를 해줘야 한다는데 이것은 perl 의 정규식 표현관련된


lib 라고 한다.


http://pcre.org 에 가서 download 받도록 하자


여기서 주의 할 점은 아마도 apache2.4.X 대 버전이라면 pcre2 가 아니라


그냥 pcre 쪽을 다운로드 받아야 한다는 점이다


내가 다운 받은 버전은 pcre-8.36 버전이다.


tar xvfz pcre-8.36.tar.gz


cd pcre-8.36

./configure --prefix=/usr/local/pcre

make

make install


이렇게 설치를 하였다


그리고 apache 설치의 경우


./configure --prefix=/usr/local/apache2.4 \

--enable-module=so \

--enable-rewrite \

--enable-so

--with-apr=/usr/local/apr \

--with-apr-util=/usr/local/apr-util \

--with-pcre=/usr/local/pcre

--enable-mods-shared=all


make


make install


이렇게 설치 하였다.


출저 : http://shonm.tistory.com/564 by 정윤재


♧ 공유 라이브러리 의존관계란,

실행 파일 또는 공유 라이브러리에서 필요로 하는 공유 라이브러리의 SONAME이

ELF 정보 내의 동적 섹션에 있는 NEEDED에 기록된 정보로 관리되고 있음을 의미한다.

▷ 개별 파일 내의 NEEDED는 objdump 또는 readelf를 사용해서 확인할 수 있지만,

의존관계를 이루고 있는 모든 공유 라이브러리를 출력하려면 ldd명령을 이용한다.

▷ ldd 명령은 내부적으로 환경변수 LD_TRACE_LOADED_OBJECTS를 이용해 구현되어 있다.

   

   

[ objdump 와 readelf로 공유 라이브러리 의존 관계 확인 ]

♧ 공유 라이브러리를 이용할 때, 실행 파일 또는 공유 라이브러리 자체는

이를 실행 하려 할 때 필요한 공유 라이브러리에 대한 정보를 갖고 있다.

▷ 그 정보는 ELF 동적 섹션의 NEEDED에 기록.

   

▶ [/bin/ls]를 objdump/readelf 명령을 사용하여 확인

objdump -p ::

   

readelf -d ::

▷ 이와 같이 /bin/ls는 [librt.so.1, libselinux.so.1, libacl.so.1, libc.so.6]

4개의 공유 라이브러리를 필요로 함.

▷ 그러나 /bin/ls 실행할 때 이 4개의 공유 라이브러리만 필요한 것은 아니다.

(4개의 공유 라이브러리는 각각의 또 다른 공유 라이브러리를 필요로 하기 때문.)

   

NEEDED로 표시되 어 있는 것은 SONAME이므로, SONAME으로부터 실제 파일을 찾아야 한다.

▷ 특히 설정되어 있지 않은 경우에는

/usr/lib(또는 /lib)에 SONAME에 해당하는 파일이 공유 라이브러리다.

(실제로는 /lib/tls 또는 /lib/tls/i686/cmov 등에 있는 공유 라이브러리가 사용 되기도 함)

▷ 환경변수 LD_LIBRARY_PATH에 라이브러리 경로를 설정한 경우 해당 디렉토리를 참조.

/etc/ld.so.cache에 기록 정보를 참조.

(/etc/ld.so.conf의 설정을 이용해 ldconfig를 실행할 때 갱신)

▷ 예를 들어 [ librt.so.1 ]의 경우, /lib/librt.so.1이라는 파일(심볼릭 링크)이 존재하므로,

이것이 SONAME librt.so.1에 해당하는 공유 라이브러리 파일이다.

   

▶ [ librt.so.1 ]이 필요로 하는 라이브러리 확인.

...(중략)...

   

▶ [ /bin/ls ]의 다른 공유 라이브러리도 의존 관계를 확인.

(※ 공유 라이브러리 의존관계는 CPU종류, OS 배포판에 따라 조금씩 다르다.)

   

   

[ ldd로 공유 라이브러리 의존 관계 확인 ]

♧ 앞에서 살펴본 바와 같이 objdump / readelf를 사용해 공유 라이브러리 의존 관계를 확인할 수는

있지만, 각각의 공유 라이브러리에 대한 의존관계를 개별적으로 확인해야 하므로 다소 번거롭다.

또한 실제 실행될 때 사용되는 공유 라이브러리의 디렉토리 경로를 정확히 얻기도 어렵다.

 

▶ ldd로 공유 라이브러리 의존 관계 확인.

(※ ldd는 실행 파일 외에도 공유 라이브러리에도 사용 가능)

- 이와 같이 실행파일이 필요로 하는 공유 라이브러리의 SONAME, 경로명과 할당된 메모리 주소를 확인.

 

▷ 사실 GNU/리눅스에서 ldd 명령은 단순히

환경변수(LD_TRACE_LOADED_OBJECTS)를 이용한 셸 스크립트이다.

▷ LD_TRACE_LOADED_OBJECTS에 1을 설정해서 프로그램을 실행하면 프로그램 실행 시점에

ELF 인터프리터(런타임 로더 /lib/ld_linux.so.2)가 필요한 공유 라이브러리를 찾아

메모리에 로딩해서 그 정보를 표시한 후, 실제 프로그램이 실행되기 전에 종료하게 된다.

 

▶ LD_TRACE_LOADED_OBJECTS를 이용한 공유 라이브러리 의존성 확인.

- 이와 같이 ldd와 동일한 결과를 얻을 수 있다.

   

▷ LD_TRACE_LOADED_OBJECTS는 실행 파일이 아닌 공유 라이브러리에의 경우 실행할 수 없다.

   

▷ 이런 경우에는 런타임 로드 /lib/ld-linux.so.2를 실행한다.

  



출저 : 컴퓨터 서적 정리/Binary Hacks / http://devanix.tistory.com/185


'리눅스 명령어' 카테고리의 다른 글

특정 파일내 문자열 치환 2  (0) 2016.10.13
파일 내 특정 문자열 검색과 치환  (0) 2016.10.13

방어적 프로그래밍 (Defensive Programming)

앞선 학습에서 프로그래밍의 기본적인 도구를 소개했다. 변수와 리스트, 파일 입력출력(I/O), 루프, 조건문, 그리고 함수. 아직 수행하지 않은 것은 프로그램이 정답을 얻었는지를 어떻게 보여주고 프로그램을 변경하고 수정하면서 여전히 정답을 얻고있는지를 보여주는 것이다.

이를 달성하기 위해서, 다음이 필요하다.

  • 자신의 연산을 확인하는 프로그램을 작성한다.
  • 널리 사용되는 함수에 대한 테스트를 작성하고 수행한다.
  • "정답"이라는 것이 실제로 무엇을 의미하는지 알고 있어야 한다.

좋은 소식은 이런 것들을 수행하는 것은 프로그래밍의 속도를 늦추지 않고 가속화한다. 실제 목공에서 나무를 자르기 전에 주의깊게 측정해서 절약되는 시간이 측정하는데 걸리는 시간보다 훨씬 크다.

목표

  • 가정 설정문(assertion)이 무엇인지 설명한다.
  • 프로그램의 상태를 올바르게 확인하는 가정 설정문(assertion)을 프로그램에 추가한다.
  • 함수에 전제조건과 사후조건 가정 설정문(assertion)에 올바르게 추가한다.
  • 테스트 주도 개발(test-driven development)가 무엇인지 설명하고, 새로운 함수를 생성할 때 사용한다.
  • 왜 변수를 초기화하는데 임의의 상수보다 실제 데이터를 사용하는지 설명한다.
  • 체계적으로 오류를 포함하는 코드를 디버그한다.

가정 설정문 (Assertions)

프로그램에서 정답을 얻는 첫번째 단계는 실수는 일어난다고 가정하고 이에 대비하여 방지하는 것이다. 이것을 방어적 프로그래밍(defensive programming)이라고 부르고, 가장 일반적인 방식은 코드에 가정 설정문(assertions)을 추가해서 실행시에 점검한다. 가정 설정문은 단순하게 프로그램의 특정 지점에서 항상 참이어야 하는 문장이다. 파이썬이 가정 설정문을 만나게 될 때, 가정 설정문의 조건을 확인한다. 만약 참이면, 파이썬은 아무것도 하지 않는다. 하지만 거짓이면, 파이썬은 즉시 프로그램을 정지시키고 마련된 오류 메시지를 출력한다. 예를 들어, 루프가 양수가 아닌 값을 마주치자 마자 바로 이 코드 부분이 정지한다.

numbers = [1.5, 2.3, 0.7, -0.001, 4.4]
total = 0.0
for n in numbers:
    assert n >= 0.0, 'Data should only contain positive values'
    total += n
print 'total is:', total
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-19-33d87ea29ae4> in <module>()
      2 total = 0.0
      3 for n in numbers:
----> 4     assert n >= 0.0, 'Data should only contain positive values'
      5     total += n
      6 print 'total is:', total

AssertionError: Data should only contain positive values

파이어 폭스 웹브라우져 같은 프로그램은 가정 설정문(assertion)으로 가득차 있다. 코드의 10-20%는 다른 80-90%의 코드가 올바르게 동작하는지 확인하기 위해서 존재한다. 대체로 가정 설정문은 다음 3개 범주안에 들어간다.

예를 들어, 4개의 좌표 (x0, y0, x1, y1)로 구성된 튜플을 사용하여 직사각형을 표현한다고 가정하자. 연산을 수행하기 위해서, 정사각형을 정규화해서 원점과 가장 긴 축을 따라 1.0 단위를 가진다. 함수가 정규화를 하지만 입력값이 올바른 형식인지 결과가 의미가 있는지 점검한다.

def normalize_rectangle(rect):
    '''Normalizes a rectangle so that it is at the origin and 1.0 units long on its longest axis.'''
    assert len(rect) == 4, 'Rectangles must contain 4 coordinates'
    x0, y0, x1, y1 = rect
    assert x0 < x1, 'Invalid X coordinates'
    assert y0 < y1, 'Invalid Y coordinates'
    
    dx = x1 - x0
    dy = y1 - y0
    if dx > dy:
        scaled = float(dx) / dy
        upper_x, upper_y = 1.0, scaled
    else:
        scaled = float(dx) / dy
        upper_x, upper_y = scaled, 1.0

    assert 0 < upper_x <= 1.0, 'Calculated upper X coordinate invalid'
    assert 0 < upper_y <= 1.0, 'Calculated upper Y coordinate invalid'

    return (0, 0, upper_x, upper_y)

주석을 제외한 2, 4, 5번 행의 사전 조건은 잘못된 입력을 잡아낸다.

print normalize_rectangle( (0.0, 1.0, 2.0) ) # missing the fourth coordinate
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-21-3a97b1dcab70> in <module>()
----> 1 print normalize_rectangle( (0.0, 1.0, 2.0) ) # missing the fourth coordinate

<ipython-input-20-408dc39f3915> in normalize_rectangle(rect)
      1 def normalize_rectangle(rect):
      2     '''Normalizes a rectangle so that it is at the origin and 1.0 units long on its longest axis.'''
----> 3     assert len(rect) == 4, 'Rectangles must contain 4 coordinates'
      4     x0, y0, x1, y1 = rect
      5     assert x0 < x1, 'Invalid X coordinates'

AssertionError: Rectangles must contain 4 coordinates
print normalize_rectangle( (4.0, 2.0, 1.0, 5.0) ) # X axis inverted
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-22-f05ae7878a45> in <module>()
----> 1 print normalize_rectangle( (4.0, 2.0, 1.0, 5.0) ) # X axis inverted

<ipython-input-20-408dc39f3915> in normalize_rectangle(rect)
      3     assert len(rect) == 4, 'Rectangles must contain 4 coordinates'
      4     x0, y0, x1, y1 = rect
----> 5     assert x0 < x1, 'Invalid X coordinates'
      6     assert y0 < y1, 'Invalid Y coordinates'
      7 

AssertionError: Invalid X coordinates

사후 조건은 계산 결과가 올바르지 않을 때 신호를 줌으로써 버그를 잡도록 도와준다. 예를 들어, 너비보다 더 큰 직사각형을 정규화한다면 모든 것이 OK 처럼 보인다.

print normalize_rectangle( (0.0, 0.0, 1.0, 5.0) )
(0, 0, 0.2, 1.0)

하지만, 높이보다 더 넓은 정사각형을 정규화한다면 사전 선언문이 자동으로 실행된다.

print normalize_rectangle( (0.0, 0.0, 5.0, 1.0) )
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-24-5f0ef7954aeb> in <module>()
----> 1 print normalize_rectangle( (0.0, 0.0, 5.0, 1.0) )

<ipython-input-20-408dc39f3915> in normalize_rectangle(rect)
     16 
     17     assert 0 < upper_x <= 1.0, 'Calculated upper X coordinate invalid'
---> 18     assert 0 < upper_y <= 1.0, 'Calculated upper Y coordinate invalid'
     19 
     20     return (0, 0, upper_x, upper_y)

AssertionError: Calculated upper Y coordinate invalid

작성한 함수를 다시 읽게되면, 10번째 행이 dx가 dy로 나누어지기 보다 dy가 dx로 나누어져야 한다. (Ctrl+M 그리고 L을 타이핑해서 행번호를 화면에 출력할 수 있다.) 만약 함수의 끝에 가정 설정문을 생략한다면, 유효한 답변으로 올바른 모양을 가진 무언가를 생성하고 반환해야할 것이지만 하지는 그렇게 하지는 않는다. 버그를 탐지하고 디버깅하는 것은 거의 항상 가정 설정문을 작성하는 것보다 장기적으로 더 많은 시간이 걸린다.

하지만 가정 설정문이 오류를 잡아내는 것만 하는 것은 아니고 사람들로 하여금 프로그램을 이해하는데 도움도 준다. 각각의 가정 설정문은 프로그램을 읽는 사람에게 코드가 동작하는 것과 프로그램을 이해하는 것이 매칭되는지 확인할 수 있는 기회의 장을 제공하기도 한다.

대부분의 좋은 프로그래머는 코드에 가정 설정문을 추가할 때 두가지 규칙을 따른다. 하나는 "미리 실패하고, 자주 실패하라(fail early, fail often)"는 것이다. 오류가 발생하는 시간과 장소와 인지하는 시점과 거리가 크면 클수록, 오류를 디버그하기가 더욱 어렵다. 그래서 좋은 코드는 가능한 이른 시점에 오류와 실수를 잡아낸다.

두번째 규칙은 "버그를 가정 설정문과 테스트로 변환하라(turn bugs into assertions or tests)"는 것이다. 만약 코드 일부분에 실수를 하게된다면, 근처에서 다른 실수를 하거나 다음번에 코드를 변경할 때 동일한 혹은 관련된 실수를 저지를 가능성이 높다. 여러분이 회귀(regressed)가 되지 않도록 (즉, 이전 문제를 다시 발생하지 않도록) 가정 설정문을 작성하는 것은 장기적으로 엄청난 시간을 절약할 수 있고 미래의 자신을 포함하여 까다로운 코드를 읽는 사람에게 경고를 주는데도 도움이 된다.

도전 과제

  1. 리스트 숫자의 평균을 계산하는 함수 average를 작성한다고 가정하자. 사전 조건과 사후 조건으로 함수 average에 대해 무엇을 작성할까요? 여러분이 작성한 것과 주위 동료의 것과 비교하세요. 여러분의 테스트를 통과했으나 동료의 테스트는 통과하지 못한 혹은 반대 경우의 함수를 생각할 수 있나요?

  2. 코드에 사전 설정문이 확인하는 것이 무엇인지 일상적인 말로 설명하세요. 그리고, 각각에 대해서 사전 설정문이 실패하게 되는 입력값의 예를 주세요.

~~~python def running(values): assert len(values) > 0 result = [values[0]] for v in values[1:]: assert result[-1] >= 0 result.append(result[-1] + v) assert result[-1] >= result[0] return result ~~~

테스트 주도 개발 (Test-Driven Development)

가정 설정문은 프로그램의 특정한 지점에서 무엇인가 참인지 확인하는데 도움이 된다. 다음 단계는 코드 일부분의 전반적인 동작을 확인하는 것이다. 즉, 특정한 입력값이 주어졌을 때, 올바른 출력값을 만들어 내는지 확인한다. 예를 들어, 두개 혹은 그 이상의 시계열이 중첩되는지 발견할 필요가 있다고 가정하자. 각 시계열의 범위는 숫자 짝으로 표현되고 시작과 끝을 표현하는 시간 간격이 있다. 출력값은 모든 시간을 포함하는 가장 큰 범위다.

Overlapping Ranges

대부분의 초보 프로그래머는 상기 문제를 다음과 같이 푼다.

  1. range_overlap 함수를 작성한다.
  2. 두개 혹은 3개의 입력값에 대해서 함수를 인터랙티브하게 호출한다.
  3. 만약 함수가 잘못된 대답을 준다면, 함수의 잘못된 것을 고치고 다시 테스트를 시행한다.

명확하게 이 방식은 동작하지만 더 좋은 방식이 있다. (수천명의 과학자가 지금 이와 같이 작업을 하고 있다.)

  1. 각 테스트에 대해서 짧은 함수를 작성한다.
  2. 상기 테스트를 통한 range_overlap 함수를 작성한다.
  3. 만약 함수 range_overlap가 잘못된 대답을 준다면, 함수의 잘못된 것을 고치고 다시 테스트를 시행한다.

함수를 작성하기 전에 테스트를 작성하는 것을 테스트 주도 개발(test-driven development) (TDD)라고 한다. TDD 지지하시는 분들은 이 방식이 더 빠르게 더 좋은 코드를 만들어낸다고 믿고 있다. 왜냐 하면,

  1. 만약 테스트 대상 코드를 작성한 후에 테스트를 작성하게 된다면, 확증 편향(confirmation bias)에 빠지기 쉽다. 즉, 무의식적으로 오류를 발견하기봐 작성한 코드가 옳다는 것을 증명하기 위한 테스트를 작성한다.
  2. 테스트를 작성하는 것은 프로그래머가 함수가 실질적으로 무엇을 수행해야 하는지에 대해 파악하는데 도움을 준다.

range_overlap에 대한 3개의 테스트 함수가 있다.

assert range_overlap([ (0.0, 1.0) ]) == (0.0, 1.0)
assert range_overlap([ (2.0, 3.0), (2.0, 4.0) ]) == (2.0, 3.0)
assert range_overlap([ (0.0, 1.0), (0.0, 2.0), (-1.0, 1.0) ]) == (0.0, 1.0)
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-25-d8be150fbef6> in <module>()
      1 assert range_overlap([ (0.0, 1.0) ]) == (0.0, 1.0)
----> 2 assert range_overlap([ (2.0, 3.0), (2.0, 4.0) ]) == (2.0, 3.0)
      3 assert range_overlap([ (0.0, 1.0), (0.0, 2.0), (-1.0, 1.0) ]) == (0.0, 1.0)

AssertionError: 

오류는 사실 안심을 준다. 아직 range_overlap을 작성하지는 않아서 만약 테스트가 통과된다면, 누군가 함수를 작성했고, 우연히 여러분이 함수를 사용한다는 표시다.

테스트를 작성하는 것에 대한 보너스로 암묵적으로 입력과 출력이 무엇인지 정의한다는 것이다. 쌍으로 구성된 여러 리스트를 입력받아 하나의 리스트로 출력하는 것이다.

하지만 중요한 것이 빠졌다. 범위가 전혀 중첩되지 않는 경우에 대해서 어떠한 테스트도 준비하지 않았다.

assert range_overlap([ (0.0, 1.0), (5.0, 6.0) ]) == ???

상기 경우에 range_overlap은 무엇을 해야할까? 오류 메시지 실패로 종료, 중첩되지 않는다는 신호로 (0.0, 0.0) 같은 값을 출력, 혹은 다른 어떤 것을 수행. 함수를 실제로 구현할 때 여러 경우의 수 중에서 하나를 작성한다. 이슈가 있다는 것을 알아차리기 이전에 감정적으로 무언가 작성하는데 투자를 일으키기 전에 먼저 테스트를 작성하는 것은 무엇이 가장 최선이지 파악하는데 도움을 준다.

다음 사례의 경우는 어떻게 처리할까?

assert range_overlap([ (0.0, 1.0), (1.0, 2.0) ]) == ???

끝점을 맞대고 있는 두 부분은 중첩된 것인가 아닌가? 수학자는 대체로 "예 맞습니다"라고 하지만, 공학자는 대체로 "아닙니다"라고 말한다. 최선의 답은 "프로그램의 나머지 부분에서 무엇이든지 가장 유용한 것이 될 것이다". 하지만, 다시 한번 range_overlap의 실제 구현은 무언가 수행하는 것이고, 구현이 무엇이든지 관계없이 전혀 중첩되는 것이 없을 때 수행되는 것과 일관성이 있어야 한다.

시계열 차트에서 X축으로 함수는 반환하는 범위를 사용하려고 계획하고 있기 때문에, 다음과 같이 결정한다.

  1. 모든 중첩은 0 이 아닌 너비를 가져야 한다.
  2. 중첩되는 것이 없을 때, 특수값 None 을 반환한다.

None은 파이썬에 내장되어져 있고, "여기에 아무것도 없어요(nothing here)"를 의미한다. 다른 언어는 종종 상응하는 값으로 null 혹은 nil 이라고 한다. 상기 결정 사항을 가지고, 마지막 두 테스트 작성을 마칠 수 있다.

assert range_overlap([ (0.0, 1.0), (5.0, 6.0) ]) == None
assert range_overlap([ (0.0, 1.0), (1.0, 2.0) ]) == None
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-26-d877ef460ba2> in <module>()
----> 1 assert range_overlap([ (0.0, 1.0), (5.0, 6.0) ]) == None
      2 assert range_overlap([ (0.0, 1.0), (1.0, 2.0) ]) == None

AssertionError: 

다시, 함수를 작성하지 않아서 오류가 생겼다. 하지만 이제 함수를 작성할 준비가 되었다.

def range_overlap(ranges):
    '''Return common overlap among a set of [low, high] ranges.'''
    lowest = 0.0
    highest = 1.0
    for (low, high) in ranges:
        lowest = max(lowest, low)
        highest = min(highest, high)
    return (lowest, highest)

(잠시 시간을 가지고 왜 lowest에 max를 사용하고, highest에 min을 사용하는지 생각해보자. 테스트를 다시 실행하고자 하지만, 3개의 다른 셀에 여기저기 분산되어 있다 테스트를 좀더 쉽게 실행하도록 함수에 테스트 케이스를 모두 모아 놓자.

def test_range_overlap():
    assert range_overlap([ (0.0, 1.0), (5.0, 6.0) ]) == None
    assert range_overlap([ (0.0, 1.0), (1.0, 2.0) ]) == None
    assert range_overlap([ (0.0, 1.0) ]) == (0.0, 1.0)
    assert range_overlap([ (2.0, 3.0), (2.0, 4.0) ]) == (2.0, 3.0)
    assert range_overlap([ (0.0, 1.0), (0.0, 2.0), (-1.0, 1.0) ]) == (0.0, 1.0)

하나의 함수 호출로 range_overlap을 이제는 테스트할 수 있다.

test_range_overlap()
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-29-cf9215c96457> in <module>()
----> 1 test_range_overlap()

<ipython-input-28-5d4cd6fd41d9> in test_range_overlap()
      1 def test_range_overlap():
----> 2     assert range_overlap([ (0.0, 1.0), (5.0, 6.0) ]) == None
      3     assert range_overlap([ (0.0, 1.0), (1.0, 2.0) ]) == None
      4     assert range_overlap([ (0.0, 1.0) ]) == (0.0, 1.0)
      5     assert range_overlap([ (2.0, 3.0), (2.0, 4.0) ]) == (2.0, 3.0)

AssertionError: 

None을 만들어내야 하는 첫번째 테스트는 실패해서, 작성한 함수에 뭔가 잘못된 것을 알게된다. 알지 못하는 것은 다른 4개의 테스트가 통과되었는지 실패했는지다. 왜냐하면 파이썬은 첫번째 오류를 탐지하지마자 프로그램을 정지한다. 여전히 약간의 정보가 없는 것보다는 낫다. 만약 그 입력값으로 함수의 동작을 추적하면 초기값을 입력값에 관계없이 lowest를 0.0 highest를 1.0 으로 각각 초기 설정함을 알게된다. 이것은 또 다른 중요한 프로그래밍 규칙("항상 데이터로 초기화하라(always initialize from data)")을 위반하게 된다. 함수 range_overlap 을 고치는 것은 연습으로 남겨둔다.

도전 과제

  1. range_overlap을 고치시오. 변경을 한 후에 test_range_overlap을 다시 실행하세요.

디버깅 (Debugging)

테스팅을 통해서 문제를 발견하게 되면, 다음 단계는 문제를 고치는 것이다. 많은 초보자는 올바른 답을 만드는 것처럼 보일 때까지 대체로 랜덤(random)하게 변경을 해서 문제를 해결한다. 하지만 이러한 접근법은 매우 비효율적이고 결과는 대체로 테스팅하고 있는 경우에 대해서만 적합하다. 프로그래머가 좀더 경험이 많을수록, 좀더 체계적으로 디버그한다. 대부분의 경험있는 프로그래머는 다음에 설명된 규칙과 변형을 따른다.

프로그램이 수행하게 되어 있는 것을 이해한다.

무언가를 디버깅하는 첫번째 단계는 프로그램이 수행하게 되어 있는 것을 이해(know what it's supposed to do)하는 것이다. "작성한 프로그램이 동작을 하지 않는다"는 충분하지 않다. 문제를 진단하고 고치기 위해서는 올바른 결과와 잘못된 결과를 구별할 필요가 있다. 만약 실패한 케이스에 대해서 테스트 케이스를 작성한다면 - 즉 이것을 입력으로 가정 설정한다면, 함수는 저것을 결과로 산출한다 - 그러면 디버깅을 시작할 준비가 되었다. 만약 이렇게 할수 없다면, 무엇인가 고칠 때 어떻게 고칠지에 대해서 파악할 필요가 있다.

하지만, 과학적 소프트웨어에 대해서 테스트 케이스를 작성하는 것은 상용 응용프로그램에 대한 테스트 케이스를 작성하는 것보다 종종 더 힘들다. 왜냐하면, 만약 과학적 소프트웨어 코드의 결과가 무엇이 되어야 하는지 알고 있다면, 소프트웨어를 실행하지 않아도 된다. 그래서 결과를 작성하고 다음 프로그램으로 옮겨간다. 실무에서 과학자들은 다음을 수행하는 경향이 있다.

  1. 단순화된 데이터로 테스트한다. 실제 데이터섹에 통계분석을 수행하기 전에, 하나의 레코드에 대해서, 두개의 동일한 레코드에 대해서, 두개의 레코드인데 한 단계가 차이가 나는, 혹은 수작업으로 정답을 계산할 수 있는 레코드에 한해서 통계를 계산한다.

  2. 단순화된 케이스를 테스트한다. 만약 프로그램이 매우 빨리 회전하는 작은 방울의 과냉각된 헬륨에 자기장 소용돌이를 모의실험하려고 한다면, 첫번째 테스트는 회전하지 않는 작은 방울 헬륨이여야 하고, 어떤 외부 전자기장에 영향을 받지 말아야 한다. 마찬가지로, 만약 어떤 종에 대한 기후변화의 효과를 살펴보려고 한다면, 첫번째 테스트는 온도, 습도, 그리고 다른 요소를 상수로 고정하여야 한다.

  3. 절대적인(oracle) 것과 비교한다. 테스트 오라클(test oracle)은 새로운 프로그램의 결과와 비교할 수 있는 무엇이다. 즉, 실험 데이터, 결과를 신뢰할 수 있는 이전 프로그램, 혹은 심지어 전문가도 될 수 있다. 만약 테스트 오라클이 있다면, 특별한 케이스에 대해서 출력 결과를 저장해서 프로그램을 다시 실행하지 않고 원하는만큼 자주 새로운 결과값과 비교한다.

  4. 보전 법칙을 확인하라. 질량, 에너지, 그리고 기타 양적 정보는 물리 시스템에서 보존된다. 프로그램에서도 또한 보존되어야 한다. 마찬가지로, 만약 환자 데이터를 분석한다면, 레코드 숫자는 같은 수가 유지되거나 다음 분석으로 옮겨가게 되면 줄어든다. (왜냐하면 결측값을 가진 레코드나 아웃라이어를 버려버리기 때문이다.) 만약, 파이프라인을 따라서 옮겨가다가 갑자기 "새로운" 환자가 값자기 나타난다면, 아마도 무언가 잘못되고 있다는 신호다.

  5. 시각화하라. 데이터 분석자는 종종 간단한 시각화를 사용하여 수행하고 있는 과학과 코드의 정합성에 대해서 점검한다. (파이썬 학습의 도입 학습과 마찬가지로). 하지만, 이 방법은 디버깅에 대해서 최후의 수단이 되어야 한다. 왜냐하면, 자동적으로 두개의 시각화 결과를 비교하는 것은 매우 어렵다.

매번 실패하게 만들기 (Make It Fail Every Time)

실패할 때만 무언가 디버그할 수 있다. 그래서 두번째 단계는 항상 매번 실패하게 만드는 테스트 케이스를 찾는 것이다. "매번(every time)"이 중요한데, 이유는 간헐적인 문제를 디버깅하는 것보다 더 좌절을 주는 것이 없기 때문이다. 만약 한번의 실패를 만들기 위해서 12번 함수를 호출해야 한다면, 실패가 실제로 일어났을 때로 스크롤하여 실패를 찾는 것이 확률적으로 높다.

이것과 관련해서, 코드가 "연결되어 있는지(plugged-in)" 확인하는 것이 중요하다. 즉, 실제로 우리가 생각하기에 문제인 것을 다룬다. 모든 프로그래머는 버그를 쫓아서 몇시간을 보내는데 단지 잘못된 데이터나 잘못된 환경설정 매개변수에 코드를 호출하거나 완전히 잘못된 소프트웨어 버젼을 사용한 것을 깨단기 위해서다. 이와 같은 실수는 특히 피곤할 때, 좌절했을 때, 마감시한에 임박했들 때 발생할 듯 하다. 이런 이유로 밤 늦게 혹은 밤새도록 코딩을 하는 것은 거의 가치없어서 지양해야된다.

빨리 실패하게 만들기 (Make It Fail Fast)

만약 버그가 표면에 나오는데 20분 걸린다면, 한시간에 3회 실험을 할 수 있다. 이것이 더 많은 시간에 더 적은 데이터를 갖는다는 것을 의미하지 말아야 한다. 프로그램이 실패하기를 기다리면서 다른 것에 의해서 산만하게 더 될 듯하다. 이것은 프로그래머가 문제에 사용하는 시간의 집중도가 떨어진다는 것을 의미한다. 그러므로 빨리 실패하게 만드는 것(Make It Fail Fast)이 매우 중요하다.

프로그램을 시간내에 빨리 실패하게 만드는 것 뿐만 아니라 공간적인 측면에서 프로그램을 빨리 실패하게 만들고 싶다. 즉, 가능하면 적은 코드 지역에 실패를 국지화하고자 한다.

  1. 원인과 결과 사이의 간격이 작으면 작을수록, 연결점을 발견하기는 더욱 쉽다. 그래서 많은 프로그래머는 버그를 찾기 위해서 분리 정복 전략(divide and conquer strategy)를 사용한다. 만약 함수의 출력이 잘못된다면, 중간에 있는 것이 OK 인지 점검하고 나서 앞쪽 혹은 뒤쪽에 점검하고 이를 반복한다.

  2. N개는 N2/2 다른 방식으로 상호작용한다. 그래서 테스트 부분으로 실행되지 않는 모든 코드 라인은 특별히 걱정할 필요가 없는 것 이상을 의미한다.

이유를 가지고 한번에 하나씩 변경하라.

임의의 코드 덩어리를 교체하는 것은 좋은 일을 하지 못할 것 같다. (결국, 처음에 잘못되면, 아마도 두번째 세번째도 잘못될 것이다.) 그래서 좋은 프로그래머는 이유를 가지고 한번에 하나씩 변경(change one thing at a time, for a reason)한다. 좋은 프로그래머는 좀더 정보를 수집(루프의 순서를 변경한다면 버그가 여전히 남아있을까?)하거나 고친 부분을 테스트(처리하기 전에 데이터를 정렬함으로써 버그를 없앨 수 있을까?)한다.

아무리 작을더라도 매번 변경을 할때마다, 즉시 테스트를 다시 돌려야한다. 왜냐하면 한번에 변경한 것이 더 많으면 많을수록, 무엇이 무엇에 (N2 상호작용) 대해서 책임이 있는지 알아내기가 더더욱 힘들다.

그리고 모든 테스트를 다시 실행하게 된다면, 코드를 수정한 절반이상은 버그를 생성 혹은 재생성하게된다. 그래서 모든 테스트를 다시 실행을 통해서 회귀(regressed)했는지 즉, 이전 문제를 다시 발생하게 했는지도 알 수 있다.

작업한 것을 기록하라.

훌륭한 과학자는 작업한 것을 기록한다. 그래서 작업한 것을 다시 재생성할 수 있고 동일한 실험을 반복하거나, 결과가 신통지 못한 것을 다시 실행하는데 시간을 낭비하지 않는다. 마찬가지로, 디버깅도 작업한 것을 기록(keep track of what we've done)하고 어떻게 잘 동작했는지도 기록할 때 가장 잘 된다. 만약 여러분이 다음과 같은 질문을 한다면, 왼쪽에서 오른쪽으로 코드 라인 홀수가 시스템 충돌을 일으켰는지? 오른쪽에서 왼쪽이 충돌을 일으켰는지? 코드라인 짝수를 사용하다가 발생했는지?,
컴퓨터에서 잠시 떨어져서, 숨을 깊이 들이 마시고, 좀더 체계적으로 일을 시작해야하는 시간이다.

시간이 흘러 도움을 요청할 때 기록은 특히 유용하다. 명확하게 했던 것을 설명할 때 사람들은 좀더 귀를 기울여 듣는다. 그리고 사람들이 필요로 하는 유용한 정보를 좀더 잘 전달할 수 있다.

버젼 제어 (version control) 재방문

버젼 제어 (version control)는 종종 디버깅 동안 이전 특정 상태로 소프트웨어를 다시 원복하는데 사용된다. 그리고 버그와 연관된 코드 최근 변경을 사항을 탐색하는데도 사용된다. 특히, 대부분의 버젼 제어 시스템은 blame 명령어가 있어서 특정한 코드 라인에 누가 마지막에 변경을 했는지도 확인할 수 있다.

겸손하라 (Be Humble)

그리고, 도움을 말하라. 만약 10분내로 버그를 발견할 수 없다면, 겸손(be humble)하게 도움을 요청하라. 문제를 크게 설명하는 것만으로도 종종 도움이 된다. 왜냐하면, 생각하는 것을 듣는 것만으로도 일관되지 못한 것과 숨겨진 가정을 발견하는데 도움이 된다.

도움을 요청하는 것은 또한 확증 편향(confirmation bias)을 줄여준다. 만약 복잡한 프로그램을 작성하는데 한시간을 썼다면, 잘 동작하길 원해서 동작하지 않는 이유를 찾기보다는 왜 동작해야 하는지에 대해서 계속 본인 스스로에게 최면을 건다. 코드에 감정적으로 투자를 하지 않은 사람은 좀더 객관적일 수 있다. 이것이 왜 외부 사람이 간과한 간단한 실수를 종종 탐지하는 이유다.

겸손의 일부는 실수로부터 배우는 것이다. 프로그래머는 동일한 것을 반복해서 잘못하는 경향이 있다. 작업하는 언어와 라이브러리를 이해하지 못하거나, 프로그램이 어떻게 동작하는지에 대한 모델이 잘못된 것도 이유다. 어느 경우에나 왜 오류가 발생했는지 메모를 해두어 다음번에 점검하는 것이 실수를 다시 하지 않게 돌리는 빠른 방법이다.

그리고 이러한 방법이 장기적으로 좀더 생산적으로 여러분을 만든다. 외국 속담에 "한주의 노력은 한 시간의 생각을 절약해준다(A week of hard work can sometimes save you an hour of thought(는 말이 있다. 어떤 유형의 실수를 피하도록, 코드를 모듈화하고, 테스트할 수 있는 덩어리로 만들고, 모든 가정(혹은 실수)을 가정 설정문(assertion)으로 만든다면, 더 많이 만들지는 못하지만 동작하는 프로그램을 만드는데 더 적은 시간이 걸릴 것이다.

주요점

  • 방어적으로 프로그램하라. 즉, 오류가 발생한다고 가정하고 오류가 발생할 때 오류를 탐지하도록 코드를 작성하다.
  • 프로그램에 가정 설정문을 넣어서 프로그램이 실행될 때 상태를 점검하게 하라. 그리고 프로그램을 읽는 사람이 작성한 프로그램이 어떻게 동작을 하는 것인지 이해할 수 있도록 도움을 줘라.
  • 사전 조건을 사용해서 함수 입력값을 사용해도 안전한지 점검하라.
  • 사후 조건을 사용해서 함수 출력값을 사용해도 안전한지 점검하라.
  • 코드를 작성하기 전에 테스트를 작성해서 정확하게 코드가 무엇을 수행해야되는지 결정하도록 하라.
  • 코드를 디버그하기 전에 코드가 무엇을 수행해야하는지 파악하라.
  • 매번 실패하게 만들어라.
  • 빨리 실패하게 만들어라.
  • 이유를 가지고 한번에 하나씩 변경하라.
  • 작업한 것을 기록하라.
  • 겸손하라.

다음 단계

IPython Notebook으로 파이썬 코드를 작성하고 테스트하는 기초를 학습했다. 학습할 필요가 있는 마지막 것은 파이프라인과 쉘 스크립트에서 사용할 수 있는 명령-라인 프로그램을 어떻게 작성하는 것이다. 그렇게 함으로써 다른 사람이 작업한 것을 여러분의 도구와 통합할 수 있다. 이것이 다음 학습의 주제이며 마지막 학습이다.



출저 : [http://statkclee.github.io/xwmooc-sc/novice/python/05-defensive.html]



구성도의 그림은 개념도이며, 이렇게 개념을 세우고 설계를 시작한다.

백본과 백본스위치는 의미상 같다고 볼수 있다.

백본스위치는 네트워크의 중심이므로 라우터는 아니고, 허브도 아니고, 주로 L3 스위치가 그런 역할을 한다.

그러나, 꼭 L3스위치가 백본스위치는 아니다.

백본과 백본스위치는 네트워크의 중심에 있으며, 모든 데이타가 거쳐서 지나가는 곳이기 때문에, 스위치를 선으로 표시하는 경향이 있다.

라우터도 전에는 백본역활을 하였는데, 현재는 거의 하지 않는다. 이유는 L3 스위치 때문이다. 처리속도도 빠르고, 데이터 변환(LAN -> WAN사용시)을 할 필요가 없기 때문이다.

개념도상의 네트워크 구조는,
맨 상위에 라우터,
그 다음에 백본스위치(주로 L3스위치)에 각종 허브나 L2스위치를 연결, 또는 서버도 연결한다.
그다음이 각종 허브나 L2스위치가 위치한다.
맨마지막이 PC, 프린터 등과 같은 단말이다.

 

01.gif

네트워크 구조 개념도

 

백본스위치
백본이란 WAN으로 연결되기 위한 하나의 노드 또는 여러 노드들의 중심이다. 한 네트워크에서 중심에 위치하며 모든 패킷이 지나간다. 이와 같은 역할을 하는 장비를 백본스위치라 한다.
백본스위치는 많은 트래픽을 처리해야 하므로 기가급 장비를 많이 사용한다.

 

02.png

 

 

이중화
백본 스위치는 방화벽, 웍그룹 스위치 및 각종 서버가 접속되는 핵심 영역이므로 고가용, 고성능, 고확장성이 확보되는 기가급 백본 스위치를 도입하여 병목 구간의 대규모 트래픽을 처리할 수 있도록 구성한다. 또한 백본 스위치 이중화하여 안정성을 확보하여 무 중단 시스템 구축한다.

HSRP 프로토콜을 사용하여 장비 이중화 구성을 한다.

  • HSRP란 Active 기가비트 백본스위치의 장애시 Standby 기가비트 백본 스위치가 LAN상의 서비스 중단 없이 해당 라우팅을 자동 인계하는 라우팅 프로토콜이다.
  • HSRP는 하나의 백본스위치에서 다른 하나의 백본스위치를 모니터링하여 장비의 장애시 동일한 기능을 백업 받아 동작한다.
  • Hot Swap 기능에 의하여 On-Line상에서 모듈의 추가 및 교체가 가능하다.
  • 장비의 주요부분 이중화로 운영 중 단일 장비의 교체 작업이나 장애로 인하여 전체 시스템의 가동이 중지되지 않는다.

VLAN
백본 스위치를 통해 구성된 각 층별 또는 건물별 등 LAN 노드간 논리적 세그먼트를 그룹화하여 주요 서버의 데이터 처리 요구량에 따라 논리적 W/G를 형성하도록 하고, 네트워크 트래픽 관리 및 튜닝을 통해 전체 네트워크의 성능을 향상시키도록 구성한다.

  • VLAN이란 현재의 네트워크 자원을 그대로 유지한 상태에서 물리적인 구성이 아닌 논리적 구성을 통하여 시스템 성능을 향상시키기 위한 개념이다.
  • 이는 사용자별 또는 서버 성능별 그룹화를 하여 한 그룹에서 발생되는 트래픽은 타 그룹에 영향을 끼치지 않는 구조로 구현하여 불필요한 트래픽을 해소시킨다.
  • 각 VLAN은 백본 스위치와 이중화 구성을 하여 한 장비의 장애시에도 원활한 통신이 되도록 설계한다.
  • 건물별, 층별로 VLAN을 설정하여 네트워크 장애를 최소화한다.

장비선택
대용량 데이터의 증가에 따른 병목 구간 트래픽을 처리할 수 있도록 충분한 성능을 확보한 장비를 적절히 선택한다.
 
워크그룹 스위치
웍그룹은 소규모 작업그룹을 의미한다. 다시 말해 작은 회사 또는 한 학급 정도의 규모가 작고 허브나 스위치만으로도 통신이 가능한 그룹의 노드를 모아 놓은 장비가 웍그룹 스위치이고 다수의 웍그룹 스위치 노드가 모이는 곳이 백본 스위치이다.

※ 출처1 : http://www.mavericksys.co.kr/
※ 출처2 : http://blog.naver.com/nds239/10029215369

※ 참조자료
1. 백본 스위치 뭐가 좋은가? A: cisco > nortel (가격대 성능비 nortel > cisco)
http://kin.naver.com/detail/detail.php?d1id=1&dir_id=102&eid=GWlU+9p/OaXz+ptpYrNVvvL9TT5+UHyX&qb=uem6uyC9usCnxKE=&pid=fKRhNloi5T8sscLvkvwsss--264298&sid=ZiDe1OSsv0gAADSZiccAAAA6

 

출처 : http://willyoppa.tistory.com/1171684603

리눅스 등의 멀티 프로세싱 운영체제에서는 동시에 여러 프로그램을 실행할 수 있다. 
그때 실행 중인 프로그램에 대한 인스턴스를 프로세스라고 한다. 

프로세스는 프로그램에 대한 각각의 인스턴스를 의미하므로,같은 프로그램을 여러개 띄웠다고 해서 하나의 프로세스를 공유하는 것은 아니다.프로세스는 운영체제로부터 주소공간, 파일, 메모리 등을 할당받는다. 

리눅스 시스템에서는 코드 영역과 라이브러리를 프로세스 간에 공유하므로, 메모리 내에 코드와 라이브러리는 하나만 존재한다. 변수에 할당되는 공간으로 데이터 세그먼트와 스택 세그먼트는 프로세스 각각 가지고 있다.  그리고 각 프로세스 마다 실행 위치를 나타내는 PC(Program Counter)도 프로세스별로 관리한다.   

스레드란 한 프로세스 내에서 동작되는 여러 실행의 흐름으로, 프로세스 내의 주소 공간이나 자원들을 대부분 공유하면서 실행된다. 

기본적으로 하나의 프로세스가 생성되면 하나의 스레드가 같이 생성된다.이를 메인 스레드라고 부르며, 스레드를 추가로 생성하지 않는 한모든 프로그램 코드는 메인 스레드에서 실행된다.또한 프로세스는 여러개의 스레드를 가질 수 있으며 이를 멀티 스레드라고 한다. 

프로세스는 자신만의 고유 공간과 자원을 할당 받아 사용하는데 비해 스레드는 다른 스레드와 공간과 자원을 공유하여 사용한다. 

스레드는 프로세스 내에서 각각의 스택 공간을 제외한 나머지 공간과 시스템 자원을 공유한다.그러므로 프로세스를 이용하여 동시에 처리하던 일을 스레드로 구현할 경우 메모리 공간은 물론 시스템 자원 소모도 현격히 줄어든다.. 이와 같이 프로세스를 생성하는 것보다 스레드를 생성하는 것이 효율적이다. 특히 멀티 프로세서 환경에서는 더욱 효과가 탁월하다. 스레드 간의 통신이 필요한 경우 별도의 자원을 이용하는 것이 아니라 전역 변수의 공간을 이용하여 데이터를 주고받을 수 있다.
 
스레드의 장점을 정리하면 다음과 같다.  
- 시스템의 throughput이 향상된다.  
- 시스템의 자원 소모가 줄어든다  
- 프로그램의 응답 시간이 단축된다.  
- 프로세스 간 통신 방법에 비해 스레드 간의 통신 방법이 훨씬 간단하다. 

마지막에 언급한 스레드 간의 통신시 데이터를 주고받는 방법은 메모리 공간을 공유하므로 데이터 세그먼트, 즉 전역 변수를 이용하여 규현한다. 그런데 공유하는 전역 변수를 여러 스레드가 함께 사용하려면 어떤 문제가 생길까? 바로 충돌이다. 따라서 스레드 간에 통신할 경우에는 충돌 문제가 발생하지 않도록 동기화 문제를 해결해야 한다. 

스레드는 장점만 갖고 있는 것이 아니라 다음과 같은 단점도 지니고 있다.  
- 여러 개의 스레드를 이용하는 프로그램을 작성하는 경우에는 주의 깊게 설계해야 한다.     미묘한 시간 차나 잘못된 변수를 공유함으로써 오류가 발생할수 있다.   
- 프로그램 디버깅이 어렵다.  
- 단일 프로세서 시스템에서는 효과를 기대하기 어렵다. 

스레드는 POSIX 위원회가 표준을 정하기 전에는 각 운영체제 벤더에서 각각의 구조를 갖고 구현되어 왔다. POSIX 1003.1c 스레드 표준안이 마련되면서 비로소 동일한 방법으로 스레드를 구현할 수 있게 되었다. 리눅스의 스레드도 이 표준안을 거의 수용하고 있어 공통된 POSIX 스레드 라이브러리 함수들을 통해 스레드를 구현할 수 있다



출저 : http://ralf79.tistory.com/34, 진형아빠 

 

[출저: http://blog.naver.com/wiztree75/90195118347, 나무 (wiztree75)  ]

 

 

 

 

 

 

※빅 데이터란? : 시사사전 | 네이버 캐스트

 

 

 

 

 

 

 

인터넷이 성숙기로 접어들고 많은 정보와 지식들이 디지털화 되면서 인간과 세상에 관한 다양한 데이터들이 광범위하게 쌓여왔다. 오늘날 그런 방대한 데이터를 빅 데이터라 부른다. 빅데이터는 질보단  양으로 우리 인간의 시야를 넓혀준다. 빅 데이터를 통해 과거 빈약한 데이터들로 인해 추론과 직관에 의지해 들여다 볼 수 밖에 없었던 세계 뿐만 아니라, 우리가 인지하지 못했던 수 많은 신세계들도 드러나고 있다. 빅 데이터는 단순히 IT 업계만의 화두가 아니다. 인터넷이 우리의 일상이 되었듯이, 빅데이터 또한 그 영향력으로 인해 앞으로 우리의 입에 자연스럽게 오르내리게 될 것이다.1 

 

 

 

 

 

 

※위 그림의 상세 내용을 보려면 여기를 클릭! 

 

 

오늘은 빅 데이터란게 무엇인지, 그리고 빅데이터가 우리 삶에 어떤 영향을 어떻게 미친다는 것인지 그 빛과 어둠을 살펴보려 한다. 보다 나은 미래를 원한다면 이 빅데이터 지도를 꼭 주목해 보길 바란다.

 

 

 

 

 

 


[책] 빅 데이터가 만드는 세상 

 

 

 

 

 

빅 데이터에 대한 정보를 얻는 허브역할로서 책 "빅 데이터가 만드는 세상"을 선정해 봤다. 빅 데이터의 개념과 영향을 이 만큼 깔끔하게 잘 정리한 것도 없어 보인다. 현재 아마존에서도 지속적으로 좋은 반응을 얻으며 관련분야 최상위에 올려져 있는 책이다2. 쉽고 간결한 어휘로 쓰여졌기에 어렵지 않게 읽을 수 있고, 번역도 잘 되었다.

 

빅 데이터의 특징은 한마디로 양이 질을 압도한다는 것이다. N1=1all (하나의 정보 집합이 모두를 보여준다는 말)이란 등식이 성립할 정도로 데이터의 양은 압도적이다. 때문에 이 빅데이터의 세계에서 중요한 건 인과관계보다 상관관계다. 왜인지 몰라도 A가 발생하면 B가 발생하는 것이 보이기 때문에, 다음에 A라는 현상이 일어날때 B가 일어날 것임을 예측할 수 있다. 한 두개의 정보로는 그 확률을 장담할 수 없기에 인관관계를 밝혀봐야 하겠지만, 거의 전부를 보여주는 빅데이터를 통해 발견한 상관관계라면 인과관계를 몰라도 쉽게 예측할 수 있다. 3

 

이런 빅 데이터는 그 효용만큼이나 위험도 있다.(마치 원자력 처럼) 데이터가 너무 광범위하게 공유되는 나머지 개인의 사생활은 거의 없어질 지경에 처해있다. 어떻게 빅 데이터로부터 사생활을 보장 받을 것인가? 또한 어느 한 기업이 이 빅 데이터를 독점하면 어떻게 될까? 데이터를 너무 맹신한 나머지 확률의 문제라는 걸 잊고 빅 데이터의 예측 시스템 안에 인간을 얽매여 놓진 않을까? 우린 이런 빅 데이터의 어두운 면을 어떻게 걷어낼 수 있을까?

 

이 책 '빅 데이터가 만드는 세상'은 이런 빅 데이터의 이중성을, 다양한 사례들과 통찰력 있는 분석을 통해 물 흐르듯이 풀어낸다. 그리하여 빅 데이터를 보다 가치있게 이용할 수 있도록 우리를 안내해 준다. 이 책을 읽으면 어떤 이들이 빅 데이터 시대에 가치를 드러내게 될런지 감을 잡아볼 수도 있다.  이 책과 더불어 이 책을 기준으로 연결한 영화, 다큐, 책 들을 따라가다 보면 어느 새 빅 데이터라는 단어가 낯설지 않게 느껴질 것이다.

 

 http://book.naver.com/bookdb/book_detail.nhn?bid=7208679

 

 

 

※ 책이란 매체가 익숙하지 않다면 연결된 다큐와 영화를 먼저 봐도 된다. 그런 후에 빅 데이터에 대해 높아진 관심을 동력으로 해서 책을 읽어본다면, 책도 어렵지 않게 읽을 수 있으리라 본다. 먼저 'KBS 글로벌 다큐멘터리 빅 데이터'를 보고 이 후에 다큐 '괴짜 경제학', 영화 '머니볼' 그리고 이후에 구글 관련 다큐 두편과  영화'마이너리티 리포트'와 '위 약관에 동의 합니다'를 이어서 보면 빅 데이터의 명과 암에 대해 대략 감을 잡을 수 있을 것이다. 나머지 콘텐츠들은 책을 읽고 관심을 확장하는 측면에서 보면 좋을 듯하다.

 

 

 

 

 

1. 빅데이터란?


KBS 글로벌 다큐멘터리. 마래 경쟁력의 핵심 빅 데이터

 


일전에 제주올레 다큐지도에서 연결을 이야기하며 다룬 적이 있던 이 다큐는 빅데이터의 효용성에 관해서만 일단 다룬다. 사법분야, 경제분야, 인터넷 서비스 분야, 의학 분야, 우주 분야 등에서 빅데이터가 새로운 길을 어떻게 열어줬는지를 설명한다. 그러면서 빅 데이터의 제대로된 활용을 위해선 기존의 영역을 넘어선 협업이 중요하다는 점도 주지시킨다. 가장 중요한 건 데이터를 분석하는 사람의 통찰력이다.

 

BBC 호라이즌 시리즈의 다큐다.

  

 http://blog.naver.com/wiztree75/90194564787

 

 

 

2. 빅 데이터가 여는 세상

이제 본격적으로 빅데이터의 효용성에 대해 좀 더 들어가 보자.

 

 

괴짜 경제학.

 

 

 

 

이 다큐의 원저인 '괴짜 경제학'의 저자 스티븐 레빗은 단도직입적으로 이렇게 이야기 한다. "데이터는 거짓말을 하지 않는다" 라고. 그러면서 데이터 분석을 통해 세상을 다시 들여다 보며 갖가지 편견을 깨버린다. 

 

'부동산업자는 과연 고객을 위한 최상의 거래를 하는가?' '부모가 아이를 위해 하는 행동은 정말로 아이 미래에 도움이 될까?' '사람의 이름은 어떻게 지어질까 그리고 이름과 운명은 어떤 상관관계를 가질까?' '스모는 정말로 정정당당한 혼의 스포츠인가?' '뉴욕의 범죄는 정말로 왜 줄었는가?' '인센티브(보상)은 사람의 행동에 어떤 영향을 미치는가?' 등의 질문을 던지며 그 답을 데이터 분석으로 구해본다.

 

처음 이 다큐를 봤을때 가진 느낌은 '신선하다' 였다. 특히 경기 승패의 패턴 분석을 통해 스모 경기의 부조리함을 발견하고(이 부분이 빅데이터 책에도 인용된다), 낙태허용과 뉴욕의 범죄율 하락을 연결시켜 이야기 하는 부분은 정말로 인상이 깊었다4. 빅 데이터라는 개념을 접했을 때 이 괴짜경제학을 떠올렸었는데, 아니나 다를까 빅 데이터 책에서 바로 인용이 되었다.

 

빅 데이터는 세상을 있는 그대로 보게 만들어 주는 도구가 될 수 있음을 이 다큐를 통해 느껴볼 수 있다. 세상을 있는 그대로 보지 못하면 그 만큼 오판의 확률도 높아질 수 밖에 없지 않은가. 복잡한 이론을 무겁게 이야기하는 다큐가 아니다. 그냥 재미로 봐도 흥미롭게 볼 수 있다. 

 

 

 

 

[책] 괴짜 경제학

 

 

 

 

괴짜 경제학 다큐는 이 괴짜 경제학 책을 기반으로 만들어 졌다. 스테디 셀러로서 현재에도 계속 읽혀지는 책이다. 다큐에 나온 이야기들이 구체적인 데이터들과 함께 언급되어 있다. 다큐에 나오지 않은 주제도 몇 개 있는데, '마약 판매상은 왜 어머니와 함께 사는 걸까?'라는 주제는 마약 경제가 어떻게 돌아가는지 그 허와 실을 들여다 본다. 물론 데이터로. 그 밖에 KKK단에 관한 이야기도 흥미롭다.

 

이 책의 진정한 효용은 그저 우리가 모르던 사실 몇개를 알 수 있다는게 아니다. 이 책의 저자는 그저 '세상에 대해 남이 얘기하는 걸 그대로 받아들이지 말고 스스로 질문해 보라' 라고 말한다. 그런 후에 각종 데이터들을 바탕으로 그 답을 탐구하는 과정에서 세상에 대한 놀라운 사실들을 알게 될 수 있다면서 말이다. 

 

"이 모든 연구 주제의 기저에는 적절한 관점을 발견하기만 한다면 아무리 복잡한 현상이라도 이해할 수 있다는 믿음이 깔려있다' 라는 이 책에 대한 한 외국 언론의 평가는 고개를 절로 끄덕이게 만든다. 빅 데이터 세계에서 가장 필요한 자세는 습관적인 편견에서 벗어나 데이터들을 있는 그대로 바라보는 것이다.

 

 

 

 

[영화] 머니볼

 

 

 

 

야구를 좋아하는 이라면 아마도 이 영화를 봤으리라 생각한다. 

 

기본적인 몇몇 기록들과 코칭 스태프들의 경험과 직감만으로 선수들의 능력을 판단하고 경기를 운영해 왔던 메이저리그. 빌리 빈이라는 인물은 추락하는 팀의 단장으로서 반전을 꾀하고자 그런 메이저리그의 관행에 반기를 든다. 그리고 단지 다양한 데이터 분석을 통해 선수들을 분류하고 역할을 부여해, 저평가된 선수들의 새로운 가치를 이끌어 낸다. 그의 참모는 야구선수 경험도 없는 통계분석가였다. 빌리 빈은 바로 빅 데이터를 통해 야구계에 새로운 운영 흐름을 만들어 냈던 것이다.

 

빅데이터 책에서 저자는 사회의 많은 영역들에서 그 분야의 전문가 보다 통계분석가들이 우위에 서고 있음을 이야기 하며 빌리 빈의 사례를 예로 들고 있다. 해당 분야에 연고가 없다는게 오히려 선입견이 없이 사실을 있는 그대로 바라볼 수 있는 능력이 될 수 있다고  저자는 말한다. 많은 영역의 빅데이터들이 개방될 수록 이런 데이터 능력자들이 부상할 수 밖에 없다.

 

단순한 야구계 인물 이야기를 넘어 사회변화를 조망해 볼 수 있는 영화다.

 

 

 

 

[책] 아웃라이어

 

 

 

 

이 책을 대하는 느낌은 괴짜경제학을 대하는 느낌과 비슷하다.5 이 책의 저자 말콤 글래드웰 또한 다양한 데이터들을 근거로 편견과 무지의 늪에서 우리를 건져올린다. 특히 성공의 문제를 개인의 의지 문제가 아니라 한 개인을 둘러싼 갖가지 환경의 영향의 문제로 이야기 한다. 즉 개인과 환경의 상관성을 각종 데이터들을 통해 집중 탐구해보는 책이라 하겠다. 

 

어린 스포츠 선수들에게 있어 같은 나이라도 1월에 태어난 아이들과 12월에 태어난 아이들의 신체적인 차이가, 성적의 상당한 차이를 만들어내는 원인이 되고 있다는걸 통계적 분석을 통해 밝혀낸 것은 빅데이터 분석을 통한 새로운 발견의 단적인 예다. 그런 숫자로 된 정형화된 데이터 분석 말고도 저자는 자기만의 통찰력을 통해 각종 비정형화된 데이터6들을 분석해 사람의 성공에 관한 편견들을 깨고 있다. 특히 문화적 환경의 영향을 이야기하는 부분에 등장하는 우리나라 대한항공의 괌추락사고의 원인에 대한 분석7은 우리나라 사람으로서 너무나도 인상적으로 다가온 부분이었다. 

 

이 책은 빅 데이터 책에 직접적으로 언급은 되지 않지만 개인적으로 연결선이 보여서 연결책으로서 기재해 봤다. 이 책이나 괴짜경제학이나 빅 데이터 책이나 모두 쉽고 간결하게 쓰여진 공통점이 있다. 이야기를 풀어가는 방식도 조금 비슷하다. 그렇기에 이 세책중 어느 한가지라도 재미있게 읽었다면 나머지도 즐겁게 읽을 수 있으리라 본다.

 

 

 

 

 

[책] 자살론

 

 

 

 

빅 데이터 책에서 빅 데이터 연구의 선구자들을 이야기하는 부분이 있다. 별 운동을 하루하루 세밀히 기록해 그 기록을 바탕으로 천체 운동의 패턴을 발견한 티코 브라헤나, 배들의 항해기록을 분석해 최적의 항로를 도출해낸 모리선장 등의 이야기가 그 예들이다.

 

이런 이야기들을 봤을 때 개인적으로 떠오른 책이 하나 있었다. 바로 에밀 뒤르켐의 자살론이다. 이 책은 1897년에 쓰여졌는데, 자살 문제를 철저히 통계적으로 분석하여 자살에 관련된 갖가지 편견들을 넘어 자살의 원인을 합리적으로 규명해 냈다. 그는 자살의 여러 이유중에 특히 현대사회에서 가장 문제가 되는 이유로 변화가 일상화된 현대사회에서 개인들이 혼란을 겪으며 고립되고 방치되고 있다는 점을 꼽고 있다.

 

아직 완독을 한 것은 아니나 1897년에 어떻게 그런 분석을 해낼 수 있었는지 곳곳에 인용되는 표들을 보면 혀를 내두를 정도다. 자본주의가 융성해 가던 시점의 그런 체계적이고도 탁월한 분석은 오늘날의 자살 문제를 바라보는 데 있어서도 많은 영감을 준다. 아직도 자살 기사에 '자살할 용기로 열심히 살지ㅉㅉ'라는 식의 막연한 댓글을 다는 사람이 있다면 이 책을 꼭 읽어보기 바란다.

 

빅 데이터가 사회적 문제를 해결하는데 일조할 수 있음을 깨닫는 사례로서 아주 적절하다고 본다.

 

 

※ 이 책의 요약 정보는 여기를 참고 : http://terms.naver.com/entry.nhn?docId=892611&cid=269&categoryId=1090

 

 

 

 

3. 빅 데이터의 강자 구글의 빛과 어둠 

 

NGC 냇지오 인사이드. 신의 직장, 구글

 

 

 

 

빅 데이터 시대에 강자는 단연 구글이다. 구글은 빅 데이터를 방대하게 수집하고 있을 뿐만 아니라, 그것을 체계적으로 축적하고 분석할 수 있는 기술도 가지고 있으며, 데이터들의 가치를 이끌어 낼 수 있는 통찰력을 지닌 인재들도 있다. 그 만큼 빅데이터 책에서도 구글의 예를 많이 언급하고 있다. 긍정적인 부분 뿐 아니라 사생활 침해 문제나 데이터의 독점, 관료제화와 같은 어두운 부분도 같이 다룬다.

 

이 다큐는 구글을 이해하는데 있어 기본적인 정보를 제공한다. 구글의 역사, 세르게이 브린과 래리 페이지를 비롯한 내부 인물들, 운영방식 등을 이야기하며 구글을 개괄해 보는 다큐라 할 수 있겠다. 이 다큐에서도 역시 구글의 막대한 권력을 이야기 하며 구글의 사회적 책임을 강조하는 걸 잊지 않는다. 구글의 미래는 결국 그런 책임에 대한 신뢰를 어떻게  유지하느냐에 달려 있다면서.

 

아주 깊이 있는 다큐는 아니지만 빅데이터 책과 연결지어 보면 여러모로 이해에 도움이 되는 다큐다.

 

 

 

 

EBS EIDF 2013 구글 북스, 라이브러리 프로젝트.

 

 

 

 

일전에 저작권 이야기를 하면서 언급했던 다큐다. 구글의 여러 빅 데이터 관련 서비스 중에 구글 북스는 그 규모와 영향력에 있어서 특히나 방대하다. 때문에 구글 북스에 있어서도 구글의 권력과 책임을 이야기 하지 않을 수 없다. 

 

세계의 모든 책을 온라인을 통해 한 곳에서 열람할 수 있다면 그 보다 좋은 서비스가 또 어디 있겠는가. 하지만 책을 관리하는 문지기인 구글이 공명정대하지 못한 길로 빠진다면 어떻게 될까. 책에 대한 정당한 대가 지불없이 자기들만 이익을 누린다면, 또 책에 대한 접근에 있어서 권력을 휘두른 다면 어떻게 될까. 독점 권력은 부패하기 마련이라는 말이 있지 않은가. 거대화된 구글이 어떻게 "don't be evil"이라는 사훈을 지켜갈 수 있을지 관심있게 지켜보는데 도움을 주는 다큐다.

 

 

 

 

4. 빅 데이터의 어둠

이제 빅 데이터의 어두운 면에 대해  좀 더 깊이 이야기 해보자.

 

빅 데이터는 여느 과학 기술과 다를바 없다. 올바르게 사용하면 인류에게 많은 혜택을 안겨줄 수 있지만 불순한 의도로 사용한다면 인류를 파멸로 몰아갈 수도 있다. 빅 데이터 책에서 지적한 빅 데이터의 어두우면은 크게 세가지다. 사생활 침해, 데이터의 독점을 통한 권력의 독점, 데이터에 대한 맹신으로 인한 오판과 남용의 문제가 그것이다.

 

 

포그 오브 워

 

 

 

 

이 다큐는 베트남 전쟁 당시 미국의 국방부 장관을 역임했던 로버트 맥나마라를 조명한 다큐다. 맥나마라가 자신의 인생을 통해 얻은 교훈을 인터뷰 형식으로 이야기 한다.

 

빅 데이터 책에서 저자는 빅 데이터의 어두운 면을 이야기하며 이 맥나마라를 자주 인용하고 있다. 맥나라마 라는 인물은 포드 자동차 회장을 하다가 국방부 장관이 된 특이한 경력의 인물이다. 하지만 그리 특이한 건 아니다. 이는 머니볼에서 야구선수 경험이 없는 통계분석가가 야구단 운영에 영향력을 발휘했던 사례와 일맥 상통하기 때문이다. 맥나마라는 숫자와 통계 전문가였다. 포드 자동차 이전에 2차대전 당시에도 그는 폭격에 관련된 통계적 분석을 통해 전쟁에 기여(?)했다. 포드 자동차에서도 현장보다는 데이터에 기초해 회사를 운영했다. 그리고 성공을 거두었다. 하지만 국방장관으로서 그는 성공하지 못했다. 어디까지나 확률에 불과한 데이터에 대한 맹신은 결국 오판을 불렀고 베트남 전을 빠져나올 수 없는 늪으로 몰아넣었다. 특히 그 판단의 기준이 되는 전쟁에 관련된 데이터들이 관료주의의 병폐로 인해 왜곡되면서 문제는 더 커질 수 밖에 없었다.

 

이 다큐의 내용과 빅 데이터 책에서 맥나마라에 대해 비판하는 내용이 묘하게 매치된다. 빅 데이터 책에서 비판한 바와 같이, 맥나마라는 과거로 부터 배울 것을 이야기 하지만 정작 자기 자신의 잘못에 대해서는 얼버무린다.

 

개인적으로 즐겨찾기를 해두는 에롤 모리스 라는 감독의 작품이기도 하다. 또 한 '포그 오브 워'는 2004년 아카데미상 장편다큐멘터리 부문 수상작이다.

 

 

 

 

[영화] 마이너리티 리포트

 

 

 

 

빅 데이터는 기본적으로 과거와 현재의 데이터를 통해 미래를 예측하는 개념이다. 그러나 이 예측은 100%가 아니며 어디까지나 확률에 기초한 상관관계에 불과하다. 확률이라는 걸 잊어버리고 데이터를 맹신한다면, 부작용이 발생할 수 밖에 없다. 'KBS 글로벌 다큐멘터리. 빅 데이터'에서도 봤듯이 빅 데이터로 사람들의 행동 패턴을 분석해 범죄예방에 이용하기도 하는데 이것이 정도를 넘어서면 마이너리티 리포트와 같은 상황이 되는 것이다. 단순히 영화라고 치부해 버릴 수 없는 이유다.

 

빅 데이터 책의 저자는 미래에 대한 불안과 데이터에 대한 맹신으로 예측의 덫에 걸려든 상황에 대한 묘사를 이 영화를 통해 설명한다. 그러면서 저자는 인간에게는 자유의지가 있으며 결국 그 자유의지로부터 빅 데이터를 분석하는 통찰력이 나오는 것임을 잊지 말라고 말한다. 빅 데이터 위의 빅 데이터는 인간 자신이라고 하면서.  

 

 

 

 

위 약관에 동의합니다.

 

 

 

 

개인 생활에 관련된 모든 것이 저장되며 빅 데이터화 되가는 시대. 과연 데이터화 된 개인 정보들은 어떻게 관리되고 있을까? 이 다큐는 빅 데이터의 가장 큰 문제로 지적되고 있는 사생활에 대한 위협 문제를 다루고 있다. 특히 우리가 각종 사이트에 가입할 때 별 생각없이 동의를 하곤 하는 약관의 내용을 분석해 인터넷 기업(특히 구글과 페이스북)들의 숨은 의도를 파헤쳐본다. 거기에 개인정보들을 탐내는 또 다른 세력인 국가정보기관들이 어떻게 개인정보를 수집하고 활용하는지도 알아본다.

 

개인정보 노출이 너무나 일상화된 나머지 우리는 개인정보 노출에 갈수록 무감각해지고 있다. 하지만 그렇게 쌓이거나 유출된 정보들이 어떻게 이용되고 있는지를 안다면 경각심을 다시 일깨울 수 있으리라 본다. 이 다큐는 빅 데이터 책에서 다룬 개인정보 관리 문제, 그리고 데이터를 바탕으로 한 통제 문제와 연결해서 볼 수 있다. 개인정보를 통해 개인의 행동을 예측하고 통제하는 국가정보기관들의 모습은 마이너리티 리포트와도 연결된다.

 

"몇 년 동안 대중을 몰래 감시한 저희로서는 수많은 사람들이 자발적으로 자신들의 거주지와 종교적, 정치적 견해, 순서대로 정리한 친구 목록, 이메일 주소, 전화번호, 자신이 찍힌 수백 장의 사진, 현재 하고 있는 활동 정보를 공개하니 놀랍기 그지 없습니다. CIA로서는 꿈에 그리던 일이죠" 라는 다큐 속 CIA 부국장의 말이 기억에 남는다. 인터넷 기업들의 책임있는 자세가 무엇보다도 중요하다는 걸 새삼 깨닫게 해주는 말이다.

 

 

 

 

 

 

5.빅 데이터 앞에선 선입견이 없어야 한다.

 

앤디해밀턴의 사탄을 찾아서

 

 

 

 

빅 데이터를 대할 때 많이 나오는 말이 '데이터가 스스로 말하게 하라'는 말이다. 그런데 데이터를 바라보는 이가 편협하거나 미신스러운 선입견을 가지고 있다면 데이터가 말하는 바를 제대로 들을 수 있을까? 바로 이런 관점에서 이 다큐가 영감을 주는 듯하여 연결해 봤다.

 

이 사탄을 찾아서 라는 다큐는 인간 내부에 깊숙히 박혀 있는 관습화된 선입견을 추적해 본다. 바로 "악마" 이라는 개념이다. 사회에 문제가 생겼을때 보통 그 문제의 원인을 개인에게서 찾는 경우가 많다. 극단적인 사건의 경우에는 한 개인을 '악마 같은 인간' 이라고 부르며, 그 개인에 대한 처벌에만 집중한다. 하지만 정말 개인만의 문제인가? 그 '악마같은 인간'을 제거하면 사회는 평화로와 지고 모든 문제가 자연스레 풀리는가? 아니다. 문제를 따라올라가다 보면 결국 드러나는 건 사회 구조와 시스템의 문제다. 이 다큐는 이렇게 "악마"라는 개념의 허상을 파헤쳐본다.

 

옛날 만화영화엔 주인공이 악마를 물리치면 어둠으로 둘러쌓인 마을이 일순간에 빛을 회복하면서 평화로운 마을로 바로 탈타꿈 하는 장면이 종종 나온다. 어릴 적에 이런 만화를 많이 봐서 그런지 아직도 어떤 문제가 터지면 종교인이 아니더라도 '우리 중에 악마가 있다. 그 악마가 누구냐? 찾아라!' 라는 식의 대응을 하는 사람들이 많다. 하지만 문제의 근원은 개인이 아니라 구조다. 사회구조가 제대로 구축되지 못한 상태에선 부조리들이 계속 발생할 수 밖에 없다. 

 

앞서 봤듯이 빅 데이터는 사회문제를 해결하는 데에도 도움을 준다. 특히나 빅 데이터를 기반으로 생겨나는건 어떤 단품이 아니라 체계와 시스템이기 때문에, 우리는 빅 데이터들을 더 잘 들여다 볼 필요가 있다. 선입견 없이 있는 그대로. 글을 쓰다 문득 생각난건데 이런 "악마"에 대한 선입견이 빅 데이터와 만나면 결국 마이너리티 리포트와 같은 사회가 탄생하는게 아닐까?  

 

아, 그리고 정말 재치있게 잘 만들었다. 이 다큐는 재미면에서 최고 점수를 주고싶다.

 

 

 

 

6.빅 데이터는 순간의 유행인가?

 

[책]소유의 종말.

 

 

 

 

자 또 이 책이 등장했다. 이 쯤되면 내가 제러미 리프킨의 빠가 아니냐는 의심도 할지 모르겠다.8 그렇지는 않다. 철저히 내용에 기반해 이 책을 다시 빼들었다. 빅 데이터를 보다 보면 너무나 광범위한 영향력을 이야기하는 것에 '그냥 한 시대의 유행이 아닌가?' 라는 생각을 가질 수 있을 것이다. 어떤 이론이나 개념이 한 순간의 유행인가 아닌가를 판단하는 방법으로는 흐름속에서 연결지어 생각하는 방법이 좋은 방법이 될 수 있다.

 

소유의 종말은 2000년도에 쓰여진 책이고 '빅데이터가 만드는 세상'은 2013년에 쓰여진 책이다. 그런데 두 책을 비교해 보면 수많은 연결고리들이 보인다. 즉 소유의 종말이 이야기한 사회의 경향이 빅 데이터 책이 말하는 오늘날의 사회에서 더 뚜렷해 졌다는 말이다. 소유의 종말에서 말한 '물질 소유보단 네트워크 접속 가능성과 빈도가 가치를 더 부른다' 라는 말은 빅 데이터로 더욱 강화된 네트워크가 힘을 발휘하는 지금의 시대에 큰 설득력을 얻는다.

 

"모든 것에 대한 시각을 바꿔놓는 책은 10년에 한 두권 나온다" 라는 말은 로렌스 레식이  '빅 데이터로 만드는 세상' 을 언급하며 한 말인데, 두 책간의 시간차를 봤을 때 더 인상깊게 다가온다.

 

 

 

 

 

p.s. 빅데이터를 말하는 우리나라 다큐로서 'KBS 시사기획 창. 빅 데이터, 비지니스를 바꾸다' 라는 시사다큐가 있다. 여기 지도에 그려넣지 않은 이유는 전체적으로 짜집기식으로 보이는 데다가, 결정적으로 마지막 부분에서 실소마저 터저 나오는 내용이 있어서다. 그러나 들어볼 만한 내용도 있으므로 참고삼아 언급해 본다.

 

 

 

 

 

 

 

이상으로 빅 데이터의 세계를 들여다 봤다. 나름 완성도 있게 만들어 본다는 욕심에 시간이 좀 걸렸다. 앞으로 이 지도는 다큐나 책 뿐만 아니라 새로운 자료가 나오면 계속 첨부되며 갱신될 것이다. 빅 데이터를 말하는 빅 데이터로서 자리 잡을 수 있기를 희망해 본다.

 

빅 데이터 이야기를 위해 자료를 찾으면서도 느낀 점이지만, 우리나라의 빅 데이터 환경은 아직도 만들어가야 할 게 너무 많은 듯하다. 특히 데이터들을 일목요연하게 보여주는 체계가 아쉽다. 많은 데이터들이 그저 모래알 같이 흩어져 있기만 하다. 개인이 일일히 정리해서 보는데 너무 많은 에너지를 소비할 수 밖에 없다. 빅 데이터 책에서도 이야기 하는 부분이지만, 빅  데이터의 가치를 이끌어 낼 수 있는 이들의 상당수는 아무것도 소유하지 않았기에 선입견 없이 빅데이터들을 넓게 바라볼 수 있는 이들이다. 앞으로 빅 데이터들이 더 많이 '체계적'으로 개방된다면 이런 숨은 인재들이 자기만의 방향성으로 갖가지 콘텐츠와 시스템들을 쏟아 낼 수 있다는 말이다. 체계적이지 못한 빅 데이터 환경이 아쉬울 수 밖에 없다.

 

다큐와 관련하여 지식입문 체계를 만들어 가려고 하는 내 입장에서도 빅 데이터는 많은 영감을 준다. 다큐 라는 영역 자체가 빅 데이터 이기 때문이다. 다큐의 수는 정말로 헤아리기 어려울 정도다. 하지만 우리나라에서 이 다큐 빅 데이터를 제대로 이용하기 위해 기초적으로 활용할 수 있는 체계는 전무하다 시피 하다. 유튜브나 imdb 같은 체계를 보면 그저 부러울 수 밖에 없다. 특히 다큐 콘텐츠 자체도 3~4년 정도가 지나면 시야에서 사라진다. 어딘가 존재는 하지만 그 존재 자체를 알 수 가 없다. 빅 데이터로 축적되긴 커녕 결국 모두 버려진다. 


데이터들을 단지 많이 흩뿌려 놓는다고해서 그 가치가 드러나는 것은 아니다. 과거의 정보들을 축적하고 활용할 수 있는 체계와 동시대의 많은 데이터들이 연결될 수 있는 체계 그리고 사람과 사람, 사람과 데이터가 연결될 수 있는 체계들이 우선 구축되어야 한다. 그래야만 빅 테이터의 가치를 제대로 이끌어 낼 수 있고, 그 연결된 체계를 통해 데이터 독점과 오남용으로 인한 폐해도 줄일 수 있다. 늘 말하지만 개인이나 기업, 서비스들도 그런 연결 속에서 자신을 더 잘 드러낼 수 있다. 

 

 

 

 

 

 

1.왜 연결인가? : 제주올레 가 반영하는 시대상

 

 

 

 

 

 

1.빅 데이터 개념 정리 : http://terms.naver.com/entry.nhn?docId=1691553&cid=3619&categoryId=3623 (목차의 제목들을 클릭)

 

2.관련 위키항목 : 빅 데이터  / big data

 

3.빅데이터 분석가 : 클릭

 

 

 

 

 

 


 

  1. 빅 데이터에 대한 관심의 증가세는 여기를 참고하시라.
    http://www.google.com/trends/explore#q=big%20data
  2. 아마존에서 책에 대한 반응을 볼 수 있다.
    http://www.amazon.com/Big-Data-Revolution-Transform-Think-ebook/dp/B009N08NKW/ref=sr_1_1?ie=UTF8&qid=1399029335&sr=8-1&keywords=big+data
  3. 예를들어 구글 검색에서 어느 특정 지역에서 독감 증세에 대한 검색이 갑자기 는다면 왜인지는 몰라도 현재 그 지역에서 독감이 퍼지고 있다는 걸 바로 예측할 수 있다. 그렇기에 빠르게 대처할 수 있다.
    월마트에선 기존의 데이터를 가지고 날씨변화에 따라 계산대 앞에 쌓아 놓는 소형 상품들의 배치를 바꾼다. 왜 날씨에 따라 소비 패턴이 틀려지는지는 알 필요가 없다. 일단 데이터가 말하는 대로 하기만 하면 된다.
    이들은 빅데이터로 부터 얻을 수 있는 효용의 단순한 예에 불과하다.
  4. 뉴욕의 범죄율 하락의 경우 그 원인으로 "깨진 유리창의 법칙"이 많이 이야기 된다.
    스티븐 레빗은 깨진 유리창의 법칙 자체를 부정하는 것은 아니다. 다만 여러 데이터를 종합해 봤을 때 '낙태 허용으로 인한 불우한 시절을 보낸 이들의 감소'가 그 원인이라고 말하고 있다.
    물론 범죄율 감소를 위해 낙태를 이용해야한다는 말은 절대 아니며 다만 그 상관관계만을 말하고 있다.
  5. 스티븐 레빗은 괴짜 경제학에서 이 아웃라이어를 언급하진 않지만, 호감어린 말투로 말콤 글래드웰을 직접적으로 언급한다.
  6. 비정형 데이터(unstructured data)란 일정한 규격이나 형태를 지닌 숫자 데이터(numeric data)와 달리 그림이나 영상, 문서처럼 형태와 구조가 다른 구조화 되지 않은 데이터를 말한다.
    자세한 내용은 아래 참고.
    http://terms.naver.com/entry.nhn?docId=1691558&cid=3619&categoryId=3623
  7. 블랙박스 분석을 통해 기장과 부기장간의 우리나라 특유의 권위적인 위계질서가, 추락당시 부기장이 의견을 제대로 내지 못하게 하는 장벽으로 기능했음이 밝혀졌다.
  8. 절대 아니라능

    [출처] 빅 데이터의 세계|작성자 나무

수학공부 링크

 http://j1w2k3.tistory.com/818



웹페이지 설계 링크

 http://yslab.kr/94

 

IT 컨퍼런스 등 행사 관련

 http://tech.eventdirectory.kr/


학원

 http://www.fastcampus.co.kr/


컴퓨터 잡지

  http://www.comworld.co.kr -> 컴퓨터 월드


다양한 분야에 대한 질문에 답변하는 커뮤니티

  https://www.quora.com/


컴퓨터관련 링크 잡지

  http://techneedle.com/


* 온라인 석사과정

  http://techneedle.com/archives/26639


초보 개발자가 오픈소스에 기여하는 방법

 http://www.bloter.net/archives/197960


해외 채용 정보

 http://www.nagaja.net/


코딩테스트(코딩도장)

 http://codingdojang.com/


데이터 사이언스 강의

 http://fastcampus.co.kr


IT 노동조합 

 http://www.freedev.kr/zbxe/

 

IT 관련 책주문 - EBOOK 많음

  http://www.hanbit.co.kr/index.html

 

react 이해하기 쉽게 강좌되어 있음.

https://velopert.com/tag/reactcodelab


경제신문

http://www.fntimes.com


방법1 :


주석처리를 하고자 하는 부분을 비주얼모드에서 블럭을 지정하여 사용하면 된다.
비주얼모드: [ctrl] +v

라인을 지정한 상태에서 
주석 처리시 
: norm i# 

주석 해제시 
: norm xx


[출저 : http://ssulsamo.egloos.com/2432826]


방법:2


 ctrl+v -> 처리할만큼 지정 -> shift+i -> # -> esc -> (0.5초 대기)


 역과정

   ctrl + v -> 처리할 # 문자들을 지정 --> d

 

+ Recent posts