'All Category'에 해당되는 글 500건

  1. 2017.01.17 javascript 이메일 check
  2. 2017.01.08 spring에서 HtmlUnit 및 Selenium WebDriver이용
  3. 2017.01.06 MockMvc
  4. 2017.01.04 spring web test시 user mock
  5. 2016.12.28 Mockito 사용법
  6. 2016.12.19 thymeleaf 기본.
  7. 2016.12.18 spring boot
  8. 2016.12.12 six2six FixtureFactory
  9. 2016.12.08 google Guava
  10. 2016.12.07 jackson (ObectMapper)
  11. 2016.12.03 Service-as-a-VM & Docker
  12. 2016.12.02 Orika - the mapper
  13. 2016.12.02 Lombok
  14. 2016.12.01 Macbook 처음사용시
  15. 2016.11.23 Stream (java8) + Collectors
  16. 2016.11.15 Armeria
  17. 2016.10.23 F,P,S & FunctionalInterface 1
  18. 2016.10.12 mySql Tip
  19. 2016.10.11 구글 SLAM 공개
  20. 2016.10.07 auto login + data Add
  21. 2016.09.27 한국과 일본 LTE
  22. 2016.09.26 netty
  23. 2016.09.22 netty활용 사례(netflix zuul)
  24. 2016.09.12 Git advanced.
  25. 2016.09.12 spring 동작구조 및 web Tip
  26. 2016.08.28 AsyncFileChannel
  27. 2016.08.16 Message Digest
  28. 2016.08.15 HTTP 2.0
  29. 2016.08.10 유니코드
  30. 2016.08.06 객체지향 5원칙(SOLID)

javascript로 이메일 verification하는 스크립트가 왜케 복잡한 것만 있는지..


인터넷에 마음에 드는 게 없어서 새로 만들어 보았다.



//check if mail address is xx@xx.xx (xx: contains "." & "_" & "-" & "alphanumeric" )
function validateEmail(email) {
var re = new RegExp("^[-a-zA-Z0-9._]+@[-a-zA-Z0-9._]+\\.[-a-zA-Z0-9._]+$");
return re.test(email);


코멘트 처럼  xx@xx.xx  폼을 체크하는데  xx 는  - . _ 알파뉴메릭  으로 이루어진다. 



조금 더 발전하면.. (이건 다른사람 꺼)

"[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*(\\.[A-Za-z]{2,})";


Posted by yongary
,

Selenium 을 이용하면 여러 브라우저를 직접구동시켜 다양한 테스트를 수행하므로

고급 웹서비스에서는 이 방식을 사용하는 것이 좋다.


하지만 간단한 웹페이지라면 이런방식이 부담이 될 수 있는데,

간단한게  spring의  HtmlUnit을 이용하면 되지만(REF) 약간 부족한 부분을

Selenium의 WebDriver만 이용하는 방법이 있다.    이경우 Selenium서버는 필요없다. REF


<비교설명> REF  챕터2.

Posted by yongary
,

MockMvc

Spring 2017. 1. 6. 15:26

영문 spring test 환경 (MockMVC+Junit) 기본설명  : REF


영문Test Guide URL



Spring에서 지원하는 MockMvc로도 거의 모든 테스트가 가능하다.

(가끔 Mockito가 필요하면 둘을 섞어서 쓰면 되는 정도로 보인다)



이전엔 Mockito가 많이 필요했지만, 필요성이 조금 줄어든 것 같다.



아래는 MockMvc로 컨트롤러를 테스트 하는 예제이다. 

  - Controller Test annotation (spring-boot 1.4 부터 지원:)  REF




<MockMVC 기본>  REF

1. Request

-perform

-accept

-with

-param

-cookie

-sessionAttr


2. Response

-andExpect

-andDo

-andReturn



<andExpect> 에서 여러가지 확인이 가능한데.. 주로 많이 쓰는 것들은

.andExpect(status().isOk())
.andExpect(content().json(expected));
.andExpect(status().is3xxRedirection());

.andExpect(view().name("list"))
.andExpect(MockMvcResultMatchers.model().size(1));

등등이다.



ModelAndView: 데이타가 복잡할 경우에도 테스트가 가능한데....  

        View name = redirect:view

             View = null

        Attribute = MyTicketReserveResult

            value = MyTicketReserved(code=0009, msg=nulll)

           errors = []


와 같은 json을 확인하려면.. (아직 확인 중)


.andExpect(jsonPath("$[1].rtncd").value("0009"))


Posted by yongary
,


Spring 에서  web Test시에 user를 mock하는 방법으로 2가지를 현재 보고 있는데,

차이점이나 장단점에 대해서는 좀 더 공부를 할 예정이다.



1. import org.springframework

        .security.authentication.UsernamePasswordAuthenticationTokenREF


  

UserDetails user = this.userDetailsService.loadUserByUsername(username);

        UsernamePasswordAuthenticationToken authentication = 
                new UsernamePasswordAuthenticationToken(
                        user, 
                        user.getPassword(), 
                        user.getAuthorities());



2. import static org.springframework

         .security.test.web.servlet.request

         .SecurityMockMvcRequestPostProcessors.user;


  RequestBuilder request = get("/my_web_url")

  .with(user (myUser));



AuthenticationManager 참고: REF

Posted by yongary
,

Mockito 사용법

Spring 2016. 12. 28. 18:09

javadoc   한글개요   goodTutorial



Mockito에서   @Mock @InjectMocks @Spy 의 차이점:

(작성 중: 현재 정확하지 않음)


@InjectMocks를 우선 사용해서 서비스/Controller등을 만들고

컴포넌트를 @Mock를 이용해서 삽입한다.  REF


둘을 하나의 object에 동시에 사용하고 싶을 경우, 동시에 사용할 수 없기 때문에

@InjectMocks와 @Spy를 동시에 사용할 수 있는데

이경우  when()함수를 사용하면 실제 함수를 호출하기 때문에  doReturn함수를 사용한다.  Ref



<검사함수들>

when  :  mock객체는 기본값을 return하기 때문에 Stubbing을 통해 원하는 값을 리턴한다.      REF

 - when(mockedGenerator.getNextId()).thenAnswer(new Answer<Integer>(


assertTrue

  assertNotNull


doReturn  Ref   -override도 가능.

  doThrow  -  void type을 stub할때, when이 java문법에 맞지않아서  
                    doThrow(new Exception()).when(mock).method() 이렇게 사용.

  doNothing

           ex) doNothing().when(authenticationManager).authenticate(Matchers.any(Authentication.class)); 

  doAnswer 

           ex) 

doAnswer(new Answer<Authentication>(){

@Override
public Authentication answer(final InvocationOnMock invocation) throws Throwable {


//case token

ObjectPostProcessor<Object> objPostProc = (
new ObjectPostProcessor<Object> () {
public Object postProcess(Object bean) throws BeansException {
System.out.println("BeforeInitialization : " );
return bean; // you can return any other object as well
}
});

final PreAuthenticatedAuthenticationToken token = (PreAuthenticatedAuthenticationToken)(invocation.getArguments())[0];
Authentication authentication = (new AuthenticationManager(){
@Override
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
return (new AuthenticationManagerBuilder(objPostProc)).getOrBuild().authenticate(authentication);
}
}).authenticate(token);
return authentication;
}

}).when(authenticationManager).authenticate(Matchers.any(Authentication.class));



Verify 사용법 : test된 코드들의 횟수체크.. . REF

  - verify ( object,  atMost/never/times/atLeast/timeout ).함수명(  any(param) OR eq(param) ) 등.


InOrder  :  object간 순서 체크. 

verifyNoMoreInteractions : mock의 행동 다 검증했는지 확인.


Posted by yongary
,

thymeleaf 기본.

FRONT-END 2016. 12. 19. 22:18

REF-Tutorial

REF기본:

REF-dateForamtter등 발전된기능  {{}}:dateFormatter

(단, 이경우는 WebMvcConfig.java나 xml등에 addFormatter override나, formatter지정이 필요. Ref안에 xml은 있음)


spring의 thymeleaf를 통해  java의 EL을 html에 사용하는 듯한 느낌으로 사용할 수 있다.


@{ }로 사용하는 Variable expression은 java의 EL과 동일하고,

그 외에도 다음과 같은 것들이 있다.


  • ${...} : Variable expressions     - iterator처럼 반복도 지원된다.
  • *{...} : Selection expressions.   - th:object = ${book}과 같이 $로 선택된 object내에서 동작한다.  
  • #{...} : Message (i18n) expressions. - 다국적 메시지 지원.
  • @{...} : Link (URL) expressions.  -변수 파라미터도 가능하고, 상대경로 URL도 가능
            ex)  th:href="@{'/app/user/'+${user.id}+'/bustickets'}
  • ~{...} : Fragment expressions.  - 주로 div안으로 삽입 가능.


thymeleaf 로 form을 submit할 때는 다음과 같다.   REF

<form action="#" th:action="@{/greeting}" th:object="${greeting}" method="post">
    	<p>Id: <input type="text" th:field="*{id}" /></p>
        <p>Message: <input type="text" th:field="*{content}" /></p>
        <p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
    </form>

@{/greeting} : 처리할 URL

${greeing} : model형태로 넘길 object

th:text 보다는 th:field를 써야 object매핑이 되겠군요.



<table if  사용법>   REF

<td th:if="${member.status} == '1'" th:text="Active"></td>
<td th:unless="${member.status} == '1'" th:text="Inactive"></td>

<a th:if="${history.myProject.payType eq 'credit_card'}"

==> { }안에서 string비교시 eq도 사용가능.



<switch >

<td class="col-sm-2" th:switch="${ticket.status}">
<span th:case = 'unused'> "Unused"</span>
<span th:case = 'used'> "Used"</span>
<span th:case = 'unknown'> "Unknown"</span>
</td>


<enum사용시>

<td class="col-sm-1" th:if="${ticket.type == T(my.constant.TicketType).PAID}" th:text="Paid"></td>

${ticket.isExpired()}와 같이 public 함수도 사용이 가능하다. 


==고급===

[[ ]]  in-line 프로그래밍.  REF

${{ }} 자동변환.  REF


==th 함수==

${#strings.isEmpty(...))}

${#lists.size(...)}


th:block  - 매우 유용. 전체 block을 if로 묶어서 나타내거나 숨길 수 있음.

  <th:block th:if="${@environmentHelper.isBeta()}">
   각종 javascript등.. 코드

</th:block>


Posted by yongary
,

spring boot

springBoot gradle 2016. 12. 18. 01:07

설치는 SDKMAN 이나 Brew등으로 가능.

$spring --version 으로 버전확인 가능.

$spring shell  :  sh도 제공


하지만, 대부분 IDEA를 이용하므로,

IntelliJ를 이용할 경우, gradle프로젝트를 만들고, springboot는 dependency로 삽입하면 된다. REF




<어노테이션>

@SpringBootApplication : component-scan 과 자동config제공.

  - @Conditional 도 가능( jdbcTemplate과 같이 dataSource존재여부에 따라...조건부 Bean제공 가능)

한데 자동 config은 이런식으로 Tomcat, ORM, web매핑(/static) 등으로 classpath등을 보고 자동판단한다.


*물론 이러한 자동config도 override를 통해  수정할수 있다.(@Configuration)


<빌드 & run - gradle 사용시>

 $ gradle bootRun : 빌드와 run동시 수행.

    = $gradle build + $java -jar build/libs/..-0.0.1-SNAPSHOT.jar(or war)


maven :  $spring-boot:run

               

             ($ mvn package ) : just package



 <설정>

application.properties는 첨엔 비어있으므로 필요한걸 추가하면 됨.

dependency가 2개가 있는데(gradle.plugin 등)

  - 위에껀 spring boot plugin dependency이고

  - 밑에껀 starter dependency 이다.   (참고로 maven은  순서가 바뀌어있지만.. plugin tag보면 알수 있음)


  - dependency 일부를 제거하고 싶을 땐,  exclude group등으로 가능.


 


 <TEST용 어노테이션>

@WithMockUser

@WithUserDetails


@WebIntegrationTest     


@Value (${local.server.port}) 등도 spring에서부터 사용가능.


물론 웹은 Sellenium과 연동테스트 된다.




<groovy> - C L I 와 궁합이 잘 맞음

Grabs.groovy 파일에 아래 3줄만 넣으면 spring-boot가 자동으로  못한 것들도, startup 시에 dependency를 자동으로 넣으면서 구동 가능. 

  @Grab("h2")

  @Grab("spring-boot-starter-thymeleaf")

  class Grabs {}  


==> 그 후에  $ spring run .  


 

Groovy로 test unit작성 시에는.. 

 $ spring test tests/myTest.groovy   로 하나 실행 혹은

 $ spring test tests  로 폴더통째로 실행 가능.



<패키징>

 $ spring jar MyProject.jar 하면 jar로 패키징 됨.. 


   war는 ?

   -gradle 의 경우 

      war {

baseName = 'readinglist'

version = '0.0.1-SNAPSHOT'

}

  - maven 의 경우

    <packaging> war </packaging>  

  

 만 추가하면 된다.



<Actuator>

CLI 환경에선 @Grab('spring-boot-starter-actuator') 추가하는 방법이 간단함.


그리고 Actuator중에선 아래 3가지가 특히 유용하다. . 

https://localhost:8080/beans  - 모든 bean과 dependency.  

https://localhost:8080/dump  - 모든thread 현황 

https://localhost:8080/trace   


그 외 enable을 시킨후에

curl -X POST http://localhost:8080/shutdown 명령어로 CLI상에서 shut-down도 가능하다. 



SSH 로도 actuator접속이 가능한데

@Grab("spring-boot-starter-remote-shell")  이런형태로나 maven/gradle에 dependency추가 후

$ ssh user@localhost -p 2000 하면 된다.






Posted by yongary
,

six2six FixtureFactory

java core 2016. 12. 12. 17:47

Unit 테스트시에 가짜 object를 만든다.

Template을 이용해서, class를 기본으로 object 데이타를 만든다.  REF




 Template을 이용하거나

  

     ClientTemplateLoader implements TemplateLoader{


@Override

public void load(){


}


Fixture.of(My.class).addTemplate("valid", new Rule(){{

}});

     }




 Fixture class안에서 ObjectFactory를 이용하게 되고.


     class Fixture {

         

        @Override

         ObjectFactory from(class<?> class){

    return new ObjectFactory(of(clazz)); 

}




Test시에는 아래와 같은 방법으로..  object를 만들어서 사용할 수 있게 된다.


  Fixture.from(My.class).gimme("new")    



- (물론)위처럼 소스에서 하나씩 생성할 수 있지만...


- Regex를 이용한 Rule을 이용해서도 만들 수도 있다. 

- Fixture 를 YAML로 저장해 놓고 일괄 생성할 수도 있다.



Posted by yongary
,

google Guava

java core 2016. 12. 8. 23:53

guava-api


Guava는 열대과일로서 분홍색 빛을 띤 주스로 즐기기기도 하는데,

구글에서는 guava library를 통해, java 에 없는 편리한 기능들을 진작부터 만들어왔고,

일부가 java7, java8등에 반영되기도 하였다.


거론되는 장점들은 다음과 같다. (추후 test후 재정리 예정)


1. MultiMap

 - 기존 Map이 <key,value>인데 반해,  MultiMap은 <key,v1,v2,v3,v4...>라고 볼 수 있다. 

   여러모로 편리하다. 속도도 구글이 만들었으니 빠를것 같긴 한데...   


2. ImmutableMap  : 

  - ImmutableMap.of( "A", ImmutableMap.of("A-1","A-2") )  ; 

  이런식으로 사용해서, data가 바뀌지 않는 Map 이 있어 test시에 유용하다.

    

  => ImmutableList.of("A","B"); 도 유용하다. (이거도 guava)


3. Ordering이 아주 편리하다고 한다. 



4. Maps.uniqueIndex  - 중복없는 Index 제공해주므로 편리.

    Maps.newHashMap() - nested Map 을 한번에 생성해서 편리.  REF (이전글이라 test필요) 



5. CharMatcher 가 아주편리하다고 한다.  regex를 대체할 수 있나 본데....



스트림에서 유용

 .stream().collect(GuavaCollectors.toImmutableMap

Posted by yongary
,

jackson (ObectMapper)

java core 2016. 12. 7. 17:49

Java 용 json parser로 가장 많이 사용되는 것이 jackson이 아닐까 싶다. : REF

 

jackson2 가 spring 4에 포함되면서,  RestController같은 경우 Object만 return 하면 자동으로

    MappingJackson2HttpMessageConverter에 의해 json으로 변환된다. : REF 

    ( 단, 모든 member변수에 gettersetter가 있어야 한다 - 이게 귀찮으니.. Lombok이 쓸만하다)

 

 

(복잡한 List<Object> 사용시에는 는)

     itemList = objectMapper.readValue(StringData, new TypeReference<List<MenuItemVo>>() {});

 

 

 

간단한 사용법은 다음과 같다. 

 

 

클래서 선언이 다음과 같을 때,

class MyObject{

String name;

int age;

}

 

import com.fasterxml.jackson.databind.ObjectMapper;

<json ->  java Object 방법>

 

   ObjectMapper mapper = new ObjectMapper();

   MyObject my = mapper.readValue ( file or URL or String , myObject.class);

  

   

 

<java Object -> json 방법>

  

  MyObject my = new MyObject("name", 12 );

  String jsonStr = mapper.writeValueAsString ( myObject )

  

  결과는 

  {"name":"name", "age":12 } 로 되는데

 

  좀 이쁘게 개행도 포함하고 싶으면

  String jsonStr = mapper.writeWithDefaultPrettyPrinter().writeValueAsString ( myObject );   으로 한다.

 

 

<변수명이 좀 다를때>

objectMapper.setPropertyNamingStrategy(     PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);

20년에 위에껀 deprecated되고. 아래와 같이 하면 snake_case 를 camelCase로 변환됨. 단 snake_case는 소문자임.

    @Data
    public static class Camel {
        String userName;
    }

    @Test
//    @Tag("excludeBuild") //테스트시 comment 필요.
    public void mapperTest() throws Exception{
        
        ObjectMapper mapper1 = new ObjectMapper().setPropertyNamingStrategy(
                PropertyNamingStrategy.SNAKE_CASE);
        Camel camel1 = mapper1.readValue ("{\"user_name\":\"Kim\"}", Camel.class );

        log.info("Camel1:" + camel1);

개선: 아래로 하면 대문자도 되는 듯

+        mapperDome.setPropertyNamingStrategy(new PropertyNamingStrategies.SnakeCaseStrategy());

 

 

spring등에선 @JsonProperty로 변환용 변수명을 설정할 수 있지만,여러개일 경우 PropertyNameStrategy 설정이 매우 유용하다.

<null은 제외>

@JsonInclude(JsonInclude.Include.NON_NULL) 

<LocalDateTime 변환>

@JsonSerialize(using = LocalDateTimeJsonSerializer.class) : Custom Serializer 이용. 

public class LocalDateTimeJsonSerializer extends JsonSerializer<LocalDateTime> {
    private static final DateTimeFormatter YYYY_MM_DD_HH_MM_SS =
            DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");

    @Override
    public void serialize(LocalDateTime localDateTime,
                          JsonGenerator jsonGenerator,
                          SerializerProvider serializerProvider) throws IOException {
        jsonGenerator.writeString(localDateTime.format(YYYY_MM_DD_HH_MM_SS));
    }
}

 

<Object Copy>

import org.apache.phoenix.shaded.org.apache.commons.beanutils.BeanUtils;

 

try {

 //멤버type과 이름이 딱맞는 애들만 쭉 copy해준다.

BeanUtils.copyProperties(destObj, srcObj);  

} catch (Exception e) {

e.printStackTrace();

Posted by yongary
,

Service-as-a-VM & Docker

Spring 2016. 12. 3. 03:34

서비스를 개발하다 보면, 여러개의 서브-서비스로 나누어지게 되고 개발도 따로 하게되는 문제가 있지만,

배포에서 큰 문제가 된다. java version이 다르다던가 하는 사소한 문제부터 복잡한 수많은 문제가 생기게 되면서

배보다 배꼽이 큰, 즉 개발보다 deploy가 더 어려워지는 경우도 발생이 되기 때문에,


이런문제를 해결하는 개념으로 Service-as-a-VM 이 등장하였다.

(넷플릭스에서는  AMI 패키지 방식으로 아마존EC2에 배포를 한다) AMI=아마존 머신 이미지.



 그러나, 

VM자체도 부하가 크고 배포도 상당히 어렵기 때문에,  

간단한 파일로 배포를 하고, 프로세스 형태로 동작하는 가벼운  Docker 가 훨씬 더 유리하게 되면서

spring-boot 에 Docker를 결합한 방법이 많이 사용되고 있다.  REF(source 포함)




<Docker>한글REF REF

 


Docker image는 read-only 파일시스템이다. 

   layer  구조라서 배포시에 없는 layer만 배포하면 되고, 이미지 생성도 필요한 것만 되므로 매우 빠르다


Docker container 는 1개 또는 몇개의 sandboxed process로 이루어진  running image이다.  즉 프로세스라고 보면 된다.

  container 단위로  포트 등이 격리가 된다.  



Posted by yongary
,

Orika - the mapper

java core 2016. 12. 2. 15:54

http://orika-mapper.github.io/orika-docs/



1. mapperFactory.classMap(Aclass, Bclass)

         .byDefault()  - 이름이 같은애들 자동 매핑

         .register()  - MapperFactory()에 등록.


        - 그 외 exclude()나 1Direction으로 map하는 방법도 존재.

        - 한쪽이 array라도 매핑가능. (index or first, last 이용) 

        - 한쪽이 classB의 List<A> 라도 가능  Bfield{ fieldOfA }

        - 한쪽이 Map<blabla,blabla2>라도 가능.  field{key}, field{value}

        - null 매핑 on/off도 가능.

        

- in line property:   user:{getName('user')|setBlaBla .. }  지원.

- 프로그래매틱하게 할 수 있도록, Property.Builder 지원.

- 상당히 복잡한 경우를 위해  (Introspector)PropertyResolver  존재.



2. mapperFactory.getMapperFacade()

    B = bMapper.map (A)


3. BoundMapperFacade< A, B>  bMapper = mapperFactory.getMapperFacade ( A,B)  :  성능이 좋음. 

   B = bMapper.map (A)






Posted by yongary
,

Lombok

java core 2016. 12. 2. 15:53

https://projectlombok.org/


@Data  만 추가하면  Creator/Getter/Setter/toString/hashCode 메쏘드들이 다 있는 것으로 간주됨. (핵심)


그 외

@Getter, @Setter, @Cleanup (Finally로 제거해 주는 효과)




<Constructor 3가지 옵션 > REF


@AllArgsConstructor

@RequiredArgsConstructor - parameter있는 생성자 만들어 주는데, 해당 필드에 @NonNull 추가 필요.

@NoArgsConstructor




상속시에는 부모클래스의 Field들도, equals & hashCode()함수에 포함하기 위해서 아래가 필요.

  => 단, 부모클래스도 자식클래스도 @Data를 사용해야 한다. 

@EqualsAndHashCode(callSuper=true)


Posted by yongary
,

Macbook 처음사용시

Mac 2016. 12. 1. 21:31

<스크롤>

터치패드와 매직마우스의 스크롤을 "자연스럽게"를 끄면 window와 동일하게 동작한다.

스크롤은 손가락 2개로 할 수 있다.


<우측클릭>

터치패드에서 손가락 두개로 누르면 된다.. 마우스는 오른쪽 귀퉁이 누르게 설정가능.


<런치패드 : f4 >

 손가락 4개를 펼치면 실행. 끌때는 반대로.


<독 : Dock> 세로선을 잡아서 끌면 크기를 줄일 수 있다



<미션컨트롤 : f3> 손가락 3개를 쓸어올린다. 끌때는 반대로


<터미널>   spotligit( 옵션+스페이스) 에서 terminal입력. 

                 


<단축키>

  • +Q: 창 닫기(quit)
  • +,: (현재 프로그램에 대한) 설정
  •  Ctrl+Space: 한영전환
  • + Shift+4: 영역 스크린샷
  • + Shift+4Space: 창 스크린샷
  • command++: 화면 확대
  • command+-: 화면 축소
  • Ctrl+Option+Space: 검색 창 열기
  • command+Space: Spotlight 검색창


<Library 폴더가 안보일때>

Finder->Go menu->Home   select  --->    View menu -> Show View Option 에서 Library 선택. 


Posted by yongary
,

[java8 in action  일부 참고]

 

한마디로, Collection은 data라고 한다면 Stream은 computation이다.

 

 

<특징 2가지>

1. PipeLining

  Stream 은 unix명령어인 pipeline( "|" ) 과 같이 순차적으로 data를 처리한다. 

  (단, 실제로 unix에선 pipeline을 순차적으로 처리하지 않고, 몇줄이라도 조금씩 output이 있으면 동시처리를 한다)

 

2. Internal iteration 

  - 코드상 눈에 보이지는 않지만, 내부적으로 iteration이 일어난다.

  - 단 한번 traverse가 가능하다.  이게 끝나면 다시 new stream을 가져와야 한다.

 

 

<operation 종류> - Builder패턴과 유사하게 chain을 통해 중간단계를 여러개 거쳐 최종물 생성.

 

1. Intermediate Operation : Terminal Operation을 만나야만 동작을 한다. 

 - map, filter 등과 같이 중간에 데이타를 가공한다.

 - sorted, distinct  

 - limit, skip

 - 한꺼번에 처리가 되는만큼, 내부 동작 순서는 최적화해서 바뀐다. 

  (예: limit먼저 실행하고 다른 것 들 실행. map과 filter를 merge해서 실행)

  

 

2. Terminal Operation : 반드시 이걸로 끝나야 한다. 그래야만 intermediate Operation도 동작을 한다.

 - collect   (주로 List, Map, an Integer 리턴)

   

   ㅁ Map으로 변경

someList.stream() .collect(Collectors.toMap(AClassName::getMyCode, AClassName::getName))

   ㅁ GroupingBy

someList.stream().

.collect(Collectors.groupingBy(  AClassName::getName  ) )

 

=> Map<String, List<Person>> 형태로 리턴됨.

 

   

   ㅁ guava와 함께 쓰면:   .collect(GuavaCollectors.toImmutableList());

jp.skypencil.guava:helper:1.0.1
<dependency>
  <groupId>jp.skypencil.guava</groupId>
  <artifactId>helper</artifactId>
  <version>1.0.1</version>
</dependency>

 - forEach  (void 리턴)

 - count   ( long 숫자 return)

 

 

 

ofNullable함께 사용: REF

map으로 예제: REF

Function protoype 이용예제: REF

 

 

 

<철학>

java8에서는 stream을 이용해 multicore 개발의 복잡함과,  multihread로 인한 오류확률을 줄이고자 한다. 

          

 -> stream은 multicore에서도 parallel한 환경에서 transparent하게 작업이 가능하다. 

 일반적으로, .stream()에서 .parallelStream()으로만 바꾸면, 별도의 multithread코드 없이 parallel작업이 된다.

 

 

 

 

<forEach 예제>

 

  "hey duke".chars().forEach (c -> System.out.println((char)c));    My-Ref

  someStream.forEach (  (oneItem) -> {

oneItem.weight -= 1; 

oneItem.height += 10;

  }

 

단, 단순한  forEach는 Collector 에도 있으므로,  list.forEach( item -> blabla ); 가 가능함.

 

Posted by yongary
,

Armeria

network개발 2016. 11. 15. 14:58

<주로 사용하는 기능들>

HttpResponse.aggregate() : CompletableFuture로 전환.

예) httpClient.get(uri.getPath()).aggregate()


Decorator: req나 response를 살짝바꾸는 역할. SoC(Seperation of Concern)가 가능.

- req,res가 같을 때는 SimpleDecoratorService를 상속 - req나 res의 type의 바뀔때는 DecoratorService를 상속 - 간단한 decorate()용 lambda도 있음.

<유용한 class - armeria thrift용 개발시에도 사용가능>

com.linecorp.armeria.common.metric.MetricLabel
      - Collector같은 애들에게, 이름을 붙여서, lambda에서 사용시 지정할 수 있다.


common.util.Functions.voidFunction (Consumer or BiConsumer)   : Consumer를 Function으로 변환. 

                                    .compose (Func12, Func23) -> Func(1,3)으로 변환.   그 외에도 각종 compose들 존재. 


common.HttpHeaders;

common.RequestContext;

server.logging.LoggingService;


<기존 netty꺼긴 하지만..유용class>

io.netty.util.AsciiString;


<Connector>

armeria's TomcatService always create a Request/Response instance.
<-> Tomcat's Http11Processor create them only once and this processor instance will be recycled.




REF-github


- 기존의 netty와는 달리 Http2.0을 지원한다.   HTTP2.0-REF
    (기존의 HTTP1 서비스와 호환성도 유지)

- JNI-based socket I/O 

BoringSSL-based TLS connections

- (Apache) Thrift  호환
   THttpClient와 호환. (Thrift-Over-Http)   

    참고:  Thrift - Binary communication을 위한 IDL로서 RPC사용을 위해 facebook에서 개발.

- Java EE Web Application이랑 호환.  (same TCP/IP port)



Posted by yongary
,

F,P,S & FunctionalInterface

java8~ 2016. 10. 23. 11:20

  

java 8 경험자 Tip:   REF-SITE ,  http://okky.kr/article/357825  


 

1. Object리턴시에  null처리가 쉽도록, Optional.ofNullable() 사용.

   예제)  

           Optional<Soundcard> soundcard = Optional.ofNullable(mabyeSoundcard); 
           if(soundcard .isPresent())

   System.out.println (soundcard.get()); //get Real Value from Optional

또는

soundcard.ifPresent(System.out::println); 도 OK.

soundcard.ifPresent(card -> map.put(card)); 도 가능.


      Soundcard soundcard = mabyeSoundcard.orElse(new Soundcard("defaut"));

- orElseThrow(IllegalStateException::new); 도 가능

 

Optional.map(s->s.getID()).orElse()도 굿.  orElseGet( blabla) 도 있음. 

Optional.flatMap : content가 또 Optional일경우 벗김-  REF2번참조


 

2.  mutable인 String[]리턴 대신에, immutable인 Stream<String> 리턴.  REF-SITE

  

Stream<String> words = Stream.of("Java", "Magazine", "is", "the", "best");

or

Stream<String> words = Arrays.stream(arrOfStr); //String[] arrOfStr = {"A","BB"}

 

 

   예제) "hey duke".chars().forEach (c -> System.out.println((char)c));

           Stream<Character> sch = "abc".chars().mapToObj(i -> (char)i);     (char)가 Character로 autobox됨.


 

3. Function Reference & Predicate Reference. (함수의 파라미터로도 넘길 수 있게 됨)

   

   Predicate의 경우 scala와 거의 유사한 방식으로. boolean리턴하는 method define후, 이 것들을 넘길 수 있음. 

 


  Function<String, Integer> f = Integer::parseInt;
  Integer result = f.apply("123");

 

  Predicate<String> p = str::equals;
  p.test("world");

 

 Supplier< > s = 

 s. get(); 

 


 4. interface  : 기존 interface를 좀 다르게 FunctionalInterface로 사용가능. @FunctionalInterface 도 존재.

   => 이걸 파라미터로 넘길수도 있다.  (function도 넘길 수 있듯이)  : 음 class도 넘길수 있으니 당연한 건가..

   

    FunctionalInterface REF -> abstract Method는 한개만 존재

    javaInAction8책에서는 Validator Strategy및 8.2장 참조.




Posted by yongary
,

mySql Tip

BACK-END 2016. 10. 12. 17:00

참고: mySql에서 

  - Key키워드도 index를 의미한다.  

     (왜 key라고 부르면서 index와 동일한 건지? 이유가 있을텐데.. 아직은 모르겠음)


 

mySQL을 쓰면서 하면안되는 일들 17가지 blog : REF

 

요약하면

- 파티션/복제/Caching계획을 세우기

- Explain포함 Profile링과 벤치마크 쓰기

- 인덱스 layout과 쿼리 cach 이해하기

- Stored procedure보다는 Prepared구문&Dynamic SQL사용

  (MySQL은 한번 연결해서 여러번 사용해야 효율 적)

- AUTO_INCREMENT 꼭 사용

- ON DUPLICATE KEY UPDATE 꼭 사용

 

정도이다.

 

시간을 가지고 개인적인 의견 하나씩 추가 계획.

 

 

Posted by yongary
,

구글 SLAM 공개

IT 2016. 10. 11. 13:39

구굴이 SLAM(Simultaneous Localization and Mapping)용

오픈소스 지도기술 Cartographer를 공개하였다.



SLAM: 로봇이 위치를 인식해서 즉석해서 지도를 작성.

- 무인자동차, 로봇청소기, 드론등에서 활용



이제 일반인도 드론이나 로봇청소기 제작시 본 API를 활용해

야외나 실내의 맵을 실시간으로 만들어 

로봇의 탐색경로를 쉽게 최적화할 수 있을 것으로 보인다.



참고사이트: http://www.bloter.net/archives/265140

시연영상: https://youtu.be/DM0dpHLhtX0 

Cartographer GitHub: https://github.com/googlecartographer 

                  소개: https://opensource.googleblog.com/2016/10/introducing-cartographer.html 





Posted by yongary
,

auto login + data Add

java core 2016. 10. 7. 17:55

java로 web페이지에 login을 해서 session을 유지하면서

data를 form방식으로 입력하는 예제입니다. 


(login페이지는 ajax/json리턴 방식이고, data add 페이지는 일반적인 form방식을 가정)

login세션 유지는 cookie에서 JESSIONID를 읽어서 다시 세팅해야 합니다.



data는 file에서 하나씩 읽어서 web상으로 입력하는 형태입니다.


=========java source=====================

import java.io.BufferedReader;

import java.io.File;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.OutputStream;

import java.net.HttpURLConnection;

import java.net.URL;

import java.util.List;

import java.util.Map;

import java.util.Scanner;



public class LoginAndInsert {


public static void main(String[] args) throws Exception{

//LOG IN

URL url = new URL("http://221.100.200.180/loginProc");

HttpURLConnection conn = (HttpURLConnection)url.openConnection();

conn.setUseCaches( false );

conn.setConnectTimeout(1000);

conn.setRequestProperty("Accept", "*/*");

conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");

conn.setRequestMethod("POST");


//data setting

String postData = "user_id=admin" + "&user_pwd=" + "a123456789";

System.out.println(postData.toString());

conn.setRequestProperty("Content-Length", String.valueOf(postData.getBytes("UTF-8").length));

conn.setRequestProperty("X-Requested-With", "XMLHttpRequest");

conn.setDoOutput(true); //POST

conn.connect();

OutputStream outputStream = conn.getOutputStream();

outputStream.write(postData.getBytes("UTF-8"));

outputStream.close();

InputStream inputStream = null;

try { 

inputStream = conn.getInputStream();

}catch (IOException ioe){

ioe.printStackTrace();

}


String m_cookies = "";

String line3;

      BufferedReader reader = new BufferedReader(new 

                                    InputStreamReader( inputStream  ));

      while ((line3 = reader.readLine()) != null) {

         System.out.println(line3);

      }

   

      //save Cookie


      Map<String, List<String>> imap = conn.getHeaderFields( ) ;

      System.out.println(imap.size());

   

   

 if( imap.containsKey( "Set-Cookie" ) ) //"Set-Cookie"

 {

    List<String> lString = imap.get( "Set-Cookie"); //"Set-Cookie" );

    for( int i = 0 ; i < lString.size() ; i++ ) 

    m_cookies += lString.get( i ) ;

 }

   

       System.err.println("Cookie:"+ m_cookies);

   

 //find JSESSIONID

 String[] cookieTokens = m_cookies.split(";");

 String JSESSIONID = cookieTokens[1].substring( cookieTokens[1].indexOf("D=")+2 );

   

 System.err.println("JSESSIONID:"+ JSESSIONID);

   

 reader.close();

 Thread.sleep(500);


//Data process

Scanner in = new Scanner(new File("./dataFile.txt"));

int i=0;

while ( in.hasNextLine() ){

String line = in.nextLine();

//System.out.println(line);


String[] token = line.split(",");

String id = token[0];

String phone = token[1];

String name = token[2];

String pw = "tel" + phone.substring(3);

if (id.length() < 4) System.err.println(id);

if (pw.length() < 10) System.err.println(pw);


//INSERT by POST

url = new URL("http://221.148.199.79/admin/normalUserMng/registProc");

conn = (HttpURLConnection)url.openConnection();

conn.setUseCaches( false );

conn.setConnectTimeout(1000);

conn.setRequestProperty("Accept", "*/*");

conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");

conn.setRequestMethod("POST");

conn.setRequestProperty( "Cookie", "JSESSIONID="+JSESSIONID );

conn.setInstanceFollowRedirects(false); //For cookie


//data Setting

postData = "act=R" 

+ "&user_id=" + id

+ "&user_pwd=" + pw

+ "&user_name=" + name

+ "&user_phone=" + phone

+ "&is_active=1"

+ "&user_domain=ktait.com";

conn.setRequestProperty("Content-Length", String.valueOf(postData.getBytes("UTF-8").length));

System.out.println(i++ + "====== "+name + "," + id + "," + phone + "," + pw +",     "+ postData);

conn.setDoOutput(true); //POST

//conn.setDoInput(true); //POST

conn.connect();

outputStream = conn.getOutputStream();

outputStream.write(postData.getBytes("UTF-8"));

outputStream.close();


String line2;

reader = new BufferedReader(new 

                                    InputStreamReader(conn.getInputStream()));

while ((line2 = reader.readLine()) != null) {

     System.out.print(line2);

}

reader.close();

System.out.println("");

Thread.sleep(100);

}

  }

}



Posted by yongary
,

한국과 일본 LTE

통신 2016. 9. 27. 14:02

한국과 일본의 LTE 주파수가 겹치는 부분도 있고, 다른 부분도 있지만

대체적으로 겹치는 부분이 존재하기 때문에,

 

한국폰을 들고 일본에 가서 가입해서 사용할 수 있다.

(보통 APN을 설정해야 한다.

  - APN: AP의 명칭으로 data망을 잡을 때 사용하는 중계기이름) : 설정경험site

 

 

<주파수 설정>

주파수가 다르지만 자동으로 되는폰과 안되는 폰이 있는데, 자동으로 LTE가 안잡히는 폰은 설정을 할 수 있다.

 

KT스마트폰 삼성폰인 경우  자동으로 안되면

통화 dialer에서 319712358 입력하고 비번에서 774632 입력하면 된다.

 

=> 그 후, Network Setting -> Network Mode에가서

일본 LTE주파수 참고해서 고르면 된다.  도코모의 경우 B1으로 선택하면 된다. 아니면 자동으로

 

    LG폰:  5457#* + 모델명3자리 + #      (5457대신 3845인 폰도 존재)

    펜텍폰:  ##7788#

 

<일본 MVNO>

 

B모바일 = 도코모의 mvno  :  개통경험사이트

=> B모바일은 15년 2월 기준으로 속도가 느림: site

빅심(IIJmio) = 도코모의 mvno  : 좀 믿을만 하겠죠.

 

라인mobile = 도코모mvno : 라인free와 커뮤니케이션free(facebook포함) 요금제 존재. : site

               -> 라인mobile 정식오픈은 16년 10월 1일.  메신저 많이 쓰는 사람 이게 유리할 듯하네요
               요금제 + (월)700엔 내야지 전화번호까지 줌. 

 

 

<참고 사이트>

일본 LTE주파수 - 참고사이트

 

한국LTE 주파수-  참고사이트

 

일본 MVNO 비교 - 참고 사이트

 

SKT폰도 비번만 다르고 동일함 - 참고사이트

 

 

Posted by yongary
,

netty

network개발 2016. 9. 26. 13:49

netty =  Async전문 java network Library

   - UserGuide(4.0 wiki)  ,  한글번역본

 

   - 3.1 Chapter2 Architecture Overview

 

   - 4.0javadoc   5.0alpha2_javadoc

 

 

netty의 핵심 Interface

 - Channel

 - ChannelFuture

 - ChannelHandler

 - ChannelHandlerContext

 - ChannelPipeline

 - EventLoop

 

 [그 외]

 - ChannelBuffer

 기존 java nio의  ByteBuffer를 쓰지 않고, ChannleBuffer를 이용해
1. flip()호출이 필요없으며 사용자정의 buffer type이 가능하다.

2. zero-copy가 가능하다.(SG-DMA NIC필요) :  zeroCopyRef

zero-copy: disk->커널메모리->유저메모리->커널메모리->NIC  이던것을

               => disk->커널메모리->NIC 방식으로 copy. (File을 socket으로 쏠때 특히 유리)

3. StringBuffer처럼 dynamic Buffer이다.

 - ChannelFactory

NIO-TCP / OIO-TCP / OIO-UDP /Local 통신등을 ChannelFactory선택만으로 쉽게 swithcing가능.

 

기본예제: jdm.kr

 

 

Posted by yongary
,

[Netflix 블로그:  곧 open Source로 공개 예정]

http://techblog.netflix.com/2016/09/zuul-2-netflix-journey-to-asynchronous.html?m=1 

 

 

Posted by yongary
,

Git advanced.

springBoot gradle 2016. 9. 12. 15:21

git기본은: http://yongary.tistory.com/151




http://learngitbranching.js.org/   graphical 공부site


  - git의 commit은 매우 가볍다. 이전버전과 차이점 delta만 관리. 

  - local 관리버전을 master라고 부름.. (remote가 origin 인 듯)

  - branch는 단지 commit으로의 pointer이다. (storage/memory overhead없음)

git branch branchName해서 만들고 + git checkout branchName 한 다음에 git commit해야 함. 

: or  git checkout -b branchName 하면 branch를 만들면서 checkOut도 같이 함.

  - git merge 방법:

: git branch bugFix

:    git checkout bugFix

:    수정후 git commit

: git checkout master

:    git commit  (이 단계가 왜 필요한지?? 연구 중)

:    git merge bugFix

   

  - git rebase : 패러랠 branch작업을 sequential한 history로 변환시켜 줌. (대단하네요)

              현재 bugFix* checkout된 상태에서, 

: git rebase master 하면 sequential로 되고 그 후,  (현재 bugFix*가 계속유지됨.)

: git rebase bugFix   (master*가 current로 바뀜. sequential상에서의 merge효과가 생김. ) 

      


           

<기억할 명령어>

git checkout FileName  : 파일 하나 Revert

git checkout -- FileName  :  파일 하나 Revert from -- branch. (need test)  REF



git branch -v :  branch상태 확인가능.. 로컬이 앞서가면(commit 이 많으면 ahead 2 이런식으로 나옴)  : REF

==>  $ git fetch --all; git branch -w   이렇게 사용해야 최신 정보가 비교가 됨.



Posted by yongary
,

<동작구조>


Request --->  DispatcherServlet  ---------------------------> Haldlermapping

                                     ----------------------------> Controller

                                     <--Model & view name--

                                     ---------------------------->ViewResolver

                                     ----------------------------> View

      response <--------------------------------------------



<어노테이션>  annotation-Driven.   @Component로 하고,  component-scan으로 자동으로 Bean으로 등록. 

  @Controller

  @RequestMapping( { "/", "/homepage" } )   =>  controller에서 이 String array를 통해 여러 request 수용가능.

  public class myController {....


 

  -param 처리  /show?my_id=12345 URL처리하려면

   public String show( @RequestParam("my_id") long myId, Model model) {
   }

  - URL방식 param처리

   @RequestMapping(value="/{my_id}", method=RequestMethod.GET)
   public String show( @PathVariable("my_id") long myId, Model model) {

   }





<Spring's MockMVC>

  myRepository mockRepository =

     mock (myRepository.class);

   when (mockRepository.findData())

     .thenReturn(expectedData);


     .setSingleView  .build  .perform  .andExpect 등.   



<Web controller에>

 @Autowired 생성자. 가능.    #146 



  Model: View로 전달할 key,value Map.이며 아래와같이 사용함.

   <c:forEach  items="${modelName}" var="oneData">

<c:out value="${oneData.kv1}" />

   </c:forEach>

   => spring에서 만든 sf (spring form) tag library도 존재.
    sf:input 이런식으로 사용하며 Model과 연동이 잘된다. 

   => srping에서 만든 s tag library도 존재

    s:message   리소스 파일등에서 읽어서 메시지 출력.




<ViewResolver>

  InternalResourceViewResolver를 기본적으로 쓰는데, 그 외 UrlBasedViewResolver, XmlViewResolver, 

  TilesViewResolver (Apache Tiles를 이용해 Web페이지 구성, tiles는 t tagLib 사용.),

  ThymeleafViewRelolsver ( Tyhymeleaf = jsp 사용성 개선한 범용 template-th tag 사용하며 html처럼 막 편집가능
        즉, jsp안에 <> <c:> 이런거 섞어쓰면서 오는 <>개수 혼란 등을 피할 수 있음.)
  
  등 10개 이상의 용도에 따른 ViewResolver가 존재한다.

 

 

<기타 & Advanced>

WebApplicationInitializer

- DispatcherServlet 외에 추가적인 servlet나 filter를 등록해서 사용가능.

- onStartup & getServletFilters 메쏘드 override .   (#7.1)

 

multipart는 보통 StandardServletMultipartResolver 를 사용.

 

 

flash attribute: redirect시 Object전달 같은 일회성 data전달을 model을 이용해 지원.

-사용법: model.addFlashAttribute("spitter", spitter);

 


 Web Flow:  spring MVC확장 framework로 flow를 관리한다.

     - status, transitions, flow_Data 의 3개 요소로 구성됨.



Posted by yongary
,

AsyncFileChannel

java core 2016. 8. 28. 21:24

[오늘의 Tip] Java는 call by value이다. (Object의 경우는 reference주소=Pointer주소 가 전달된다)

c++은 call by reference가 있는데, 이 것은 실제로는 reference of reference가 전달된다.



[본론]


jdk 1.7 에 AsynchronousFileChannel class가 있다.  REF


그냥 java 의  NIO를 사용해도 될텐데.. 차이점이 무언인지 분석을 해보자.



..




Posted by yongary
,

Message Digest

IT 2016. 8. 16. 17:08

Message Digest는 간단히 말하면 Message Hashing이다.

- 단방향으로만 동작하고 역방향 유추는 불가.

- 암호 저장, file이 동일한 파일인지 비교하는데 쓰인다.

 

Java Ref - java.security.MessageDigest 존재.

 

 

좀 더 복잡하게 하기 위해서  Ref

Salting- 메시지 앞에 특수값을 삽입. (사용자별로 다르게 할 수도 있음)

Key Stretching-  Digest하고 그 값을 또 Digest하는 multi-chain형태의 Digest.

=> 위 둘을 잘 섞어서 Adaptive Key Derivation Functions 이라고 부른다.

대표적인 게 PBKDF2랑 bcrypt, scrypt가 있다.

이 존재한다.

 

 

Posted by yongary
,

HTTP 2.0

IT 2016. 8. 15. 16:54

REFwiki

 

HTTP1.1이 현재까진 대세인데

HTTP2.0은 2015년 5월에 spec이 발표되었고, 대부분의 브라우저에서 2015년 말부터 지원한다.

  - web site들은 10%미만이 이를 지원.

 

주요 특징.

 - HTTP2.0 서버 Push

: 기존에는 index.html을 파싱하고 나사 style.css, javascript.js를 받지만, HTTP 2.0에서는 서버가 index.html 을 내려주면서 같이 css와 js도 내려줄 수 있다.

 

 - HTTPS over TLS

:원래 https는 SSL기반인데,   2.0에서는 https가  TLS기반(SSL의 브랜치)으로 동작한다.

 

 (SSL vs TLS: REF1,  )

-같은 말이다. 네스케이프에 의해서 SSL이 발명되었고, 이것이 점차 폭넓게 사용되다가 표준화 기구인 IETF의 관리로 변경되면서 TLS라는 이름으로 바뀌었다. TLS 1.0은 SSL 3.0을 계승한다. 하지만 TLS라는 이름보다 SSL이라는 이름이 훨씬 많이 사용되고 있다.

( REF2-의심감)

 SSL - 7.Application Layer 와 4.Transport Layer 간에서의 보안.

 TLS -  서버인증은 선택사항, 반드시 공개키만 사용.

 

 - SPDY (pronounced like "speedy") : TCP pipe는 쓰면서도 TCP와 다른프로토콜을 사용하는데 HTTP2.0 초기에는 SPDY방식으로 HTTP가 바뀔 것으로 제안 되다가 몇가지 문제가 있어 빠진 것으로 보임.

 

Posted by yongary
,

유니코드

IT 2016. 8. 10. 18:02

<UnicCode> REFWiki  REF2

UTF 8  - 가변길이의 유니코드이다.   ASCII영역은 1Byte로 표현되고, 일반적으론 한글은 3Byte로 표현된다.. 드물게 4byte로 표현되는 언어도 있다.

 

UTF 16 - ASCII영역도 2Byte로 표현된다.

 

 

<다른 encoding>


EUC-KR (MS의 CP949는 EUC-KR을 확장) :  한글OS에서만 제대로 보이는 문제 존재. 영문-1Byte, 한글-2Byte 로 고정Length

Posted by yongary
,

SOLID라고 부르며: 굿 REF

 

경험적으론 이미 다 아는 내용이긴 하지만, 

다음과 같이 객체지향 5원칙을 정리한 사람들이 있다.. 글로 보니 새롭군요..

 

REF: 

S- single responsibility principle

O- open-closed principle  :

 - 확장에는 open, 변경에는 close

 

L- Liskov Substitution principle 

  - 어떤 함수 m(p)에서 P클래스의 p instance가 잘 동작하면,  그를 상속받은 C클래스의 c instance도 잘 동작해야 한다 m(c)
 (일반적으로 잘 동작함.   하위 클래스에 부모에게 있는 method가 없거나 다른일을 하거나 하면 문제..)

 

I- interface segregation principle 

 - I/F는 가능한한 기능별로 세분화해서 구현해야 한다.

 

D- dependency Inversion principe

  - 하위레벨 모듈의 변경이 상위레벨 모듈의 변경을 요구하던 관계를 끊음.

 - 상위 클래스에서는 하위클래스 일들을 전혀 할 필요가 없다.

 

 

 

Posted by yongary
,