- java takes care of memory management and pointers
- java has libraries and community support
java | c++ |
---|---|
memory-secured | memory issues |
OOD | OOD |
data type | size |
---|---|
byte | 8-bit |
short | 16-bit |
int | 32-bit |
long | 64-bit |
float | 32-bit |
double | 64-bit |
int[] numbers = new int[10];
- explicit array: fixed size array; vs dynamic collections
- devices used to control, monitor, or assist operation of equipment, machinery, or plant
- types: (simple) embedded system, (complex) embedded computer system
- in an embedded system, sensors --> CPU --> actuators
- sensor readings are continuous and analog
- computers are discrete-time and digital
- so report discrete values at given times from the sensors
- analog-to-digital-converter (ADC): part of the codec; coverts continuous-time analog signal to discrete-time digital signal
- actuators: convert output from computer system into some effect on environment
- the program needs to
- handle incoming signals from sensors
- generate desired signals to actuators
- coordinate diff events from diff hardware pieces
- loop indefinitely until user shuts down system
- sensor > flag > handler > actuator
- sensor > event manager > handler > actuator
- everything is already automated
- sensor event manager: part of the OS that checks flags raised by sensors and acts when necessary
- event handler: action sequence that OS does upon events
- every event is distinct course of actions
- every sensor needs a Handler that programmer defines
- Android OS is standardized OS:
- standardized hardware and software APIs
- manage hardware platform
- implements Sensor Event Manager to take care of sensor-actuator interactions
- event manager: standardized loop for event checking, standardized procedures for interacting with sensor events/data delivery, event: handler lookup table
- exception: signal of runtime execution error; an event that indicates something is wrong during execution, and computer doesn't know what to do
- java
throws
errors - two sources: automatically generated by JRE, explicitly generated by programmer
- handle: take actions to deal with Exception
- exception handling hierarchy (call stack)
- local exception handler > exception handlers in the invoker/caller > handlers in higher invokers/callers > handlers in main method >> execution stops + error message on screen
try - catch
block; can also have multiple catch blocksfinally
block: always executes after try-catch block- purpose: avoid accidental bypass of mandatory cleanup code
- sometimes don't want to handle the error
- try-catch block is system-resource demanding
- most exceptions can be prevented with code review and test cases
- exceptions that matter are runtime-determined user/machine mistakes that are recoverable
- sometimes, just force invoker of method to handle exception > "pass the hot potato"
- declaring pass on exceptions: handling the
IOException
is the responsibility of the invoker ofwriteList()
public void writeList() throws IOException
- java. I/O is modeled as a stream
- stream: sequence of data; used to read data (input stream) or write data (output stream)
- the superclasses:
InputStream
andOutputStream
- file streams are closed in
finally
block - very bad efficiency -->
in.read()
accesses hard disk one character (one byte) at a time- solution: reduce disk access
public class CopyFile {
public static void main(String[] args) throws IOException {
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("input.txt");
out = new FileOutputStream("output.txt");
int c;
while ((c = in.read()) != -1) {
out.write(c);
}
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}
-
reconfigurable size (usu multiples of 1024 bytes)
-
given file name, BufferedReader reads bytes from the file and store in buffer until buffer is full
-
readLine()
method requests all data before seeing\n
- data can be in the buffer already
- BufferedReader checks its own buffer, provides data from buffer if requested data is found (disk access is avoided)
- if BufferedReader reaches end of buffer before finding requested data, then disk access to fill up buffer with next chunk of data
-
significantly reduces number of disk access
- reconfigurable size
- outputs from
println()
is kept in buffer, disk write only happens when buffer is full - program crash > disappearance of some expected output data, because data in buffer may not have been written to disk
- if program catches Exception (leading to program crash),
flush()
can be called to force buffer to output data before it's full - closing the stream also flushes the buffer
public class CopyFile {
public static void main(String[] args) throws IOException {
BufferedReader inputStream = null;
PrintWriter outputStream = null;
try {
inputStream = new BufferedReader(new FileReader("input.txt"));
outputStream = new PrintWriter(new FileWriter("output.txt"));
String l;
while ((l = inputStream.readLine()) != null) {
outputStream.println(l);
}
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
}
}
- internal storage: hidden in OS; cannot access files stored in there, unless within program that creates the files
- default external storage: located under
Android/data
folder- use
getExternalFileDir(FOLDER_NAME)
to obtain absolute path
- use
- additional external storages: SD cards, SIM cards, etc. need to configure permission parameters in
Manifest.xml
to access from within app
FileReader
andFileWriter
are grouped under data type file
File file = new File(getDefaultFileDir(FOLDER_NAME));
PrintWriter pwr = new PrintWriter(file);
- events are random incidents
- system has internal states that can its response to the same event
- environmental stimulants + user input > finite state machine (internal state feedback) > machine output
external | internal |
---|---|
external stimulants | events |
internal stimulants | system states |
output | combinatorial result of external and internal stimulants |
- graphical representation of FSM
- used by embedded hardware and software designers
- generated from functional description of system
- used as reference to create software/hardware version of FSM implementation
look at slides from lec5 for more UML stuff
- events: excitations to a system
- hardware excitations: sensor reading changes
- software excitations: timer expires
- in Android: notification of change of state of system
- handlers/listeners: response of system to the excitation
- sensor event handlers, timer handlers, button event listeners
- events and its data gets passed to Android's Sensor Event Manager >> respective event listeners
- event driven: reactive, not proactive
- sensor > event manager > handler > actuator
- callback methods (classes): system/users/environments decides what happens, not the program
- inversion of control
- allows for asynchronous, non-blocking program exec.
- with callback methods, time-consuming tasks (TCT) won't delay program because it's running in parallel
- concurrent programming uses power of multi-core CPU/similar processor structures
- callbacks are facilitating tool of program concurrency
- modern embedded systems: each sensor/actuator has >= 1 micro-controller within
- used for sensor monitoring/actuator control; communication with CPU
- polling (passive synchronization): watches parameter for change at any given time
- interrupt (active synchronization): raises attention when parameter is confirmed to be changed
- CPU takes role of checking devices status
- passive synchronization; devices passively report status changes
- programmers decide how much system allocates to checking device status
polling "intensity level" | description |
---|---|
tight polling | entire system resource dedicated to monitoring changes |
periodic polling | using a fixed timer period, use system resources to obtain changes |
occasional polling | obtain changes when system resources are free |
- every Event Listener thread has a tight-polling loop used to monitor sensor events
- hardware version of Event-Handler setup
- active synchronization; device actively reporting changes to CPU
- devices setup for interrupts are connected to CPUs (interrupt request (IRQ) line)
- programmer creates program to take care of interrupt when specific IRQ is raised >> interrupt service routine (ISR) or interrupt handler
- IRQ >> CPU takes an action
- events are random occurrences
- event listeners are parallel threads to main program (concurrent programming)
- timer: periodic event generator
- parallel thread to main program, own configurable expiry time, can be one-shot timer or recurring, has Timer Handler
- tasks are put in Timer Handler for repeating timer, so when TimerExpire event happens, it gets fired up
- interval timer: period task performer (period polling)
- watchdog timer: system deadlock prevention before TCT that could crash
- one-shot timer with duration longer than estimated max process time of TCT so that if TCT completes before timer, TCT probably got stuck
- TimerExpire event >> TimerHandler >> TCT forced to terminate in the Handler
- activity: full-screen window that users can interact with
- widgets (views): interactive items that allow for user interactions
- single-activity app: app with one full-screen interface
- multi-activity app: app with multiple full-screen interfaces, functionally dependent on each other
- activity cross-dependency: activities in one app may have dependency on activities in another app
- task (activity call stack): android OS has a task stack (prevents disruption to functional dependency)
- multi-tasking: switching between Tasks; switch activity stacks between foreground activity and background activity
-
events take place between state transitions
-
onCreate(): activity initialized, ready in memory
-
onStart(): moved to foreground, active, initial state
-
onResume(): foreground active, running state
-
onPause(): background inactive, data persistent
-
onStop(): background inactive, data destroyed
-
onDestroy(): activity removed from memory
- to conserve data: need a Bundle and helper method onSaveInstanceState()
- called in onDestroy() right before activity is destroyed
- everything in the bundle is available in onCreate() when the activity is brought back
- bundle is a key-value map
- onSaveInstanceState() is a method in AppCompatActivity class
- use
putString(String key, String value)
- to get data:
protected void onCreate(Bundle savedInstanceState) {
if (savedInstanceState != null) {
data = savedInstanceState.getString("key");
}
}
- a markup language; structured document format (define appearance and properties of contents of document)
- no intrinsic meaning
- XML documents are displayed to users through XML parser
<?xml version="1.0" encoding="utf-8"?>
stuff
- micro-electro-mechanical (MEM) device that senses ambient mechanical movements
- transitional acceleration, torsional acceleration
- how does it work: relative positioning of "proof mass" to surrounding wall under acceleration (mass inertia)
- signal analysis: software noise minimization and main signal recognition
- inheritance, polymorphism, interface/abstract classes
- class name, fields, methods (member functions, constructor, destructor)
- class instantiation: dynamic memory allocation, just need keyword
new
- all non-static fields and methods are accessible after the class is instantiated
static
fields and methods are pre-allocated in memory with unique memory address reference before execution so they are readily accessible without creating instance of class
- data encapsulation: fields and functions can be intended just for internal operations of class, and be only accessible in the class
- visibility: public, private, protected
- uniqueness: final, static
- macro-management: class instantiation allows multiple instances of the class without micromanagement in memory allocation
- 3 column:
- class name (bold)
- attributes/fields : data type
- operations (constructors, methods, etc) : return type
- visibility modifier (put in front of field/method): public (+), private (-), protected (#)
- uniqueness modifier: static (underline), final (capitalization)
- destructor/package (~)
- range of values (..)
- separator of items in set (,)
- in in front of input parameters
- out in front of output parameters
extends
: facilitates inheritancesuper
: reference instance of super-classsuper()
: calls constructor of super-classthis
: reference instance of the child-class
- signal cleansing: remove unwanted noise to keep the main signal
- pattern recognition: using characteristics from cleaned signal to find pattern
- low pass filter: rejects high-frequency signals at input and pass low-frequency signals to output
- filteredReading += (newReading - filteredReading) / C;
- C is the attenuation factor
- interface
- abstract class
- override and overload
- polymorphism
- scope of field
- types: structural (class diagram), behavioral (state diagram), interaction (sequence)
- look at slides
- functional verification: every stage of software development
- result verification: every debug attempt
- integrity verification (regression test): after every software update
- testing levels:
- smoke test: test software after change applied; if fail > revert change
- unit test: test on small piece of code (JUnit)
- integration test: bring modules together to test combined behavior
- system test: test entire system
- stress test: execute over period of time with long and cyclic test plans
- regression test: previously fixed bugs should stay fixed
- three core elements in JUnit test:
- module (code) under test
- test file (test case class)
- test runner class
- assertion:
asserEquals()
- 3 types of code coverage:
- line coverage: a line is covered when it's tested by test cases
- branch coverage: condition branch is covered
- multiple condition coverage: module with multiple conditions is covered
- bug localization: estimate location of bug based on the nature of the unexpected output
- code instrumentation: printing out the intermediate steps
- single-step execution (hardcore debugging)
- use a breakpoint
- breakpoints:
- line breakpoint: start single step at this line
- method breakpoint: start when the method is invoked
- exception breakpoint: when the Exception is thrown, start single step
- watchpoint: start single step when the field is changed
- step over, step into, step out, resume, rerun, stop
- common bug: basic; semantic with 100% predictable output
- sporadic bug: second basic; only occurs in edge cases
- Heisenbug: the hard bug (eg. race condition, memory errors, optimizations)
- bugs hiding behind bugs
- secret bugs: do not have full access to bug report (possibly from company confidentiality)
- configuration bug: need to properly configure runtime environment
- hardware bug
- not-a-bug
- processes vs. threads
- threads faster to create/destroy than processes
- less time to switch between threads in same process
- threads in same process share memory/files
- time division/time slicing: threads take turns sharing the CPU resource (perceived as threads executing in parallel)
- thread states:
- executing: thread occupies one CPU and command sequence is executing
- ready: thread has assess to all needed resources, waiting to occupy CPU
- blocked: thread does not have all needed resources, blocked from command execution on CPU
- cooperative multithreading: each thread yields CPU proactively when appropriate
- for embedded systems that do not manage threads
- could be very efficient
- problem: greedy threads
- pre-emptive multithreading: OS forces thread to switch when it is time
- in most standard OSes
- ???
- "chronological message exchange"
- instance: object in the interaction sequence (ie. thread, process, system)
- instance name: object type
- lifeline: vertical, dashed, unitless time line
- creation and destruction of corresponding instance on lifeline
- action box: on the lifeline of the Life Time of the instance
- rectangular box on the lifeline
- synchronous message: solid arrow-headed line labelled with method call
- inquiring instance is blocked, waiting for response of responding instance
- asynchronous message: dotted arrow-headed line labelled with field containing response
- inquiring instance does not wait for response of responding instance
- message condition: condition to be met before message can be issued
- [Guard] Action
- process
- create unit test / code instrumentation
- run test
- make refactoring changes
- run test again
- evaluate results
- simple techniques:
- method extraction
- repeated code that can be replaced with a method call
- magic number removal
- assign magic number to a constant field
- variable naming
- rename
- method naming
- rename
- OOD techniques:
- encapsulating fields
- make inappropriate public fields private or protected
- getter-setter methods
- generalize types
- create superclass (concrete or abstract) and move repeated content
- extract method / class
- create new method / class that should be logically isolated
- inline method / class
- combine two methods / classes that should be merged
- move / pull-up / push-down fields & methods
- pull-up : if used in most subclasses, move to superclass
- pull-down : if used in few subclasses, move to subclasses
- replace conditionals with polymorphism
- antipatterns:
- the blob
- one class with too much logic --> extract methods / classes
- lava flow
- old useless code left behind --> delete it
- functional decomposition
- coding style like structural / sequential languages when OOP
- copy-and-paste programming
- copied code segments --> extract methods / classes
- poltergeists
- inline poltergeist methods / classes (exist but don't do much)
- golden hammer
- class designed to handle every possible event --> extract classes and specialize them
- exceptions as control flows
- try-catch to catch expected Exception --> use if-else
- spaghetti code
- no structure, small # of objects with long methods --> extract and restructure
- verification & validation
- build the thing right (meet requirements through testing and static analysis)
- build the right thing (check design against customer's needs through beta testing)
- software maintenance: rewrite vs. patching
- types of maintenance: corrective, adaptive, perfective, preventive
- software licensing: legal instrument describing how piece of software can be used / distributed
- proprietary license (copyright): strictest software license, impossible to generalize
- general public license (copy-left): mandatory non-profit software modules
- Berkeley software distribution (BSD): disclaims all liabilities
- Mozilla public license (MPL, hybrid): open-source license, allow source code to be mixed
- public domain (license-free): no copyright owner
- parametric object selection: invoke method from object without knowing specific instance
- linked list of generic types:
- have a linked list of all the object instances and just invoke that method that is overriden in each subclass
- listener interface allows the correct methods to be implemented in all Listeners
- Manchester coding scheme: used in Wired Network Communication for Noise Tolerance
- G.E. Thomas Scheme
- data 0, network 0-1 (rising)
- data 1, network 1-0 (falling)
- IEEE 802.3 Scheme
- data 0, network 1-0 (falling)
- data 1, network 0-1 (rising)
- G.E. Thomas Scheme
- decoder design: implement in code