Sling, OSGi and JCR
URL resolution is the core skill
Sling resolves a request in order: resource path โ resource type โ script/component. A URL like /content/mysite/en/page.hero.mobile.html/extra/suffix decomposes into resource path (/content/mysite/en/page), selectors (hero, mobile), extension (html) and suffix (/extra/suffix). The resource's sling:resourceType (e.g. mysite/components/page) is walked up the sling:resourceSuperType chain, and the matching script (.html, .servlet, or a Servlet registered by resource type) is chosen. Related concepts: sling:vanityPath, /etc/map mappings, and the resource resolver's search paths that let /apps override /libs.
OSGi and Felix
AEM runs Apache Felix. Bundles are the unit of code; Declarative Services annotations (@Component, @Service, @Reference, @Activate, @Designate) create components and configurations. Configurations are bound by PID (the component name or an explicit service.pid), can be run-mode specific (config.author, config.publish), and can be factory configurations for multiple instances. Ordering matters: use @Reference(cardinality=..., policy=OPTIONAL) or reference the ConfigurationAdmin when activation order is uncertain.
JCR and Oak
Nodes and properties; nt:unstructured for authored content; mixins (mix:versionable, cq:Page, dam:Asset) add behaviour. Reads go through a ResourceResolver (never keep it in a static field). Queries use JCR-SQL2 or XPath - both need a suitable Oak index; unindexed traversal queries are the classic performance trap.
Rule of thumb: to debug rendering, find the resource type, climb the supertype chain, then pick the most specific script - that ordering explains most "why is my component not rendering?" questions.