This is a prerequisite for further topology optimization in the Streams DSL: we should let different operators inside the DSL to be able to pass along key and value serdes if they are not explicitly specified by users. The serde specification precedence should generally be:
1) Overridden values via control objects (e.g. Materialized, Serialized, Consumed, etc)
2) Serdes that can be inferred from the operator itself (e.g. groupBy().count(), where value serde can default to `LongSerde`).
3) Serde inherited from parent operator if possible (note if the key / value types have been changed, then the corresponding serde cannot be inherited).
4) Default serde specified in the config.