- She is my neighbor who lives right next to me. We are about the same sage and have a lot in common.
- She is a good listener. She gives me a pep talk.
- She is a butterfly.
- I lose track of time.
- I live in ---
- There are --- in my neighborhood
- My neighborhood is ----
- I recently had a(n) ---- experience in my neighborhood.
- It was --- ago.
- We talked about --- in our neighborhood
- When I was young, there was nowhere to --- in my neighborhood
Q1
You indicated in the survey that you live in an apartment. What is your neighborhood like? Where is it located? Please describe your neighborhood in detail?
A1
I live in the downtown of Seoul. There are many restaurants and supermarkets in my neighborhood. Also, it has a good transportation system. It's only a 5-minute walk to a subway station. My neighborhood is very clean and nice. I feel lucky to live in my neighborhood.
Q2
I would like to know about your neighbors. Who are they? What do they do? How often do you interact with them
A2
I am close with one of my neighbors. Her name is Pia. She lives right next to me. She is a teacher who lives alone. We have a lot in common. I think we get together at least once a week. We usually watch movies together. We also go grocery shopping and go for a walk when we have time. She is a good neighbor who became my friend.
Q3
Can you tell me about an interesting or memorable experience you have had in your neighborhood? Tell me about the experience in detail and explain what made it so memorable.
A3
Yes, I had a special experience. I was taking a walk in my neighborhood last year. When I was walking, I ran into an old friend of mine. My friend in my heighborhood! Can you belive it? We went to the same high school. He told me he was shopping with his family. We met for a drink that night. It was an amazing experience. We became even better friends after that.
Q4
How has your neighborhood changed from when you were young? Describe in detail how it was in the past, and how it is now?
A4
Well.. My current nighborhood is very different from my old neighborhood. When I was young, I lived in the countryside. It was very quiet all the time and it had Limited amenities[어메너티스]. It took more than 2 hours to a grocery store. But now, I live in the downtown. It's a busy city 24/7. Evertything is within walking distance so it's super convenient! I love my current neighborhood!
- 집 문에 들어오면 신발 벗을 공간이 있고, 더 들어오면 왼쪽이 거실과 내 방이 있다. 오른쪽에는 주방과 형방과 부모님방이 있다.
- 그 옆에 발코니와 화장실이 있다.
- 집은 깨긋하고 현대적이다.
스토리라인
- 집의 모습 묘사
- 집에서 가족들과 함께 하는 일
- 방에 있는 가구나 가전제품 묘사
- 최근에 집에 준 변화
표현
I live on the 2 floor of a 10 story apartment.
It gave a new atmosphere to my house.
I have lived here for all my life.
a comfy bed / a brand-new sofa / a second-hand sofa
It was worth the mony
a perfect fit for me
Theare are serveral reasons for my preference.
My house is clean and morden
My home has a living room and three bedrooms
I have a desk and a bed in my room
I recently redecorated my room
It made the room cozier
I usually spend time with my family on weekens
We usually have meals together at home
Sample Question and Answer Scripts
Q1. You indicated in the survey that you live in an apartment. Tell me about your home. What dose it look like? What types of rooms dose it have? Please describe it in detail.
A1.
I live in a 3-bedroom apartment. When you walk[워크] in the front door, you can see a area[에리아] where you can take off your shoes. One the left, there is my room. The living room is also to the left. On the right is a kitchen. Next to the kitchen, you can see a bathroom and a balcony[밸커니]. My house is very clean and modern.
Q2.
Tell me about your bedroom. What dose it look like and what do you keep in it? Use as many details as possible to describe it.
A2.
I think my room is very clean and modern. I love my room because it's only for me. I can have quiet moment all by myself without any distractions. Another reason is that since my bedroom has large windows, I can enjoy breathtaking view and fresh air. When you walk in my room, you can see a bed. On the left there is a dressing table. A desk is also to the left. On the right is a bookshelf. I am very satisfied with my room.
Q3.
It is important for a family to spend time together. When do you spend time at home with your family? What dose your family usually do at home?
A3.
Well... I am very busy during the weekdays, so I usually spend time with my family on weekends. We usually prepare dinner together at home. I help my mother cook and my brother dose the dishes. While having our meal, we often talk about current events. After dinner, everyone relaxes[릴렉시스]. My house is very cozy[쿼우지], so we enjoy spending time there. My brother and I usually play video games together. My parent like to watch TV.
Q4.
Have you made any changes to your house within the last few years? If so, what kinds of changes have you made to your home? Are you satisfied with the changes?
A4.
I live in an apartment and I recently redecorated[리데코레이릿ㄷ] my living room. I replaced the[디] old pillow. The new pillow is soft and cozy. I also decided[디싸이릿ㄷ] to get new furniture. I purchased a new couch[카우치], and matching chair[체이얼]. Finally, I put up new curtain[커른] in the room. I am very happy with my living room now.
void PrintTree(NodeRef root, int depth)
{
for (int i = 0; i < depth; i++)
{
cout << "-";
}
cout << root->data << endl;
for (NodeRef& child : root->childeren)
{
PrintTree(child, depth+1);
}
}
트리 높이 구하기
- 자식 노드의 깊이가 다를 수 있다는 걸 주의 해야한다. (가장 깊은 자식과 루트의 거리가 깊이다)
- 재귀적인 특성을 이용해 재귀함수로 구현
static int GetHeight(TreeNode<string> root)
{
int height = 0;
foreach(TreeNode<string> child in root.Children)
{
int newHeight = GetHeight(child) + 1;
height = Math.Max(height, newHeight); // 높이가 다른 경우 큰값으로 치환.
}
return height;
}
// 깊이(depth) : 루트에서 어떤 노드에 도달하기 위해서 거쳐야하는 간선의 수(aka 몇층?)
// 높이(height) : 가장 깊숙히 있는 노드의 깊이 max(depth)
int GetHeight(NodeRef root)
{
int height = 1;
for (NodeRef& child : root->childeren)
{
height = max(height, GetHeight(child) + 1);
}
return height;
}
814p. 코드 최적화는 일반적으로 아키텍처, 알고리즘 선택과 같이 극적인 향상을 제공하지도 않고, 성능을 향상시키기 가장 쉬운 방법도 아니다. 하지만 진정한 프로그래머가 되는 통과 의례이다. 여러분과 다른 프로그래머들을 제외한 어느 누구도 일반적으로 여러분의 코드가 얼마나 엄격한지에 대해서 신경 쓰지 않는다. 그럼에도 불구하고 프로그래밍 문화에서는 아주 미세하게 효율적인 코드를 작성하는 것은 여러분이 훌륭한 프로그래머라는 것을 증명한다.
818p. 코드를 작성하면서 최적화해야 한다! - 거짓! : 세부적인 최적화를 하느라 너무 바빠서 중요한 전역적인 최적화를 뭇히나는 경우가 생긴다.
820p. 최적화 시기 : 고급 설계를 사용하라. 프로그램을 올바로 만들어라. 나중에 작업하기 쉽도록 모듈화하고 변경이 쉽도록 만들어라. 정확하게 완성되었을 때, 성능 검사하라. 만약 프로그램을 못 쓰게 하고 싶다면, 빠르고 작게 만들어라. 최적화가 필요하다는 것을 알게 될 때까지 최적화를 하지 않는다.
823p. 비효율성의 공통적인 원인 : 입/출력 연산, 메모리 페이징(page), 시스템호출(컨텍스트 스위칭 발생), 인터프리트 언어, 오류
831p. 만약 보다 효율적인지를 알기 위해서 측정할 가치가 없다면, 성능 도박을 위해서 명료함을 제물로 바칠만한 가치도 없다.
827p. 공통적인 연산의 상대적인 성능 비용
Chapter26 코드 최적화
논리구조
답을 알고 있을 때에는 테스트를 중단하라
- break문 사용
빈도에 따른 테스트 정렬
- 거의 항상 참인경우가 가장 먼저 수행되도록 정렬한다.
유사한 논리 구조의 성능을 비교해라
- case문과 switch문의 경우 언어보다 성능의 우위가 다르다. 간단히 말해서 결과를 측정할만한 신뢰할 수 있는 방법이 없다.
복잡한 표현식을 테이블 참조로 대체하라
- 테이블 참조가 복잡한 논리 구조를 따지는 것보다 더 빠른 경우가 있다.
소극적인 평가를 사용하라
루프
언스위칭
- 루프 검사를 밖에서 하는 것을 고려해라
재밍
- 결합가능한 루프를 하나로 묶어라
언롤링
- 루프의 보조 수단 코드의 양을 줄이는 것이다. 하지만 전체 코드량이 늘어나고 가독성이 떨어지는 단점이있다. 또한 코드 최적화에 대한 보증이 없다. 언어나 컴파일러에 따라 상이하기 떄문이다.
루프 내부 작업의 최소화
감시값
- 루프의 지속 중단 여부를 결정 짓는 감시값을 외부에서 정의해서 사용해라
가장 빈번한 루프를 안쪽에 작성해라
강도감소
- 곱셉과 같이 시간이 많이 걸리는 연산을 덧셈과 같이 시간이 적게 걸리는 연산으로 대체해라
c++은 탄생 이후로, 세계에서 가장 넓게 사용되는 프로그래밍 언어입니다. 잘 작성된 c++ 프로그램은 빠르고 효율적입니다. 다른 언어보다 더 유연합니다. 높은 수준의 추상화와 저수준 실리콘? 작업이 가능합니다. c++ 높은 수준의 최적화 표준 라이브러리를 제공합니다. 이것은 저수준 하드웨어에 접근 가능하게하고 속도를 최대하 하고, 메모리 사용을 최소하 시킵니다. c++을 사용하면 당신은 다양합 앱을 만들 수 있습니다. 게임, 장치 드라이버, 고성능 과학 프로그램, 임베디드 프로그램, 윈도우 앱. 심지어 다른 언어를 위한 라이브러리나 컴파일러 까지 c++로 작성됩니다.
c++의 본래 요구사항 중 하나는 c언와의 역호환성이였습니다. 결과적으로, c++은 저수준 포인터, 배열, 널 제거 캐릭터 스트링?, 기타 등등 c언어의 프로그래밍 스타일을 항상 지원하고 있습니다. 그것은 훌륭한 퍼포먼스를 발휘할 수도 있지만, 또한 버그와 복잡성을 유발 시킬 수 있다. c++ 진화는 c 스타일의 관용어의 필요성을 크게 줄이는 것을 강조해 왔습니다. 오래된 c 프로그래밍 장치들은 당신이 필요할 때 사용할 수 있습니다. 그러나 모던c++ 쓸 때는 c를 사용을 최대한 줄여야합니다. 모던 c++코드는 간단하고, 안전하면서, 더 우아하고, 여전히 빠릅니다.
Resources and smart pointers
C스타일 프로그래밍 버그 중 가장 주요한 클래스중 하나는 메모리 leak 이다. leak은 new로 할당된 메모리에 대해서 delete 하는 것이 실패되었을 때 자주 발생한다. 모던 c++은 RAII(Resource acquisition is initialization) 원리를 강조한다. 그 생각은 간단한것 입니다. 자원(힙 메모리, 파일 처리, 소켓, 등)은 object에 의해 소유 됩니다. 그 object는 생성자에서 새로 할당된 자원을 생성하거나 받고, 소멸자에서 삭제합니다. RAII의 원리는 오브젝트 소유권이 범위를 벗어 났을때 운영체제에게 적절히 반환되도록 보장하는 것이다.
RAII 원리의 손쉬운 채택을 지원하기 위해서 c++ 표준 라이브러리는 세가지 스마트 포인터 타입을 제공 합니다. std::unique_ptr,std::shared_ptr, and std::weak_ptr. 스마트 포인터는 본인이 소유한 메모리의 할당과, 제거를 다룹니다. 다음 예제는 make_unique() 호출로 힙에 배열 멤버가 할당된 클래스를 보여줍니다. new와 delete의 호출은 unique_ptr 클래스에 내포되어 있습니다. widget 오브젝트가 범위를 벗어나면 유니크 포인터 소멸자는 호출되고 그것은 배열에 할당되어 있는 메모리를 release 시킵니다.
#include <memory>
class widget
{
private:
std::unique_ptr<int> data;
public:
widget(const int size) { data = std::make_unique<int>(size); }
void do_something() {}
};
void functionUsingWidget() {
widget w(1000000); // lifetime automatically tied to enclosing scope
// constructs w, including the w.data gadget member
// ...
w.do_something();
// ...
} // automatic destruction and deallocation for w and w.data
가능하면, 힙메모리를 사용할때 스마트 포인터를 사용해라. 당신이 반드시 new, delete 연산을 명시적으로 사용해야 한다면 RAII 원칙을 따르세요. 더 많은 정보를 여기를 참고하세요. 오브젝트 수명과 자원 관리(RAII)
std::string and std:;string_view
C 스타일 문자열은 또다른 주요 버그 원인이다. std;;string and std::wstring을 사용하면 당신은 C스타일 문자열과 관련된 가상의 모든 에러들을 제거할 수 있다. 당신은 또 Searching, appending, prepending 등 멤버 함수의 이점을 얻을 수 있다. 둘다 매우 속도면에서 최적화 되어 있다. 읽기나 쓰기 전용으로 함수에 사용되면 c++17에서는 당신은 std::string_view 를 사용할 수있다. 이는 훨씬 더 강력한 이점을 갖는다.
std::vector and other Standard Library containers
표준 라이브러리 컨테이너는 모두 RAII 원칙을 따릅니다. 그들은 요소들의 안전한 순회를 위해 iterators를 제공합니다. 그리고 매우 최적화 되어 있으며, 철저하게 정확성에 대해 테스트 되었습니다. 이러한 컨테이너를 사용하면 당신은 커스텀 자료구조에서 제시되는 잠재적인 버그나 비효율성을 제거할 수 있습니다. raw array 대신에 c++ 선형 컨테이너인 vector를 사용하세요.
C 스타일 배열을 사용하지 마세요. 데이터에 직접 접근이 필요로 하는 오래된 api인 경우 f(vec.data(), vec.size()); 와 같은 접근자 함수를 사용하세요. 컨테이너에 대한 더 많은 정보는 참고하세요 Standard Library Containers.
Standard Library algorithms
당신이 당신 프로그램에 자체제작 알고리즘을 작성하기 전에 먼저 C++ 표준 알고리즘 라이브러리를 검토해라. 표준 라이브러리는 탐색, 정렬, 필터, 램덤과 같은 많은 공통적인 연산에 대한 꾸준히 증가하는 알고리즘 모음입니다. 수학 라이브러리는 광범위합니다. C++17이 시작되면서 많은 알고리즘 버전 또한 제공됩니다.
아래 몇가지 중요한 샘플이 있다
- for_each, 기본적인 순회 알고리즘( for 반복 범위에 따라)
- transform, 컨테이너 요소의 not-in-place 수정용
- find_if, 기본 탐색 알고리즘
- sort, lower_bound, 그리고 다른 정렬, 탐색 알고리즘들
비교자를 쓰기 위해서는 <를 사용해라 그리고 명명 람다를 사용해라
auto comp = [](const widget& w1, const widget& w2)
{ return w1.weight() < w2.weight(); }
sort( v.begin(), v.end(), comp );
auto i = lower_bound( v.begin(), v.end(), comp );
auto instead of explicit type names(명시적인 타입 이름을 대신 하는 auto)
C++11 은 변수, 함수 그리고 템플릿 선언에 사용되는 auto 키워드를 소개 했습니다. auto는 컴파일러에게 오브젝트으 타입을 추론하도록 합니다. 그래서 당신은 타입을 명시하지 않아도 됩니다. auto는 특히 추론되는 타입이 nested 탬플릿일 때 유용합니다.
Range-based for loops
C 스타일의 배열이나 컨테이너에 대한 반복은 인텍스 에러를 발생시키기 쉽고, 또한 이걸 타이밍하는 것은 지루한 일이다. 이러한 에러를 제거하고 더 읽기 좋은 코드를 만들기 위해서 표준 라이브러리 컨터네이너와 기존 배열을 지원하는 범위기반 for 반복문을 사용해라. 더 많은 정보는 여기를 참고하세요 Range-based for statement.
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v {1,2,3};
// C-style
for(int i = 0; i < v.size(); ++i)
{
std::cout << v[i];
}
// Modern C++:
for(auto& num : v)
{
std::cout << num;
}
}
constexpr expressions instead of macros
C와 C++ 매크로는 컴파일전에 전처리기에 위해서 처리되는 토큰이다. 각각의 매크로 토큰은 파일이 컴파일 되기전에 정의된 값이나 표현식으로 교체된다. 매크로는 공통적으로 컴파일 타임에서 상수값을 정의하기 위한 c스타일 프로그래밍에서 사용되었다. 하지만 매크로는 에러를 일으키고 디버깅하기 어렵다. 모던 c++에서는 컴파일 상수를 위해 constexpr 변수를 사용하는것이 더 좋다.
#define SIZE 10 // C-style
constexpr int size = 10; // modern C++
Uniform 초기화
모던 c++ 에서는 당신은 어떤 타입이든 괄호 초기화를 사용할 수 있습니다. 이 초기화 형식은 특히 배열이나 벡터 또는컨테이너를 초기화할때 효과적입니다. 예를 들어 v2는 3개의 인스턴스로 초기화 됩니다. v3는 괄호를 사용해서 초기화된 S 인스턴스를 3개로 초기화됩니다. 컴파일러는 v3의 선언된 타입을 통해 각요소 타입을 추론합니다.
#include <vector>
struct S
{
std::string name;
float num;
S(std::string s, float f) : name(s), num(f) {}
};
int main()
{
// C-style initialization
std::vector<S> v;
S s1("Norah", 2.7);
S s2("Frank", 3.5);
S s3("Jeri", 85.9);
v.push_back(s1);
v.push_back(s2);
v.push_back(s3);
// Modern C++:
std::vector<S> v2 {s1, s2, s3};
// or...
std::vector<S> v3{ {"Norah", 2.7}, {"Frank", 3.5}, {"Jeri", 85.9} };
}
모던 C++은 move semantice를 제공합니다. move semantics는 불필요한 메모리 복사를 제거하는 것을 가능하게 합니다. 이전 버전 언어에서는 특정 상황에서 복사는 피할 수 없었습니다. move 연산은 자원의 소유권을 복사 없이 다른 객체로 전달합니다. 일부 클래스는 힙메모리, 파일 처리 등의 자원을 소유합니다. 당신이 자원 소유 클래스를 구현할 때, 당신은 move 생성자와 move 할당연산을 정의할 수 있습니다. 컴파일러는 복사가 필요하지 않는 상황에서 오버로드 해결책에서 특별한 멤버들을 선택합니다. 표준 컨테이너 유형은 정의 되어 있다면 move 생성자를 실행합니다. 더 많은 정보는 여기를 보세요. Move Consructors and Move Assignment Operators(C++)
람다 표현식
C스타일 프로그래밍에서 함수는 함수 포인터를 사용해서 다른 함수로 전달될 수 있습니다. 함수 포인터는 유지하고 이해하기 불편합니다. 그 함수는 그 함수가 실행되는 위치에서 매우 멀리 떨어진 소스코드에 정의되어 있을 것입니다. 그리고 그 함수들은 안전한 타입이 아닙니다. 모던 c++은 함수 객체, operator()를 오버라이드하는 클래스를 제공합니다. 그것은 그들을 함수처럼 불리는게 가능하게 합니다.함수 객체를 만드는 가장 편한 방법은 인라인 람다 표현식입니다. 다음 예제는 함수 객체를 전달하기 위해서 어떻게 람다 표현식을 쓰는지 보여줍니다. for_each 함수는 벡터의 각 요소를 실행 시킵니다.
std::vector<int> v {1,2,3,4,5};
int x = 2;
int y = 4;
auto result = find_if(begin(v), end(v), [=](int i) { return i > x && i < y; });
이 람다 표현식 [=](int i){return i > x && i < y; } 은 함수는 "하나의 int 매개변수를 갖고 매개변수가 x보다 크고 y보다 작은 것인지를 나타내는 boolean값을 반환합니다. "라고 해석됩니다. 여기서 주목할 점은 주변 켄텍스트 변수인 x,y는 람다 안에서 사용될수 있습니다. [=] 는 이러한 값들을 캡쳐 되도록 지정합니다. 즉, 람다 표현식은 이런한 값들의 복사본을 갖습니다.
내부 스레드 통신 메커님에 대해서는 C++ 표준 라이브러리 std::atomic 구초제나 관련 유형을 사용하세요.
std:;variant(C++17)
유니온은 보통 C스타일 프로그래밍에서 다른 유형의 멤버타입을 같은 공간을 차지하게 함으로서 메모리 보존을 위해서 사용됩니다. 그러나 유니온은 안전한 방법이 아니고 프로그래밍 에러를 일으킵니다. C++17은 더 강력하고 유니온에 비해 비교적 안전한 클래스인 std:;variant를 제안합니다. std:;visit 함수는 안전한 방식으로 variant 유형 멤버를 접근하는데 사용될 수 있습니다.
666p. 어떤 방법을 사용하든지 간에, 모든 협력적인 구현 기법은 오류를 해결하기 위한 목적으로 여러분의 작업을 다른 사람에게 보여주는 것을 형식적으로 만들기 위한 시도이다.
667p. 협력적인 개발 방법의 개요 - 서로 간에 차이가 있을지라도 모든 협력적인 구현 기법은 개발자들이 자신의 작업에 있는 문제점들을 제대로 파악하지 못한다는 점과 다른 사람들은 제대로 파악할 수 있다는 점, 그리고 다른 프로그래머가 자신의 작업을 지켜보면 도움이 된다는 기본 개념에 기초하고 있다.
671p. 짝 프로그래밍 성공 요건 - 짝 프로그래밍을 강요하지 마라 : 매우 복잡한 코드를 작성할 때 짝 프로그래밍을 사용했던 한 그룹은 15분 동안 칠판에 상세 설계를 한 다음 혼자서 프로그램을 작성하는 것이 더 적절하다는 것을 발견 했다.
675p. 정밀 검사에 경영자가 참가하는 것은 일반적으로 좋은 생각이 아니다. 사람들은 검토를 하는 대신 평가를 받고 있다고 느낀다.
679p. 정밀 검사에서의 자존심 - 정밀 검사 자체의 핵심은 설계나 코드에 있는 결함을 발견하는 것이다. 다른 대안을 찾거나 누가 옳고 누가 그른지에 대해서 논쟁하는 것이 아니다.
680p. 정밀 검사에서의 자존심 - 그럼에도 불구하고, 작성자는 언급된 모든 결함을 인정하고 계속 진행해야 한다. 비평을 인정한다고 해서 작성자가 비평의 내용에 동의한다는 것을 의미하지는 않는다. 작성자는 검토중에 자신이 한 작업에 대해서 방어를 하려고 해서는 안된다. 각 검토자는 오류를 어떻게 해결할 것인지에 대한 작성자의 최종 결정권을 존중해 주어야 한다.
이 래퍼런스는 마이크로소프트 c++ 컴파일로 구현된 c++ 프로그래밍을 설명합니다. 그 기간은margaret eliis 와 bjarne stroustrup, 그리고 ANSI/ISO C++ 국제 표준(ISO/IEC FDIS 14882)에 의해 발표된 c++ 레퍼런서를 기본으로 합니다. 마이크로소프트만의 c++ 특징이 있습니다.
779p. 구현중에 변경하는 것은 일반적으로 원래의 개발자가 수행하고, 보통 프로그램이 완전히 잊혀지기 전에 수행된다. 시스템이 아직 외부에 공개되지 않았기 때문에, 변경 사항을 끝내야 한다는 압박도 일정상의 압박일 뿐이지 시스템이 다운된 이유를 궁금해 하는 500명의 사용자가 아니다. 같은 이유로 구현중의 변경사항은 자유로울 수 있다.
787p. 전문가들은 미래의 요구 사항을 준비하는 가장 바람직한 방법은 이론적인 코드를 작성하지 않는 것이라고 말한다. 현재 필요한 코드를 분명하고 직관적으로 작성하여, 미래의 프로그래머가 그 코드가 무엇을 하고 무엇을 하지 않는지 대해서 알 수 있도록 하고 그에 따라 변경할 수 있도록 하는 것이다.
790p 데이터 수준 리펙토링 - 컬렉션을 캡슐화 한다 : 만약 클래스가 컬렉션을 리턴할 때, 고정되지 않는 여러 개의 컬렉션을 갖고 있다면 동기화 처리를 어렵게 할 수 있다. 클래스가 읽기만 가능한 컬렉션을 리턴하도록 하고, 컬렉션에 요소를 추가/제거하기 위한 루틴을 제공하도록 한다.
791p 명령문 수준 리펙토링 - 조건문을 다형성으로 대체 한다.
792p 루틴 수준 리팩토링 - 다운캐스팅을 캡슐화 한다 : 만약 루틴이 객체를 리턴하고 있다면, 일반적으로 루틴이 알고 있는 가장 구체적인 객체의 타입을 리턴해야 한다. 이러한 리팩토링은 특히 반복자(iterator), 컬랙션(collection), 컬렉션의 요소 등을 리턴하는 루틴에도 적용이 가능하다.
799p 안전한 리팩토링 - 주차장을 만든다 : 여러분이 리팩토링을 수행하고 있을 때, 때로는 다른 리팩토링을 해야 할 필요가 있을 것이다. 또한 새로운 리팩토링을 수행하고 있을 때, 또 다른 리팩토링이 도움이 된다는 것을 발견하게 될 것이다. 지금 당장 필요하지 않는 변경을 위해서 "주차장"을 만들어 놓는다. 즉, 지금 당장은 변경해야 할 필요가 없지만 어느 시점에서 변경해야 하는 변경사항에 대한 목록을 만들어둔다.
799p 안전한 리팩토링 - 빈번하게 체크 포인트를 설정한다 : 리팩토링을 하다보면 코드가 갑자기 엉뚱한 방향으로 가기 쉽다. 여러분이 시작한 코드를 저장하는 것뿐만 아니라, 리팩토링을 하면서 여러 곳에 체크 포인트를 저장하여 막다른 골목에 갔을 때, 작동하는 프로그램으로 돌아올 수 있도록 한다.
800p 안전한 리팩토링 - 컴파일러의 경고를 활용한다 : 컴파일러의 경고 수준을 가장 까다롭게 설정하면 많은 오류들을 즉시 잡는 데 도움이 될 것이다.
800p 안전한 리팩토링 - 변경 사항을 검토한다 : 작은 변경이 큰 변경보다 오류를 발생시킬 가능성이 더 높은 경향이 있다.