10 TECHNIQUES TO UNDERSTAND EXISTING CODE Jonathan Boccara @JoBoccara
@JoBoccara 2
10 TECHNIQUES TO UNDERSTAND EXISTING CODE
Hi, I’m Jonathan Boccara! @JoBoccara
10 TECHNIQUES TO UNDERSTAND EXISTING CODE
10 TECHNIQUES TO UNDERSTAND EXISTING CODE OUTLINE: Exploring the code (3 techniques) Becoming a code speed-reader (4 techniques) Understanding code in details (3 techniques) @JoBoccara 6
Exploring the code (3 techniques) @JoBoccara 7
TECHNIQUE #1 Know your I/O frameworks. @JoBoccara 8
Compute 42 @JoBoccara 9
Compute @JoBoccara 10
@JoBoccara
Compute 42 42 @JoBoccara 12
Compute 42 UI Framework Get familiar with the code of your UI framework 42 @JoBoccara 13
UI Framework REST handler I/O Framework Logs Unit tests @JoBoccara 14
TECHNIQUE #2 Find a stronghold. @JoBoccara 15
@JoBoccara
@JoBoccara
@JoBoccara
@JoBoccara
WTF map = codebase stronghold = code you understand perfectly well even one line Chances are you can figure out the immediate surroundings too. @JoBoccara 20
y = y 0 + ( x − x 0) × y 1 − y 0 x 1 − x 0 @JoBoccara 21
@JoBoccara
@JoBoccara
@JoBoccara
@JoBoccara
TECHNIQUE #3 function11 function10 module #4 function9 function8 module #3 Analyse call stacks. function7 function6 module #2 function5 function4 function3 module #1 function2 function1 @JoBoccara 26
@JoBoccara
@JoBoccara
@JoBoccara
What is an interesting stack? • A deep stack • A common use case of the application @JoBoccara 30
What is an interesting stack? • A deep stack • A common use case of the application How to find an interesting stack? • Your dev lead • Business people for the common use case • Your knowledge of the I/O to locate it @JoBoccara 31
Flamegraphs @JoBoccara 32
Exploring the code (3 techniques) TECHNIQUE #1: Know your I/O frameworks. TECHNIQUE #2: Find a stronghold. TECHNIQUE #3: Analyse call stacks. @JoBoccara 33
10 TECHNIQUES TO UNDERSTAND EXISTING CODE OUTLINE: Exploring the code (3 techniques) Becoming a code speed-reader (4 techniques) Understanding code in details (3 techniques) @JoBoccara 34
Becoming a code speed-reader (4 techniques) @JoBoccara 35
@JoBoccara 36
Don’t read cover to cover Goal is not to understand everything code Focus on where the information is @JoBoccara 37
TECHNIQUE #4 Start reading from the end. code @JoBoccara 38
TECHNIQUE #4 Information is at the beginning and the end code beginning = prototype end = ? @JoBoccara 39
std::vector<MultipleAlignmentBlock> AlignmentGroup::loadAlignments(std::string const& chr, int start, int end) { IntervalTree* ivTree = index.getIntervalTree(chr); if (ivTree == NULL) return {}; std::vector<Interval> intervals = ivTree.findOverlapping(start, end); if (intervals.empty()) { return {}; } // Find the starting (left most) interval. Alignment blocks do not overlap, so we can start at the // minimum file offset and just proceed until the end of the interval. Int startPosition = 0; for (Interval const& iv : intervals) { startPosition = Math.min(startPosition, iv.getValue()); } IGVSeekableStream is; is = IGVSeekableStreamFactory.getInstance().getStreamFor(path); is.seek(startPosition); IGVBufferedReader reader(IGVInputStreamReader(is), 256000); std::vector<MultipleAlignmentBlock> alignments; std::string line; while (getLine(reader, line)) { if (startsWith(line, "a ")) { // TODO -- parse score (optional) MultipleAlignmentBlock block = parseBlock(reader); if(block.getEnd() < start) { continue; } if (block.getStart() > end || !block.getChr() == chr)) { break; } else { alignments.push_back(block); } } } return alignments; @JoBoccara 40 }
TECHNIQUE #4 • Returned value • Out parameter Start reading Start reading • Data member from the outputs. from the end. • IO • Global variable • Output via exception Heuristics: look for outputs towards the end @JoBoccara 41
TECHNIQUE #5 Find the frequent words. @JoBoccara 42
bool CSetting::ReadValue( CRegKey ®Key, const wchar_t *valName ) { // bool, int, hotkey, color if (type==CSetting::TYPE_BOOL || (type==CSetting::TYPE_INT && this[1].type!=CSetting::TYPE_RADIO) || type==CSetting::TYPE_HOTKEY || type==CSetting::TYPE_HOTKEY_ANY || type==CSetting::TYPE_COLOR) { DWORD val; if (regKey.QueryDWORDValue(valName,val)==ERROR_SUCCESS) { if (type==CSetting::TYPE_BOOL) value=CComVariant(val?1:0); else value=CComVariant((int)val); return true; } return false; } // radio if (type==CSetting::TYPE_INT && this[1].type==CSetting::TYPE_RADIO) { ULONG len; Word # occurrences DWORD val; if (regKey.QueryStringValue(valName,NULL,&len)==ERROR_SUCCESS) { len 20 CString text; regKey.QueryStringValue(valName,text.GetBuffer(len),&len); text.ReleaseBuffer(len); value 17 val=0; for (const CSetting *pRadio=this+1;pRadio->type==CSetting::TYPE_RADIO;pRadio++,val++) { CSetting 15 if (_wcsicmp(text,pRadio->name)==0) { if 14 value=CComVariant((int)val); return true; } type 13 } } else if (regKey.QueryDWORDValue(valName,val)==ERROR_SUCCESS) regKey 11 { value=CComVariant((int)val); return true; valName 11 } return false; } return 11 // string if (type>=CSetting::TYPE_STRING && type<CSetting::TYPE_MULTISTRING) { val 10 ULONG len; if (regKey.QueryStringValue(valName,NULL,&len)==ERROR_SUCCESS) bstrVal 10 { value.vt=VT_BSTR; value.bstrVal=SysAllocStringLen(NULL,len-1); 1 8 regKey.QueryStringValue(valName,value.bstrVal,&len); return true; } 0 8 return false; } // multistring NULL 7 if (type==CSetting::TYPE_MULTISTRING) { ULONG len; true 6 if (regKey.QueryMultiStringValue(valName,NULL,&len)==ERROR_SUCCESS) { value.vt=VT_BSTR; QueryStringValue 6 value.bstrVal=SysAllocStringLen(NULL,len-1); regKey.QueryMultiStringValue(valName,value.bstrVal,&len); ERROR_SUCCESS 6 for (int i=0;i<(int)len-1;i++) if (value.bstrVal[i]==0) value.bstrVal[i]='\n'; int 6 return true; } else if (regKey.QueryStringValue(valName,NULL,&len)==ERROR_SUCCESS) … { value.vt=VT_BSTR; value.bstrVal=SysAllocStringLen(NULL,len); regKey.QueryStringValue(valName,value.bstrVal,&len); if (len>0) { value.bstrVal[len-1]='\n'; @JoBoccara value.bstrVal[len]=0; 43 } return true; } return false; } Assert(0); return false; }
bool CSetting::ReadValue( CRegKey ®Key, const wchar_t *valName ) { // bool, int, hotkey, color if (type==CSetting::TYPE_BOOL || (type==CSetting::TYPE_INT && this[1].type!=CSetting::TYPE_RADIO) || type==CSetting::TYPE_HOTKEY || type==CSetting::TYPE_HOTKEY_ANY || type==CSetting::TYPE_COLOR) { DWORD val; if (regKey.QueryDWORDValue(valName,val)==ERROR_SUCCESS) { if (type==CSetting::TYPE_BOOL) value=CComVariant(val?1:0); else value=CComVariant((int)val); return true; } return false; } // radio if (type==CSetting::TYPE_INT && this[1].type==CSetting::TYPE_RADIO) { ULONG len; Word # occurrences DWORD val; if (regKey.QueryStringValue(valName,NULL,&len)==ERROR_SUCCESS) { len 20 CString text; regKey.QueryStringValue(valName,text.GetBuffer(len),&len); text.ReleaseBuffer(len); value 17 val=0; for (const CSetting *pRadio=this+1;pRadio->type==CSetting::TYPE_RADIO;pRadio++,val++) { CSetting 15 if (_wcsicmp(text,pRadio->name)==0) { if 14 value=CComVariant((int)val); return true; } type 13 } } else if (regKey.QueryDWORDValue(valName,val)==ERROR_SUCCESS) { regKey 11 { inputs value=CComVariant((int)val); return true; valName 11 } return false; } return 11 // string if (type>=CSetting::TYPE_STRING && type<CSetting::TYPE_MULTISTRING) { val 10 ULONG len; if (regKey.QueryStringValue(valName,NULL,&len)==ERROR_SUCCESS) bstrVal 10 { value.vt=VT_BSTR; value.bstrVal=SysAllocStringLen(NULL,len-1); 1 8 regKey.QueryStringValue(valName,value.bstrVal,&len); return true; } 0 8 return false; } // multistring NULL 7 if (type==CSetting::TYPE_MULTISTRING) { ULONG len; true 6 if (regKey.QueryMultiStringValue(valName,NULL,&len)==ERROR_SUCCESS) { value.vt=VT_BSTR; QueryStringValue 6 value.bstrVal=SysAllocStringLen(NULL,len-1); regKey.QueryMultiStringValue(valName,value.bstrVal,&len); ERROR_SUCCESS 6 for (int i=0;i<(int)len-1;i++) if (value.bstrVal[i]==0) value.bstrVal[i]='\n'; int 6 return true; } else if (regKey.QueryStringValue(valName,NULL,&len)==ERROR_SUCCESS) … { value.vt=VT_BSTR; value.bstrVal=SysAllocStringLen(NULL,len); regKey.QueryStringValue(valName,value.bstrVal,&len); if (len>0) { value.bstrVal[len-1]='\n'; @JoBoccara value.bstrVal[len]=0; 44 } return true; } return false; } Assert(0); return false; }
Recommend
More recommend