Reactive programming with RxJava allows for asynchronous and event-based programming by using Observables that push data via onNext(), onError(), and onComplete() calls, where Observables can be either "cold" and lazily produce values only after subscription or "hot" and produce values independently of subscriptions; key concepts include asynchronous data streams, the Observable interface and contract, and differences between RxJava 1 and 2 such as handling of null values and new types like Maybe and Processors.