SlideShare a Scribd company logo
All things that are not code
!code
Eyal Keren
BASIC - first bug
PERL - first time I couldn’t read my code
JAVA - first unit test
Vim
TDD
CTO & Co-founder @ Rollout.io
@ekeren (github)
Once upon a time…
While working @Intel
Once upon a time...
public class MyClass{
public double calculateAnswer(String question){
//real  code
return  answer;
}
}
public class MyClass{
static Logger log  = Logger.getLogger(MyClass.class.getName());
public double calculateAnswer(String question){
log.debug("in  calculateAnswer");
//real  code
return  answer;
}
}
Once upon a time...
public class MyClass{
static Logger log  = Logger.getLogger(MyClass.class.getName());
public double calculateAnswer(String question){
log.debug("in  calculateAnswer");
//real  code
log.debug("out  calculateAnswer");
return  answer;
}
}
Once upon a time...
public class MyClass{
static Logger log  = Logger.getLogger(MyClass.class.getName());
public double calculateAnswer(String question){
log.debug("in  calculateAnswer question={}"  ,question);
//real  code
log.debug("out  calculateAnswer answer={}"  ,answer);
return  answer;
}
}
Once upon a time...
public class MyClass{
static Logger log  = Logger.getLogger(MyClass.class.getName());
public double calculateAnswer(String question){
//real  code
return  answer;
}
}
Once upon a time...
All things that are not code
new  system  >>  old  system
new  system  >>  old  system
Less mistakes Less performance cost
Less data to process Less code
new  system  >>  old  system
Less mistakes Less performance cost
Less data to process Less untestable code
All things that are not code
This talk
boolean function  isCode(){
return true;    //  TODO  implement
}
if  (!code)  {
//  TODO  implement
}
This talk
• Once upon a time..
• !code by examples
• Why Mobile?
• !code definition
• Q&A
Agenda
Rate Us
When a user press the restart button on a high
score, let’s trigger rate us
Rate Us
When a user press the restart button on a high
score, let’s trigger rate us
Definition
R&D
PMResults
Implementation
QA
Release
Rate Us
When a user press the restart button on a high
score, let’s trigger rate us
Definition
R&D
PMResults
Implementation
QA
Release
• Methods are decorated on demand
(before/after/inside)
• You can define actions for decoration
• Call these actions based on available data
• Decoration are safe and guarded
• Gradually rollout the decoration
• Zero performance hit
Imagine an Engine…
Rate Us Demo
All things that are not code
!code
Not all code is created equal
Are these even necessary?
Rate Us
Testing
Code
Review QA
Automated
YES - because we are humans
Are these even necessary?
Rate Us
Testing
Code
Review QA
Automated
Not all code is created equal
The Power of !code
Profiling
Profiling
public void transactionA(){
start_trace(“business_trans_A”);
doA();
doB();
doC();
doD();
end_trace(“business_trans_A”);
}
Profiling
public void takesALongTimeInProduction(){
start_trace(“business_no_1”);
doA();
doB();
doC();
doD();
end_trace(“business_no_1”);
}
public void doA(){
start_trace(“diag_AB”);
//real  code
}
public void doB(){
//real  code
end_trace(“diag_AB”);
}
public void doC(){
start_trace(“diag_C”);
//real  code
end_trace(“diag_C”);
}
public void doD(){
//real  code
}
(Sounds familiar?)
Profiling
Get results into
NR dashboard
Set diag on
1% of users
Figure out
your next step
Remove
diag traces
Logs
Use cases
Automatic logging
• View  controller  life  cycle  
• Memory  warnings
• System  notifications
Upload your logs when something happens
• If  the  flow  gets  here  with  this  value
• Until  you  get  5  logs  of  this  issue
Rollout
Mixpanel Surveys
Apptimize
Intercom
HelpShift
LeanPlum
Rollout
iRateMixpanel analytics
Mixpanel A/B
Launchdarkly
Parse config
Configo
LinkedIn
Facebook
ZenDesk
Insert.io
Elasticode
Google Tag Manager
Segment
Mixpanel Surveys
Apptimize
Intercom
HelpShift
LeanPlum
Rollout
iRateMixpanel analytics
Mixpanel A/B
Launchdarkly
Parse config
Configo
LinkedIn
Facebook
ZenDesk
Insert.io
Elasticode
Google Tag Manager
Segment
Github/Jira for !Code
Why Mobile ?
Why Mobile first ?
Why Mobile first ?
encoding:NSUTF8StringEncoding  error:nil];;                    if  ((self  =  [self  initWithVertexShaderString:vertexShaderString
fragmentShaderString:fragmentShaderString]))            {          }                    return  self;;  }  //  END:init //  START:compile -­
(BOOL)compileShader:(GLuint *)shader type:(GLenum)type                                  string:(NSString *)shaderString
{  //        CFAbsoluteTime startTime =  CFAbsoluteTimeGetCurrent();;            GLint status;;          const GLchar *source;;                    
source  =                (GLchar *)[shaderString UTF8String];;          if  (!source)          {                  NSLog(@"Failed  to  load  vertex  
shader");;                  return  NO;;          }                    *shader =  glCreateShader(type);;          glShaderSource(*shader,  1,  &source,  
NULL);;          glCompileShader(*shader);;                    glGetShaderiv(*shader,  GL_COMPILE_STATUS,  &status);;     if  (status  
!=  GL_TRUE)   {   GLint logLength;;   glGetShaderiv(*shader,  
GL_INFO_LOG_LENGTH,  &logLength);;   if  (logLength >  0)   {  
GLchar *log  =  (GLchar *)malloc(logLength);;  
glGetShaderInfoLog(*shader,  logLength,  &logLength,  log);;  
NSLog(@"Shader compile  log:n%s",  log);;   free(log);;   }  
} //        CFAbsoluteTime linkTime =  (CFAbsoluteTimeGetCurrent()  -­ startTime);;  //        
NSLog(@"Compiled  in  %f  ms",  linkTime *  1000.0);;            return  status  ==  GL_TRUE;;  }  //  END:compile #pragma  mark  
-­ //  START:addattribute -­ (void)addAttribute:(NSString *)attributeName {          if  (![attributes  
containsObject:attributeName])          {                  [attributes  addObject:attributeName];;                  glBindAttribLocation(program,        
(GLuint)[attributes  indexOfObject:attributeName],                                                            [attributeName UTF8String]);;          }  }  //  
END:addattribute //  START:indexmethods -­ (GLuint)attributeIndex:(NSString *)attributeName {          return  
(GLuint)[attributes  indexOfObject:attributeName];;  }  -­ (GLuint)uniformIndex:(NSString *)uniformName {          return  
glGetUniformLocation(program,  [uniformName UTF8String]);;  }  //  END:indexmethods #pragma  mark  -­ //  
START:link -­ (BOOL)link  {  //        CFAbsoluteTime startTime =  CFAbsoluteTimeGetCurrent();;            GLint status;;                    
glLinkProgram(program);;                    glGetProgramiv(program,  GL_LINK_STATUS,  &status);;          if  (status  ==  
GL_FALSE)                  return  NO;;                    if  (vertShader)          {                  glDeleteShader(vertShader);;                  vertShader =  0;;          }          
if  (fragShader)          {                  glDeleteShader(fragShader);;                  fragShader =  0;;          }                    self.initialized =  YES;;    //        
!code
!code Smells
if C do A
• C:
• Remotely  configured
• opinionated
• A:
• Volatile
• Not  testable
• Doesn’t  change  the  
application  behavior  
Look for !Code
Mixpanel
Surveys
Apptimize
Intercom
HelpShift
LeanPlum
Rollout
iRateMixpanel
analytics
Mixpanel A/B
Launchdarkly
Parse config
Configo
LinkedIn
Facebook
ZenDesk
Insert.io
Elasticode
Q&A

More Related Content

All things that are not code

  • 1. All things that are not code
  • 3. Eyal Keren BASIC - first bug PERL - first time I couldn’t read my code JAVA - first unit test Vim TDD CTO & Co-founder @ Rollout.io @ekeren (github)
  • 4. Once upon a time… While working @Intel
  • 5. Once upon a time... public class MyClass{ public double calculateAnswer(String question){ //real  code return  answer; } }
  • 6. public class MyClass{ static Logger log  = Logger.getLogger(MyClass.class.getName()); public double calculateAnswer(String question){ log.debug("in  calculateAnswer"); //real  code return  answer; } } Once upon a time...
  • 7. public class MyClass{ static Logger log  = Logger.getLogger(MyClass.class.getName()); public double calculateAnswer(String question){ log.debug("in  calculateAnswer"); //real  code log.debug("out  calculateAnswer"); return  answer; } } Once upon a time...
  • 8. public class MyClass{ static Logger log  = Logger.getLogger(MyClass.class.getName()); public double calculateAnswer(String question){ log.debug("in  calculateAnswer question={}"  ,question); //real  code log.debug("out  calculateAnswer answer={}"  ,answer); return  answer; } } Once upon a time...
  • 9. public class MyClass{ static Logger log  = Logger.getLogger(MyClass.class.getName()); public double calculateAnswer(String question){ //real  code return  answer; } } Once upon a time...
  • 11. new  system  >>  old  system
  • 12. new  system  >>  old  system Less mistakes Less performance cost Less data to process Less code
  • 13. new  system  >>  old  system Less mistakes Less performance cost Less data to process Less untestable code
  • 15. This talk boolean function  isCode(){ return true;    //  TODO  implement }
  • 16. if  (!code)  { //  TODO  implement } This talk
  • 17. • Once upon a time.. • !code by examples • Why Mobile? • !code definition • Q&A Agenda
  • 18. Rate Us When a user press the restart button on a high score, let’s trigger rate us
  • 19. Rate Us When a user press the restart button on a high score, let’s trigger rate us Definition R&D PMResults Implementation QA Release
  • 20. Rate Us When a user press the restart button on a high score, let’s trigger rate us Definition R&D PMResults Implementation QA Release
  • 21. • Methods are decorated on demand (before/after/inside) • You can define actions for decoration • Call these actions based on available data • Decoration are safe and guarded • Gradually rollout the decoration • Zero performance hit Imagine an Engine…
  • 24. !code
  • 25. Not all code is created equal
  • 26. Are these even necessary? Rate Us Testing Code Review QA Automated
  • 27. YES - because we are humans Are these even necessary? Rate Us Testing Code Review QA Automated
  • 28. Not all code is created equal
  • 29. The Power of !code
  • 32. Profiling public void takesALongTimeInProduction(){ start_trace(“business_no_1”); doA(); doB(); doC(); doD(); end_trace(“business_no_1”); } public void doA(){ start_trace(“diag_AB”); //real  code } public void doB(){ //real  code end_trace(“diag_AB”); } public void doC(){ start_trace(“diag_C”); //real  code end_trace(“diag_C”); } public void doD(){ //real  code }
  • 33. (Sounds familiar?) Profiling Get results into NR dashboard Set diag on 1% of users Figure out your next step Remove diag traces
  • 34. Logs Use cases Automatic logging • View  controller  life  cycle   • Memory  warnings • System  notifications Upload your logs when something happens • If  the  flow  gets  here  with  this  value • Until  you  get  5  logs  of  this  issue
  • 36. Mixpanel Surveys Apptimize Intercom HelpShift LeanPlum Rollout iRateMixpanel analytics Mixpanel A/B Launchdarkly Parse config Configo LinkedIn Facebook ZenDesk Insert.io Elasticode Google Tag Manager Segment
  • 37. Mixpanel Surveys Apptimize Intercom HelpShift LeanPlum Rollout iRateMixpanel analytics Mixpanel A/B Launchdarkly Parse config Configo LinkedIn Facebook ZenDesk Insert.io Elasticode Google Tag Manager Segment Github/Jira for !Code
  • 41. encoding:NSUTF8StringEncoding  error:nil];;                    if  ((self  =  [self  initWithVertexShaderString:vertexShaderString fragmentShaderString:fragmentShaderString]))            {          }                    return  self;;  }  //  END:init //  START:compile -­ (BOOL)compileShader:(GLuint *)shader type:(GLenum)type                                  string:(NSString *)shaderString {  //        CFAbsoluteTime startTime =  CFAbsoluteTimeGetCurrent();;            GLint status;;          const GLchar *source;;                     source  =                (GLchar *)[shaderString UTF8String];;          if  (!source)          {                  NSLog(@"Failed  to  load  vertex   shader");;                  return  NO;;          }                    *shader =  glCreateShader(type);;          glShaderSource(*shader,  1,  &source,   NULL);;          glCompileShader(*shader);;                    glGetShaderiv(*shader,  GL_COMPILE_STATUS,  &status);;     if  (status   !=  GL_TRUE)   {   GLint logLength;;   glGetShaderiv(*shader,   GL_INFO_LOG_LENGTH,  &logLength);;   if  (logLength >  0)   {   GLchar *log  =  (GLchar *)malloc(logLength);;   glGetShaderInfoLog(*shader,  logLength,  &logLength,  log);;   NSLog(@"Shader compile  log:n%s",  log);;   free(log);;   }   } //        CFAbsoluteTime linkTime =  (CFAbsoluteTimeGetCurrent()  -­ startTime);;  //         NSLog(@"Compiled  in  %f  ms",  linkTime *  1000.0);;            return  status  ==  GL_TRUE;;  }  //  END:compile #pragma  mark   -­ //  START:addattribute -­ (void)addAttribute:(NSString *)attributeName {          if  (![attributes   containsObject:attributeName])          {                  [attributes  addObject:attributeName];;                  glBindAttribLocation(program,         (GLuint)[attributes  indexOfObject:attributeName],                                                            [attributeName UTF8String]);;          }  }  //   END:addattribute //  START:indexmethods -­ (GLuint)attributeIndex:(NSString *)attributeName {          return   (GLuint)[attributes  indexOfObject:attributeName];;  }  -­ (GLuint)uniformIndex:(NSString *)uniformName {          return   glGetUniformLocation(program,  [uniformName UTF8String]);;  }  //  END:indexmethods #pragma  mark  -­ //   START:link -­ (BOOL)link  {  //        CFAbsoluteTime startTime =  CFAbsoluteTimeGetCurrent();;            GLint status;;                     glLinkProgram(program);;                    glGetProgramiv(program,  GL_LINK_STATUS,  &status);;          if  (status  ==   GL_FALSE)                  return  NO;;                    if  (vertShader)          {                  glDeleteShader(vertShader);;                  vertShader =  0;;          }           if  (fragShader)          {                  glDeleteShader(fragShader);;                  fragShader =  0;;          }                    self.initialized =  YES;;    //         !code
  • 42. !code Smells if C do A • C: • Remotely  configured • opinionated • A: • Volatile • Not  testable • Doesn’t  change  the   application  behavior  
  • 43. Look for !Code Mixpanel Surveys Apptimize Intercom HelpShift LeanPlum Rollout iRateMixpanel analytics Mixpanel A/B Launchdarkly Parse config Configo LinkedIn Facebook ZenDesk Insert.io Elasticode
  • 44. Q&A