Application Handling of Database Timeouts and Deadlocks

When database returns error code that says that:

  • limit of resources was exceeded or
  • there was a timeout or
  • there was a deadlock

then application needs to:

  1. explicitly rollback (conn.rollback()) and
  2. wait RETRY_WAIT_TIME and
  3. execute retry logic until MAX_RETRY_ATTEMPTS

When database returns error saying that:

  • maximum number of locks for a database was reached because insufficient memory was allocated to the lock list

then database will automatically rollback and application needs only to execute retry logic.

Tips
Try to avoid applications, that access database, starting at the same time. For multiple concurrent updates, increase the RETRY_WAIT_TIME or make it varying.

For the integration web-services – database for long running queries:
– identify these queries (e.g. complicated reports), put the to the queue, process them sequentially – email results later to the client or put the results to another table to be viewed later on by clients
– use asynchronous calls, ajax to refresh only part of web page after query completes (javascript callback)
– use popup with progress bar updated periodically by a separe thread polling the server about the progress.

Throttling – based on number of currently processed request – for overrloaded servers, discard new requests until internal load on server decreased.

Lazy loading – load only necessary data, other on demand
Facade design pattern – coarse grained calls instead fine – grained
Normalize to reduce data redundancy and denormalize to improve performance

If your application is suited to storing per-user state in the HttpSession, this option is often better than the alternatives. Storing session state in the client using HTTP cookies or hidden form fields has significant security risks — it exposes a part of your application internals to the untrusted client layer.
Session replication enables a host of benefits — load balancing, scalability, fault tolerance, and high availability.

Theoretically, it is possible to completely replicate session state coherently across a cluster, so that any node in the cluster can service any request, and a dumb load balancer can simply route the request in a round-robin fashion, avoiding hosts that have failed. However, such tight replication has a considerable performance cost and implementation complexity, and may also have scalability problems as the cluster approaches a certain size.

A more common approach is to combine load balancing with session affinity — the load balancer is able to associate connections with sessions and route subsequent requests within a session to the same server. This feature is supported by numerous hardware and software load balancers and means that replicated session information is only accessed when the primary connection host fails and the session needs to be failed over to another server.

surrogate keys (e.g. assigned by the database like Oracle sequences, Sybase identity
columns, max()+1, universally unique identifiers UUIDs, etc), natural keys (e.g. Tax File Numbers, Social
Security Numbers etc), and composite keys

Can we minimize the network trip by passing a coarse-grained value object instead of making 4 network trips with fine-grained parameters?

Should we use method level (coarse-grained) or code level (fine-grained) thread synchronization?

Should we hide the member variables to improve integrity and security?

Can we get a polymorphic behavior so that we can easily add new classes in the future?

Vertical scaling is achieved by increasing the number of servers running on a single machine. Horizontal scaling is achieved by increasing the number of machines in the cluster.
Horizontal scaling is more reliable than the vertical scaling because there are multiple machines involved
in the cluster. In vertical scaling the number of server instances that can be run on one machine are
determined by the CPU usage and the JVM heap memory.

Vertical slicing: Getting the reusable and flexible design the first time is impossible. By developing the initial
vertical slice of your design you eliminate any nasty integration issues later in your project. Also get the design patterns right early on by building the vertical slice. It will give you experience with what does work and what does not work with Java/J2EE. Once you are happy with the initial vertical slice then you can apply it across the application. The initial vertical slice should be based on a typical business use case.

Concurrency issues (multi-threading): What if two threads access my object simultaneously will it
corrupt the state of my object?
Transactional issues (ACID properties): What if two clients access the same data simultaneously?
What if one part of the transaction fails, do we rollback the whole transaction? Do we need a distributed
(i.e. JTA) transaction?. What if the client resubmits the same transactional page again?

Security issues: Are there any potential security holes for SQL injection or URL injection by hackers?

Will this application scale vertically and horizontally if the load increases? Should
this object be serializable? Does this object get stored in the HttpSession?

Creating and destroying valuable resources like database connections, threads etc can be expensive. So if a client is not using a resource can it be returned to a pool to be reused when other clients connect? What is the optimum pool size?

Caching: can we save network trips by storing the data in the server’s memory? How often do we have
to clear the cache to prevent the in memory data from becoming stale?

Transparent fail over: If one server crashes can the clients be routed to another server without any
interruptions?

Clustering: What if the server maintains a state when it crashes? Is this state replicated across the
other servers?

Profiling can be used to identify any performance issues or memory leaks. Profiling can identify what lines of code the program is spending the most time in? What call or invocation paths are used to reach at these lines? What kinds of objects are sitting in the heap? Where is the memory leak?

Use operating system process monitors like NT/XP Task Manager on PCs and commands like ps, iostat,
netstat, vmstat, uptime, nfsstat etc on UNIX machines.

In Java, typically the memory leak occurs when an object of a longer lifecycle has a reference to the objects
of a short life cycle. This prevents the objects with short life cycle being garbage collected. The developer must
remember to remove the reference to the short-lived objects from the long-lived objects. Objects with the same life cycle do not cause any problem because the garbage collector is smart enough to deal with the circular references.

Commonly used singleton design pattern can cause memory leaks. Singletons typically have a long life cycle. If a singleton has an ArrayList or a Hashtable then there is a potential for memory leaks.

Application design is one of the most important considerations for performance. A well-designed application will not only avoid many performance pitfalls but will also be easier to maintain and modify during the performance-testing phase of the project.

Use of multi-threading from a thread-pool (say 10 – 50 threads). Using a large number of threads
adversely affects performance by consuming memory through thread stacks and CPU by context
switching.

Database related performance bottlenecks.
Use proper database indexes. Numeric indices are more efficient than character based indices. Minimize
the number of columns in your composite keys. Performing a number of “INSERT” operations is more
efficient when fewer columns are indexed and “SELECT” operations are more efficient when, adequately
indexed based on columns frequently used in your “WHERE” clause. So it is a trade-off between
“SELECT” and “INSERT” operations.

Partition the database for performance based on the most frequently accessed data and least frequently
accessed data.

Use optimistic concurrency as opposed to pessimistic concurrency where appropriate.

Thread-safety issues
Unlike processes, threads share the same address space which means they can read and write the same variables and data structures.

Swing components can only be accessed by one thread at a time. A few operations are guaranteed to be
thread safe but the most others are not. Generally the Swing components should be accessed through an
event-dispatching thread.

A typical Servlet life cycle creates a single instance of each servlet and creates multiple threads to handle the service() method. The multi-threading aids efficiency but the servlet code must be coded in a thread
safe manner. The shared resources (e.g. instance variable) should be appropriately synchronized or should
only use variables in a read-only manner.

The declaration of variables in JSP is not thread-safe, because the declared variables end up in the
generated servlet as an instance variable, not within the body of the _jspservice() method.

Some Java Collection classes like HashMap, ArrayList etc are not thread-safe.

Some of the Java core library classes are not thread safe. For e.g. java.util.SimpleDateFormat,
java.util.Locale etc.

When a connection is created, it is in auto-commit mode. This means that each individual SQL statement is
treated as a transaction and will be automatically committed immediately after it is executed. The way to
allow two or more statements to be grouped into a transaction is to disable auto-commit mode. Disabling auto-commit mode can improve performance by minimizing number of times it accesses the database.

A
distributed transaction is an ACID transaction between two or more independent transactional resources
like two separate databases. For a transaction to commit successfully, all of the individual resources must
commit successfully. If any of them are unsuccessful, the transaction must roll back all of the resources. A 2-phase commit is an approach for committing a distributed transaction in 2 phases.

Isolation levels provide a degree of control of the effects one transaction can have on another concurrent
transaction.

Decide between optimistic and pessimistic concurrency control.

Evaluate a strategy to determine if the data is stale when using strategies to cache data.

OOD
When to use an Abstract Class: Abstract classes let you define some default behavior and force subclasses to provide any specific behavior.

When to use an Interface: If you need to change your design frequently, I prefer using interface to
abstract.

Prefer interface inheritance to implementation inheritance because it promotes the design concept of coding to an interface and reduces coupling. Interface inheritance can achieve code reuse with the help of object composition.

Composition (Black-box reuse) – Defined dynamically or at runtime via object references. Since only interfaces are used, it has the advantage of maintaining the integrity (i.e. encapsulation). Disadvantage of aggregation is that it increases the number of objects and relationships.

Inheritance (White-box reuse) – Inheritance is defined statically or at compile time. Inheritance allows an easy way to modify implementation for reusability. A disadvantage of inheritance is that it breaks
encapsulation, which implies implementation dependency. This means when you want to carry
out the redesign where the super class (i.e. parent class) has to be modified or replaced, which is
more likely to affect the subclasses as well. In general it will affect the whole inheritance
hierarchy.

Verdict: So the tendency is to favor compositionover inheritance.

The Front Controller pattern uses a single servlet, which acts as initial point of contact for handling all the requests, including invoking services such as security (authentication and authorization), logging,
gathering user input data from the request, gathering data required by the view etc by delegating to the helper classes, and managing the choice of an appropriate view with the dispatcher classes.

Use the data access object design pattern to promote the design concept of code to interface not implementation, so that the implementation can change without affecting the calling code.

There are some common names like cross site scripting, SQL injection, hidden field manipulation, cookie poisoning, etc for input tampering attacks.

The best practice to prevent the above mentioned security vulnerability is to strip any unwanted characters
and HTML tags from user input.

Perform rigorous positive input data validation. Positive input validation means checking the input data
against a list of valid characters like A-Z and 0-9 etc as opposed to checking for any invalid characters
because it is too difficult to determine all possible malicious characters.

Have a centralized code for input validation because scattered code is hard to maintain.

Handle your exceptions properly without revealing any sensitive information about your datasources,
table names etc, which could help them create a SQL injection attack. Catch all your exceptions and display harmless error messages to users and hackers alike.

Protect your Web resources like JSP files, HTML files, pdfs, css, script files etc behind the WEB-INF
directory.

Avoid using hidden fields, cookies etc to store sensitive state information.

Prefer prepared statements over statements to prevent any SQL injection attacks.

What language features are available to allow shared access to data in a multi-threading
environment? Synchronized block, Synchronized method, wait, notify

What Java language features would you use to implement a producer (one thread) and a wait, notify
consumer (another thread) passing data via a stack? wait, notify

What is the difference between String and StringBuffer? mutable, efficient

How do you exclude a field of the class from serialization? transient

What does overriding a method mean? (What about overloading?) inheritance (different signature)

What is the difference between a runtime exception and a checked exception? Must catch or throw checked
exceptions.

What does Servlet API provide to store user data between requests? HttpSession

What is the difference between forwarding a request and redirecting? redirect return to browser

What object do you use to forward a request? RequestDispatcher

What’s the requirement on data stored in HttpSession in a clustered (distributable)
environment? Serializable

If I store an object in session, then change its state, is the state replicated to distributed
Session? No, only on setAttribute() call.

What is a filter, and how does it work? Before/after request, chain.

What form of statement would you use to include user-supplied values? PreparedStatement

Why might a preparedStatement be more efficient than a statement? Execution plan cache.

How would you prevent an SQL injection attack in JDBC? PreparsedStatement

What is the performance impact of testing against NULL in WHERE clause on Oracle? Full table scan.

List advantages and disadvantages in using stored procedures? Pro: integration with existing dbase,
reduced network traffic Con: not portable, mutliple language

What is the difference between sql.Date, sql.Time, and sql.Timestamp? Date only, time only, date and time

If you had a missing int value how do you indicate this to PreparedStatement? setNull(pos, TYPE)

How can I perform multiple inserts in one database interaction? executeBatch

How might you model object inheritance in database tables? Table per hierarchy, table per class, table per concrete class

What would be the XPath to select any element called table with the class attribute of info? Table[@class=’info’]

What is the difference between a topic and a queue? broadcast, single

Describe some types of relationships can you show on class diagrams? generalization, aggregation, uses

Give a few reasons for using Java?
Built-in support for multi-threading, socket communication, and memory management (automatic garbage collection).
Object Oriented (OO).
Better portability than other languages across operating systems.
Supports Web based applications (Applet, Servlet, and JSP), distributed applications (sockets, RMI, EJB etc) and network protocols (HTTP, JRMP etc) with the help of extensive standardized APIs (Application Programming Interfaces).

What is the difference between C++ and Java?
Java does not support pointers. Pointers are inherently tricky to use and troublesome.
Java does not support multiple inheritances because it causes more problems than it solves.

Java does not support destructors but adds a finalize() method. Finalize methods are invoked by the garbage
collector prior to reclaiming the memory occupied by the object, which has the finalize() method. This means
you do not know when the objects are going to be finalized. Avoid using finalize() method to release non-
memory resources like file handles, sockets, database connections etc because Java has only a finite
number of these resources and you do not know when the garbage collection is going to kick in to release
these resources through the finalize() method.

Java does not include structures or unions because the traditional data structures are implemented as an
object oriented framework

All the code in Java program is encapsulated within classes therefore Java does not have global variables or
functions.

C++ requires explicit memory management, while Java includes automatic garbage collection.

Java class loaders
Class loaders are hierarchical. The very first class is especially loaded with
the help of static main( ) method declared in your class. All the subsequently loaded classes are loaded by the classes, which are already loaded and running. A class loader creates a namespace. All JVMs include at least one class loader that is embedded within the JVM called the primordial (or bootstrap) class loader.

Bootstrap – Loads JDK internal classes, typically loads rt.jar and i18n.jar
Extensions – Loads jar files from JDK extensions directory, usually lib/ext directory of the JRE
System – Loads classes from system classpath

Classes loaded by Bootstrap class loader have no visibility into classes

The classes loaded by system class loader have visibility into classes loaded by its parents (ie Extensions and Bootstrap class loaders).

Class loaders are hierarchical and use a delegation model when loading a class. Class loaders request their
parent to load the class first before attempting to load it themselves. When a class loader loads a class, the child class loaders in the hierarchy will never reload the class again. Hence uniqueness is maintained. Classes loaded by a child class loader have visibility into classes loaded by its parents up the hierarchy but the reverse is not true as explained in the above diagram.

c:\>java –cp c:/myProject com.xyz.client.Pet
OR
c:\>java -classpath c:/myProject/client.jar com.xyz.client.Pet

Important: Two objects loaded by different class loaders are never equal even if they carry the same values, which mean a class is uniquely identified in the context of the associated class loader. This applies to singletons too, where each class loader will have its own singleton.

Static class loading – Classes are statically loaded with Java’s “new” operator.

Dynamic loading is a technique for programmatically invoking the functions of a class loader at run time. Let us look at how to load classes dynamically. Class.forName (String className); //static method which returns a Class. class.newInstance (); //A non-static method, which creates an instance of a //class (i.e. creates an object).

//Static initializer block, which is executed only once when the class is loaded.

Don’t use inheritance just to get code reuse. If there is no ‘is a’ relationship then use composition for code
reuse. Overuse of implementation inheritance (uses the “extends” key word) can break all the subclasses, if
the superclass is modified.

Use interface inheritance with composition, which gives you code reuse.

Aggregation – Aggregation is an association in which one class belongs to a collection. This is a part of a whole relationship where a part can exist without a whole. For example a line item is a whole and product is a part. If a line item is deleted then corresponding product need not be deleted. So aggregation has a
weaker relationship.

Composition – Composition is an association in which one class belongs to a collection. This is a part of a whole relationship where a part cannot exist without a whole. If a whole is deleted then all parts are
deleted. For example An order is a whole and line items are parts. If an order is deleted then all corresponding line items for that order should be deleted. So composition has a stronger relationship.

Overloading deals with multiple methods in the same class with the same name but different method signatures.

Overriding deals with two methods, one in the parent class and the other one in the child class and has the same name and signatures.

Overriding lets you define the same operation in different ways for different object types.
Overloading lets you define the same operation in different ways for different data.

Original classes before the introduction of Collections API. Vector & Hashtable are synchronized. Any
method that touches their contents is thread-safe.

if you don’t need a thread safe collection, use the ArrayList or HashMap. Why pay the price of synchronization unnecessarily at the expense of performance degradation.

Java arrays are even faster than using an ArrayList/Vector and perhaps therefore may be preferable if you know the size of your array upfront (because arrays cannot grow as Lists do).

ArrayList/Vector are specialized data structures that internally uses an array with some convenient methods like add(..), remove(…) etc so that they can grow and shrink from their initial size. ArrayList also supports index based searches with indexOf(Object obj) and lastIndexOf(Object obj) methods.

Queue First item to be inserted is the first one to be removed. FIFO
Stack – Allows access to only last item inserted. LIFO

A TreeSet is an ordered HashSet, which implements the SortedSet interface.

A List is a collection with an ordered sequence of elements and may contain duplicates.

The Collections API also supports maps, but within a hierarchy distinct from the Collection interface.

A map can contain duplicate values, but the keys in a map must be distinct. HashMap, TreeMap and Hashtable are implementations of a Map interface. A TreeMap is an ordered HashMap, which implements the SortedMap interface.

The “Comparable” allows itself to compare with another similar object (i.e. A class that implements Comparable becomes an object to be compared with). The method compareTo() is specified in the interface.

The Comparator is used to compare two different objects. The following method is specified in the Comparator interface. public int compare(Object o1, Object o2)

Speaking of static factory methods, they are an alternative to creating objects through constructors. Unlike constructors, static factory methods are not required to create a new object (i.e. a duplicate object) each time they are invoked (e.g. immutable instances can be cached) and also they have a more meaningful names like valueOf, instanceOf, asList

Return zero length collections or arrays as opposed to returning null: CO Returning null instead of zero
length collection (use Collections.EMPTY_SET, Collections.EMPTY_LIST, Collections.EMPTY_MAP) is more
error prone, since the programmer writing the calling method might forget to handle a return value of null.

Immutable objects should be used as keys for the HashMap

Avoid storing unrelated or different types of objects into same collection: CO This is analogous to
storing items in pigeonholes without any labeling. To store items use value objects or data objects (as
opposed to storing every attribute in an ArrayList or HashMap). Provide wrapper classes around your
collections API classes like ArrayList, HashMap etc as shown in better approach column.

Avoid nested loops where possible (e.g. for loop within another for loop etc) and instead make use of an appropriate java collection.

The == returns true, if the variable reference points to the same object in memory. This is a “shallow
comparison”.

The equals() – returns the results of running the equals() method of a user supplied class, which compares the attribute values. The equals() method provides “deep comparison” by checking if two objects are
logically equal as opposed to the shallow comparison provided by the operator ==.

If equals() method does not exist in a user supplied class then the inherited Object class’s equals() method is run which evaluates if the references point to the same object in memory. The object.equals() works
just like the “==” operator (i.e shallow comparison).

If a class overrides the equals() method, it must implement the hashCode() method as well.

If a class overrides equals(), it must override hashCode().
If 2 objects are equal, then their hashCode values must be equal as well.
If a field is not used in equals(), then it must not be used in hashCode().
If it is accessed often, hashCode() is a candidate for caching to enhance performance.
It is a best practice to implement the user defined key class as an immutable

Immutable objects whose state (i.e. the object’s data) does not change once it is instantiated (i.e. it becomes a read-only object after instantiation).

Immutable classes can greatly simplify programming by freely allowing you to cache and share the references to the immutable objects without having to defensively copy them or without having to worry about their values becoming stale or corrupted.
Immutable classes are inherently thread-safe and you do not have to synchronize access to them to be used in a multi-threaded environment. So there is no chance of negative performance consequences.

1. A class is declared final (i.e. final classes cannot be extended).
public final class MyImmutable { … }
2. All its fields are final (final fields cannot be mutated once assigned).
private final int[] myArray; //do not declare as private final int[] myArray = null;
3. Do not provide any methods that can change the state of the immutable object in any way – not just setXXX
methods, but any methods which can change the state.
4. The “this” reference is not allowed to escape during construction from the immutable class and the immutable
class should have exclusive access to fields that contain references to mutable objects like arrays, collections
and mutable classes like Date etc by:
• Declaring the mutable references as private.
• Not returning or exposing the mutable references to the caller (this can be done by defensive copying)

Other languages use pass-by-reference or pass-by-pointer. But in Java no matter what type of argument you
pass the corresponding parameter (primitive variable or object reference) will get a copy of that data, which is exactly how pass-by-value (i.e. copy-by-value) works.

Serialization is a process of reading or writing an object. It is a process of saving an object’s state to a sequence of bytes, as well as a process of rebuilding those bytes back into a live object at some future time. An object is marked serializable by implementing the java.io.Serializable interface, which is only a marker interface — it simply allows the serialization mechanism to verify that the class can be persisted, typically to a file.
Transient variables cannot be serialized. The fields marked transient in a serializable object will not be
transmitted in the byte stream. An example would be a file handle, a database connection, a system thread etc.
Such objects are only meaningful locally. So they should be marked as transient in a serializable class.

Instance and static variables are associated with objects and therefore live in the heap.
Local variables are also known as stack variables because they live on the stack.

Private constructor is used if you do not want other classes to instantiate the object and to prevent subclassing.
The instantiation is done by a public static method (i.e. a static factory method) within the same class.
Used in the singleton design pattern.
Used in the factory method design pattern. e.g. java.util.Collections class (Refer
Used in utility classes e.g. StringUtils etc.

Each time an object is created in Java it goes into the area of memory known as heap. The primitive variables like int and double are allocated in the stack (i.e. Last In First Out queue), if they are local variables and in the heap if they are member variables (i.e. fields of a class). In Java methods and local variables are pushed into stack when a method is invoked and stack pointer is decremented when a method call is completed. In a multi-threaded application each thread will have its own stack but will share the same heap. This is why care should be taken in your code to avoid any concurrent access issues in the heap space. The stack is thread-safe because each thread will have its own stack with say 1MB RAM allocated for each thread but the heap is not thread-safe unless guarded with synchronization through your code

All Java methods are automatically re-entrant. It means that several threads can be executing the same method at once, each with its own copy of the local variables.

Idempotent methods are methods, which are written in such a way that repeated calls to the same method with the same arguments yield same results.

Each time an object is created in Java, it goes into the area of memory known as heap. The Java heap is called the garbage collectable heap. The garbage collection cannot be forced. The garbage collector runs in low memory situations. When it runs, it releases the memory allocated by an unreachable object. The garbage collector runs on a low priority daemon (i.e. background) thread. You can nicely ask the garbage collector to collect garbage by calling System.gc() but you can’t force it.

A soft reference will only get removed if memory is low. So it is useful for implementing caches while
avoiding memory leaks.
A weak reference will get removed on the next garbage collection cycle. Can be used for implementing
canonical maps. The java.util.WeakHashMap implements a HashMap with keys held by weak references.

Why should you throw an exception early – as meeting preconditions
The exception stack trace helps you pinpoint where an exception occurred by showing you the exact sequence of method calls that lead to the exception. By throwing your exception early, the exception becomes more accurate and more specific.

Why should you catch a checked exception late in a catch {} block?
You should not try to catch the exception before your program can handle it in an appropriate manner.
The best practice is to catch the exception at the appropriate layer (e.g. an exception thrown at an integration layer can be caught at a presentation layer in a catch {} block), where your program can either meaningfully recover from the exception and continue to execute or log the exception only once in detail, so that user can identify the cause of the exception.

Use checked exceptions when the client code can take some useful recovery action based on information in exception. Use unchecked exception when client code cannot do anything.

Briefly explain high-level thread states
Runnable — waiting for its turn to be picked for execution by the thread scheduler based on thread priorities.
Running: The processor is actively executing the thread code. It runs until it becomes blocked, or voluntarily
gives up its turn with this static method Thread.yield(). Because of context switching overhead, yield() should
not be used very frequently.
Waiting: A thread is in a blocked state while it waits for some external processing such as file I/O to finish.
Sleeping: Java threads are forcibly put to sleep (suspended) with this overloaded method:
Thread.sleep(milliseconds), Thread.sleep(milliseconds, nanoseconds);
Blocked on I/O: Will move to runnable after I/O condition like reading bytes of data etc changes.
Blocked on synchronization: Will move to Runnable when a lock is acquired.
Dead: The thread is finished working.

When a task invokes yield(), it changes from running state to runnable state. When a task invokes sleep(), it
changes from running state to waiting/sleeping state.

The method wait(1000), causes the current thread to sleep up to one second. A thread could sleep less than 1 second if it receives the notify() or notifyAll() method call. call to sleep(1000) causes the current thread to sleep for exactly 1 second.

If 2 different threads hit 2 different synchronized methods in an object at the same time will they both continue?
No. Only one method can acquire the lock.

Occasionally threads have to block on conditions other than object locks. I/O is the best example of this.

Be sure to not synchronize code that makes blocking calls, or make sure that a non-synchronized method
exists on an object with synchronized blocking code.

The J2SE 5.0 release is focused along the key areas of ease of development, scalability, performance, quality, etc. The new features include generics, metadata (aka annotations), autoboxing and auto-unboxing of
primitive types, enhanced “for” loop, enumerated type, static import, C style formatted output, formatted
input, varargs,

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s