ChatGPT - How Long Till They Realize I’m a Robot?

Image
I tried it first on December 2nd... ...and slowly the meaning of it started to sink in. It's January 1st and as the new year begins, my future has never felt so hazy. It helps me write code. At my new company I'm writing golang, which is new for me, and one day on a whim I think "hmmm maybe ChatGPT will give me some ideas about the library I need to use." Lo-and-behold it knew the library. It wrote example code. It explained each section in just enough detail. I'm excited....It assists my users. I got a question about Dockerfiles in my teams oncall channel. "Hmmm I don't know the answer to this either"....ChatGPT did. It knew the commands to run. It knew details of how it worked. It explained it better and faster than I could have. Now I'm nervous....It writes my code for me. Now I'm hearing how great Github Copilot is - and it's built by OpenAI too...ok I guess I should give it a shot. I install it, and within minutes it'

Notes on Effective Java 2nd Edition

Chapter 3 - Methods Common to All Objects
  •  Item 8: Obey the general congract when overriding equals - page 33
    • If you decide to implement equals, make sure it is
      • reflexive: for all x, x.equals(x)
      • symmetric: for all x & y, x.equals(y) iff y.equals(x)
      • transitive: for all x, y, z, if x.equals(y) and y.equals(z), then x.equals(z) must be true
      • consistent: for all x & y, multiple invocations of x.equals(y) return the same result provided nothing used in equality is changed in either x or y
      • for all x, x.equals(null) must return false
  • Item 9: Always override hashCode when you override equals
  • Item 10: Always override toString
  • Item 11: Override clone judiciously
  • Item 12: Consider implementing Comparable
Chapter 4 - Classes and Interfaces
  •  Item 13: Minimize the accessibility of classes and members
    • accessibilities
      • private
      • package-private (default)
      • protected
      • public
    • classes with public mutable fields are not thread-safe
  • Item 14: In public classes, use accessor methods, not public fields
    • if a class is accessible outside its package, provide accessor methods to preserve flexibility
    • if a class is package-private there is nothing inherently wrong with exposing its data fields
  • Item 15: Minimize mutability
    • to make a class immutable:
      • Don't provide any methods that modify the object's state
      • Ensure that the class can't be extended
      • Make all fields final
      • Make all fields private
      • Ensure exclusive access to any mutable components
    • immutable objects are simple, inherently thread-safe and can be shared freely
  • Item 16: Favor composition over inheritance
    •  Inheritance violates encapsulation
    • Inheriting from another class propagates any flaws that were in the superclass
    • Use composition and forwarding instead
  • Item 17: Design and document for inheritance or else prohibit it
    • If a class is meant to be inherited from, the class must document it's self-use of overridable methods
      • state in a method comment, which overridable methods it invokes
    • The only way to test a class designed for inheritance is to write subclasses
      • therefore you must test your class by writing subclasses before releasing it
    • constructors must not invoke an overridable method - pg. 90
    • It's best to prohibit subclassing in classes that are not designed and documented to be safely subclassed
      • either make the class final
      • or make all the constructors private or package-private
  • Item 18: Prefer interfaces to abstract classes
    • A class can only extend 1 abstract class, but can implement multiple interfaces
    • Existing classes can be easily retrofitted to implement a new interface
    • Interfaces are ideal for defining mixins, abstract classes cannot
      •  mixin: a type that a class can implement in addition to it's primary type, to declare it has some optional functionality
    • Interfaces allow for the construction of nonhierarchical type frameworks
    • Interfaces enable safe, powerful functionality enhancements
      • via the wrapper class idiom
    • You can combine the virtues of abstract classes with interfaces by providing an abstract skeletal implementation class to go wit heach nontrivial interface that you export
      • by convention, skeletal implementations are called AbstractInterface (e.g. AbstractSet, AbstractCollection, etc.)
      •  because skeletal implementations are designed for inheritance, obey the rules of Item 17
      • example page 95
      • simulated multiple inheritance : create a skeletal implementation of an interface, then create another class that has an instance of a private innerclass that extends that skeletal implementation
    • 1 major advantage of abstract classes : they are far easier to evolve than interfaces
      • to add a method to an abstract class, just add it with a reasonable default implementation - then the inheriting classes can override it in due time
      • interfaces, however can never have a method added without breaking pre-existing implementations
        • because of this, the programmer must get it right the first time, before it's released into the wild
    • Interfaces are generally the best way to go
      • the exception is when ease of evolution is deemed more important than flexibility and power
  • Item 19: Use interfaces only to define types
    • The constant interface anti-pattern is a poor use of interfaces
      • it is an implementation detail that becomes visible to clients
      • subsequent releases of a class that may no longer need the constants must continue implementing the interface to ensure binary compatibility
  • Item 20: Prefer class hierarchies to tagged classes
    • tagged classes(example pg. 100) are verbose, error-prone and inefficient
    • a tagged class is just a pallid imitation of a class hierarchy
  • Item 21: Use function objects to represent strategies
    • function object: an instance of a class whose methods perform operations on other objects (e.g. comparator)
    • a primary use of function pointers/objects is to implement the Strategy Pattern
  • Item 22: Favor static member classes over nonstatic
    • a nested class should exist only to serve its enclosing class - if it's useful outside that class, it should be a top-level class
      • 4 types: static member classes, nonstatic member classes, anonymous classes, local classes
        • all but the 1st are inner classes
        • each has it's use (page 108, end)
    • If you declare a member class that does not require access to an enclosing instance, always put the static modifier in its declaration
      • not doing so forces instances to store a reference to it's eclosing class, which wastes space and time
Chapter 5 - Generics (page 109)
- useful generics vocabulary chart on page 115
  • Item 23: Don't use raw types in new code
    • generics are safe, raw types are not
      • this is because the compiler will tell you if you're using a type where you shouldn't be rather than finding out at runtime
    • Set<?> can contain objects of some unknown type (safe)
    • Set<Object> can contain anything (unsafe)
  • Item 24: Eliminate unchecked warnings
    • Eliminate all unchecked warnings if you can
    • If you can't eliminate a warning, and you can prove that the code is typesafe, then and only then, suppress the warning with an @suppressWarnings("unchecked") annotation
      • Always use suppressWarnings on the smallest scope possible
      • Always add a comment saying why you used it
  • Item 25: Prefer lists to arrays
    •  Arrays are covariant(Object[] is a supertype of String[]) , Lists are invariant(better - can't add objects of typeA to a list of typeB - compile time error
    • Arrays are reified (enforce types at runtime and not at compile time) and generics are implemented by erasure (enforce types at compile time but not at runtime - allows for backwards compatibility with older Java version code)
    • Better to enforce and find out of issues at compile time
  • Item 26: Favor generic types
    •  Fewer errors discovered at runtime - they'll be discovered at compile time
    • If using arrays, can't generically type them, so might need to use type casting (pg126 example)
  • Item 27: Favor generic methods
    •  generic methods use type inference to figure out the type of the invocation
    • generic static factory method (pg131)
    •  type parameters can be bounded by an expression that involves that type parameter itself
      • e.g. <T extends Comparable <T>>
        • this reads 'for every type T that can be compared to itself'
      • pg 133
  • Item 28: Use bounded wildcards to increase API flexibility
    • for maximum flexibility, use wildcard types on input parameters that represent producers or consumers 
      • if a type is both a producer and consumer, wildcards are useless
    • PECS - producer-extends, consumer-super
    • use wildcards so that you can use any subtype of a certain type in a list
      • e.g. stack.pushAll(Iterable<? extends E> src) { for(E e: src)...}
      • pg. 135
    • use wildcards so that you can require a method parameter to be able to store a generic type
      • e.g. stack.popAll(Collection<? extends E> dst) { ...dst.add(pop())}
      • pg. 136
    • do not use wildcard types as return types - it only causes the client code to have to use wildcard types and provides no additional flexibility
    • properly used, wildcard types are nearly invisible to a class' users
    • rarely, explicit type parameters are necessary
      • e.g. Set<Number> numbers = Union.<Number>union(integers, doubles);
    • Comparables and Comparators are always consumers (pg. 138)
      • always use Comparable<? super T> in preference to Comparable<T>
      • always use Comparator<? super T> in preference to Comparator<T>
      • e.g. public static <T extends Comparable<? super T>> T maxOf(List>? extends T> list)
  • Item 29: Consider typesafe heterogeneous containers
    •  The Class class has a generic method for casting safely
      • public class Class<T> { T cast(Object obj); }
    • The Class class has a method to cast to a subclass
      • someClassObj.asSubclass(Annotation.class);

Comments

Post a Comment

Popular posts from this blog

ChatGPT - How Long Till They Realize I’m a Robot?

Architectural Characteristics - Transcending Requirements

My experience with Udacity