----
It should be mandatory that all software and hardware engineer do #1 / #2 / #3. All embedded software engineers and ALL digital design enginers should also do #4.
#1 - How to program a computer at its lowest-level? Write an assembly program, then convert it BY-HAND to hex, then load it into a single board computer using one switch per bit of the address and data buses, like an ALTAIR 8800, run it, halt, write down results from data memory. All good software engineers must know things from the very lowest levels.
#2 - Do the above, but use a built-in monitor to download the program via RS232. Use monitor commands to read the contents of memory and perform of monitor tasks.
#3 - Do the above, but download the program via JTAG. Use JTAG to read the contents of memory.
#4 - Do the above but load program in serial-flash / SD / NOR-FLASH / EPROM, then boot from it on a single-board computer.
-----
Study all the popular source control methods, the advantages and disadvantages of each one, hands on use of the most popular ones, configure and setup source control, how to attach to source control via the internet and download source code from completely different systems, including public source code.
----
All the ways to test software. Hands on!
----
Extreme software commenting. Document the heck out of some functions. Learn how and what is important to document.
----
Learn how to write software specifications. Learn how to read software specifications and implement a program.
----
Write a manual to document how a completed software program runs.
----
Learn how to communicate with the opposite sex.
Learn how to communicate with managers.
Learn how to communicate with fellow engineers.
----
Learn how to write effective emails...without rambling and not do other mindless stupid things.
----
How to install and uninstall software from every version of windows / linux 2.6 / mac 10.x.
----
likely many other important things that I've forgot to include :)