Subjects
PRICING
COURSES
SIGN IN
Start Free Trial
Jinesh D.
Former Intro CS TA
Tutor Satisfaction Guarantee
Javascript Programming
TutorMe
Question:

How do you avoid race conditions between asynchronous function calls?

Jinesh D.
Answer:

A race condition occurs when two asynchronous function calls might have different results depending on which is completed first. Remember, from the point of view of the programmer, which function executes to completion first is totally arbitrary (it relies on factors almost impossible to reason about from the software layer of abstraction), so we can't make one function evaluate before the other without some kind of trickery. JavaScript allows several ways to prevent race conditions. One might be to simulate synchronous functionality by calling one asynchronous function in the callback function of another. Recall that a callback function is a function which is passed to another function as an argument, and executes only upon completion of the function to which it was passed. So in this way, if we include a call to our second asynchronous function in the callback of the first, rather than in the next independent instruction, we can ensure that the 2nd function is called only after the 1st one completes, thus avoiding the race condition. Promise libraries work similarly to the above, while providing some syntactic sugar and a streamlined way to handle errors related to concurrency. Yet another way would be to use locks. A lock is a simple structure that tells a program not to evaluate beyond a certain line of code until it has been "acquired", or unlocked. Typically, to avoid a race condition, you might place a lock in the middle of one function and acquire it at some critical point in the other, this critical point being the point beyond which the race condition is no longer possible. Consider the following example: function X() { a += "first" console.log(a); } function Y() { a += "second"; } We could place the lock in the middle of X and acquire it at the end of Y if we wanted to ensure that both "first" and "second" are added to a before printing even when X and Y are run asynchronously. The lock would prevent "console.log(a)" from being executed unless the lock has been acquired at the end of Y. Note that the lock isn't set until "a += first" is executed, since we placed the lock set statement after it. Therefore, there is no possible race condition. The advantage of using locks is that we can allow portions of the offending functions to run, increasing our efficiency with high probability since less time is spent wasted waiting for the lock to be acquired unless the hardware responsible for deciding which behaves in a way that is uniquely disadvantageous to us. There are many other ways we could do this, some of which are more sophisticated than others, but this is a simple introduction to how you could avoid race conditions in JavaScript.

Java Programming
TutorMe
Question:

Why doesn't Java allow multiple inheritance?

Jinesh D.
Answer:

The "diamond problem" is an interesting consequence of multiple inheritance that Java chose to avoid entirely by not allowing multiple inheritance to begin with. The diamond problem goes as follows. Suppose I have a class A, and classes B and C that inherit from A. Let's say I have some method "foo" in A, and let's say both B and C have their own override of foo. To be clear, let's say "foo" in A prints "Car", while "foo" in B prints "Mercedes" and "foo" in C prints "BMW". Suppose I have a fourth class, D, which extends both B and C. The question that the diamond problem poses is, "what will calling 'foo' on an object of class D do?". The answer is pretty unclear, because D should be inheriting the overrides of both B and C for the same method! How do we know which "foo" override should be called? The simple answer is that we don't. There's no way to resolve this issue reasonably. We could arbitrarily choose one or the other, or we could throw an exception, but either of these is a reasonably inelegant solution. The creators of Java decided that it would be a better idea for people who wanted multiple inheritance-like behavior to use interfaces to specify that behavior instead (a class may implement any number of interfaces) and implement it independently to avoid confusion. Some people argue that this reduces the power and expressiveness of the object-oriented paradigm, but this is just the decision that the creators of Java made in favor of safety.

Computer Science (General)
TutorMe
Question:

Explain to someone who knows nothing about programming what a higher-order function is.

Jinesh D.
Answer:

Note: I've avoided defining unnecessary terminology like "calling" functions or "variables" or "references" to streamline the answer and also to be less confusing to a reader. Programming is essentially telling a computer to do things for you. In programming, a function is a name for a specific list of instructions. If I have a function named "takeScreenshot", and I write a program that tells my computer to use "takeScreenshot", my computer knows that I want it to execute the list of instructions associated with the name "takeScreenshot". A function can have "arguments". What this means is that a function can receive some sort of input, (it could be several distinct values, and each of these values is one "argument") from the programmer and take some action whose result depends on that input. However, you have to clearly tell the computer what those arguments are, so that it knows how to use them. For example, I might define the function "takeScreenshot" to accept 4 numbers as arguments. I might then use the arguments "200,200,300,300" with the function "takeScreenshot", which would be analogous to telling my computer "take a screenshot of the rectangle on the screen from the coordinates (200,200) to (300,300)" if my "takeScreenshot" function has instructions that tell my computer how to interpret the arguments as coordinates on the screen. Arguments can be any kind of information, provided that I show the computer how to use that information. What this means is that in theory, I can also allow a function to be the argument to another function. What does this mean? It means something like telling the computer "When I need use function X, I'll give you the name of some list of instructions. Whatever those instructions may be, execute them and do something with the result and output the final result." However, this type of function that uses another function as an argument, called a "higher-order function", has one caveat: you also have to tell the higher-order function what the argument function is going to be generally. This means we need to specify to the higher-order function what arguments the argument function itself will use, and what kind of output it will give us, so that the computer can reasonably determine how to use the function without a guarantee of what exactly it does. To be clear, in my above example, I might have said "I'll give you the name of some list of instructions that takes 2 numbers as input and outputs 1 number. Use that list of instructions on the first two numbers I give you, then use the instructions again on the result of that and the third number. Output the result, which is a single number". In this way I can use any function which uses two numbers and outputs one number as an argument, but if I use a different kind of function, my instructions won't make any sense. To give another example, let's say you have three functions, "doMath", "addNumbers", and "multiplyNumbers". Let's say doMath takes 5 arguments, 2 function arguments and 3 number arguments. Let's say the instructions defined by "doMath" are something like "use the two functions I give you to operate on the 3 numbers and give me the result". So then if I use "doMath" with the arguments "addNumbers, addNumbers, 1, 2, 4", it would add 1, 2 and 3 to give me 7. However, If I used doMath with the arguments "addNumbers, multiplyNumbers, 1, 2, 4" it would first add 1 and 2 to give 3, and then multiply 3 and 4 to give 12 as the final output. In this way, "doMath" can be used to do dramatically different things based on the functions I use with it as arguments. This is useful because it lets me capture complex, generalized logic that can be reused in a number of different ways.

Send a message explaining your
needs and Jinesh will reply soon.
Contact Jinesh
Ready now? Request a lesson.
Start Session
FAQs
What is a lesson?
A lesson is virtual lesson space on our platform where you and a tutor can communicate. You'll have the option to communicate using video/audio as well as text chat. You can also upload documents, edit papers in real time and use our cutting-edge virtual whiteboard.
How do I begin a lesson?
If the tutor is currently online, you can click the "Start Session" button above. If they are offline, you can always send them a message to schedule a lesson.
Who are TutorMe tutors?
Many of our tutors are current college students or recent graduates of top-tier universities like MIT, Harvard and USC. TutorMe has thousands of top-quality tutors available to work with you.