Most complex libraries (or systems) in java require reflection to meet the inherent complexity;
Most complex libraries in c++ require template meta-programming.
But these are for different reasons… which I’m not confident to point out.
Most complex python systems require … reflection + import hacks? I feel python’s reflection (as with other scripting languages) is more powerful, less restricted. I feel reflection is at the core of some (most?) of the power features in python – import, polymorphism
Based on whatever little I know, here are some technical advantages of c# over java.
(Master these c# feature and mention them in your next java interview 🙂
- C# has many more advantages on desktop GUI, but today let’s focus on server side.
- [L] generics —- c# generics were designed with full knowledge of java/c++ shortcomings. Simpler than c++ (but less powerful), but more complete than java (no type erasure). For example see type constraints.
- [L] delegates —- Rather useful. Some (but not all) of its functionalities can be emulated in java8.
- [L] c# can access low-level windows concurrency constructs such as event wait handles. Windows JVM offers a standardized, “reduced-fat” facade. If you want optimal concurrency on windows, use VC++, or c#.
- [L] reflection —- is more complete than java. Over the years java reflection proved to be extremely powerful. Not sure if c# has the same power, but c# surely added a few features such as Reflection.Emit.
- concurrency —- dotnet offers many innovative concurrency features. All high level features, so probably achievable in java too.
- tight integration with COM and MS Office. In fact, there are multiple official and unofficial frameworks to write Excel add-ins in c#
- tight integration with high-level commercial products from Microsoft like MSSQL, sharepoint
- tight integration with windows infrastructure like Windows Services (like network daemons), WCF, Windows networking, Windows web server, windows remoting, windows registry, PowerShell, windows software installation etc
- c# gives programmers more access to low-level windows system API, via unmanaged code (I don’t have examples). In contrast, Java programmers typically use JNI, but I guess the java security policy restricts this access.
- probably higher performance than JVM on windows
[L = low-level feature]
If you want highest performance on Windows, low-level access to windows OS, but without the complexity of VC++ and MFC, then c# is the language of choice. It is high-level, convenient like java but flexible enough to let you go one level lower when you need to.
Another way to address your question — listen to the the complaints against java. (Put aside the complaints of GUI programmers.)
Even if a (rational, objective) architect doesn’t recognize any of these as important advantages, she may still favor c# over java because she is familiar and competent ONLY in the Microsoft ecosystem. She could point out countless features in Visual Studio and numerous windows development tools that are rather different from the java tool set, so different that it would take months and years to learn.
Also, there are many design trade-off and implementation techniques built on and for Dotnet. If she is reliant on and comfortable in this ecosystem, she would see the java ecosystem as alien, incomplete, inconvenient and unproductive. Remember when we first moved to U.S. — everything inconvenient.
On a more serious note, her design ideas may not be achievable using java. So java would appear to be missing important features and tools. In a nutshell, for her java is a capable and complete ecosystem theoretically, but in practice an incomplete solution.
A Shanghai Morgan Stanley interviewer asked in a 2017 java interview.
One hypothesis — no free() or delete() in java, so the memory manager doesn’t need to handle reclaiming and reusing the memory. [[optimizedC++]] P333 confirmed the c++ mem mgr need that.
One hypothesis — after a warm-up period, based on heuristics JIT compiler could aggressively compile bytecode into machine code with speedy shortcuts for the “normal” code path + special code path to handle the abnormal conditions. Here’s an analogy — if every borrower seen so far has acceptable credit score, the bank may simplify credit check and have special procedure to deal with defaults. For most of the cases this work flow is faster than the traditional.
http://www.javaworld.com/article/2076593/performance-tests-show-java-as-fast-as-c–.html is a 1998 research.
In my GS-PWM days, a colleague circulated a publication that java could match C in performance.
https://stackoverflow.com/questions/1984856/java-runtime-performance-vs-native-c-c-code is not a published expert but he says:
On average, a garbage collector is far faster than manual memory management, for many reasons:
- on a managed heap, dynamic allocations can be done much faster than the classic heap
- shared ownership can be handled with negligible amortized cost, where in a native language you’d have to use reference counting which is awfully expensive
- in some (possibly rare and contrived) cases, object destruction is vastly simplified as well (Most Java objects can be reclaimed just by GC’ing the memory block. In C++ destructors must always be executed)
See also https://bintanvictor.wordpress.com/2009/03/21/realtime-inter-vm-communication-in-front-desk-trading-sys/
These are in the QQ category i.e. skills required for QnA IV only.
Q1: 3 threads to print the numbers 1,2,3,4,5… in deterministic, serial order. Just like single-threaded.
Q1b: what if JVM A has T1, T2, and JVM B has T3? How do they coordinate?
%%A: in C++ shared memory is the fastest IPC solution for large data volume. For signaling, perhaps a semaphore or named pipe
%%A: I feel the mutex is probably an kernel object, accessible by multiple processes.
On Windows, mutex, wait handle, … are all accessible cross-process, but java (on Windows or unix) is designed differently and doen’t have these cross-process synchronization devices.
%%A: use a database table with one row one column. Database can notify a JVM.
AA: The java.nio.file package provides a file change notification API, called the Watch Service API. The registered JVM has a thread dedicated to watching.AA: in java, the JDK semaphore is NOT a wrapper of the operation system semaphore so not usable for IPC
A: java Semaphore? Probably not an IPC construct in java.
Q2: have you used any optimized Map implementations outside the JDK?
Q3: to benchmark your various threading solutions how do you remove the random effects of GC and JIT compilation?
%%A: allocate enough memory to avoid GC. Turn off JIT to compile every code path. Perhaps give the JVM some warm-up period to complete the JIT compilation before we start the benchmark.
Parametrized Functor (class template) is a standard, recommended construct in c++, with no counterpart in java. C# delegae is conceptually simpler but internally more complex IMO, and represents a big upgrade from c++ functor. Better get some clarity with functor before comparing with delegates.
The most common functor is the simple stateless functor (like a simple lambda). The 2nd common category is the (stateful but) immutable functor. In all cases, the functor is designed for pass-by-value (not by ref or by pointer), cheap to copy, cheap to construct. I see many textbook code samples creating throwaway functor instances.
Example of the 2nd category – P127[[essentialC++]].
A) One mental block is using a simple functor Class as a template type param. This is different from java/c#
B) One mental block is a simple parametrized functor i.e. class template. C++ parametrized functor can take various type params, more “promiscuous” than c#/java.
C) A bigger mental block, combining A+B, is a functor parametrized with another functor Class as a template param. See P186[[EssentialC++]].
This is presented as a simple construct, with about 20 lines of code, but the more I look at it, the more strange it feels. I think this is somwehwat powerful but unpopular and unfamiliar to mainstream developers.
Functional programming in c++?
In java, we write a custom comparitor class rather than a comparitor class Template. We also have the simpler alternative of a Comparable interface, but that’s not very relevant in this discussion. Java 8 lambda — http://www.dreamsyssoft.com/java-8-lambda-tutorial/comparator-tutorial.php
I hope to find online articles to support each claim.
C# — anon (unicast) delegates. See [[c# in depth]]
java — anon nested classes. See [[mastering lambdas]]
c++ — functor class (template) or function pointer. See https://blog.feabhas.com/2014/03/demystifying-c-lambdas/ and http://www.cprogramming.com/c++11/c++11-lambda-closures.html
* in dotnet the plain lookup operation will throw exception if non-existent. I hit this frequently in my projects…
*** STL map silently adds an empty entry! For the justifications (crazy interviewers?), see http://stackoverflow.com/questions/4382656/why-is-stdmapoperator-so-counter-intuitive
*** java returns null http://stackoverflow.com/questions/5220619/return-from-hashmapstring-string-when-no-key
* basic Dictionary offers TryGet…()
TryAdd? Concurrent dict only, not the basic Dictionary.
* in dotnet, the plain Add() will throw exception if clash
*** STL map will silently ignore the insert() attempt, but operator can be used to insert or overwrite ???
TryRemove? No such thing. Using the plain Remove to remove a non-existent is no-throw.
Someone pointed out
“The whole reason you have a special Interface type-category in addition to abstract base classes in C#/Java is because C#/Java do not support multiple inheritance. C++ supports multiple inheritance, and so a special type isn’t needed. An abstract base class with only pure virtual methods is functionally equivalent to a C#/Java interface.”
The sample code shows no special ctor, though the dtor is public virtual but without “=0” (not pure virtual), so I assume an “interface” type in c++ can have a virtual dtor.