├── .github └── workflows │ └── test.yml ├── .gitignore ├── LICENSE ├── README.md ├── explanation ├── DoubleMinValue.md └── TypesAreHard.md ├── pom.xml └── src └── test └── java ├── DoubleMinValue.java ├── FinallyExitMethod.java ├── IntegersEquality.java ├── StringEquality.java ├── TypesAreHard.java └── WhereIsTheAnnotation.java /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Run tests 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | test: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v2 11 | - name: Set up JDK 16 12 | uses: actions/setup-java@v1 13 | with: 14 | java-version: 16 15 | - name: Run tests 16 | run: mvn --batch-mode --update-snapshots test -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### JetBrains template 2 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 3 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 4 | 5 | # IntelliJ 6 | .idea 7 | out/ 8 | 9 | ### Java template 10 | # Compiled class file 11 | *.class 12 | 13 | # Log file 14 | *.log 15 | 16 | # BlueJ files 17 | *.ctxt 18 | 19 | # Mobile Tools for Java (J2ME) 20 | .mtj.tmp/ 21 | 22 | # Package Files # 23 | *.jar 24 | *.war 25 | *.nar 26 | *.ear 27 | *.zip 28 | *.tar.gz 29 | *.rar 30 | 31 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 32 | hs_err_pid* 33 | 34 | ### Maven template 35 | target/ 36 | pom.xml.tag 37 | pom.xml.releaseBackup 38 | pom.xml.versionsBackup 39 | pom.xml.next 40 | release.properties 41 | dependency-reduced-pom.xml 42 | buildNumber.properties 43 | .mvn/timing.properties 44 | # https://github.com/takari/maven-wrapper#usage-without-binary-jar 45 | .mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Michał Kasprzyk 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Java xD 2 | ======= 3 | The best interview questions ever. 4 |
5 | I hope you get the irony. 6 |
7 | 8 | How to use this repo 9 | -------------------- 10 | All examples are written as JUnit tests. 11 | Open files in `src/test/java` and try to answer why tests pass. -------------------------------------------------------------------------------- /explanation/DoubleMinValue.md: -------------------------------------------------------------------------------- 1 | ``` 2 | System.out.println(Double.MIN_VALUE > 0); // true 3 | ``` 4 | 5 | According to the Javadoc, `Double.MIN_VALUE` is the smallest positive number possible to encode in a Double, 6 | not the smallest negative number. 7 | 8 | > A constant holding the smallest positive nonzero value of type double, 2-1074. 9 | > It is equal to the hexadecimal floating-point literal 0x0.0000000000001P-1022 and also equal to Double.longBitsToDouble(0x1L). -------------------------------------------------------------------------------- /explanation/TypesAreHard.md: -------------------------------------------------------------------------------- 1 | TypesAreHard 2 | ============ 3 | 4 | ``` 5 | final int a = 97; 6 | System.out.println(true ? a : 'c'); 7 | ``` 8 | 9 | > The type of a conditional expression is determined as follows: 10 | > * If the second and third operands have the same type (which may be the null type), then that is the type of the conditional expression. 11 | > * If one of the second and third operands is of primitive type T, and the type of the other is the result of applying boxing conversion (§5.1.7) to T, then the type of the conditional expression is T. 12 | > * If one of the second and third operands is of the null type and the type of the other is a reference type, then the type of the conditional expression is that reference type. 13 | > * Otherwise, if the second and third operands have types that are convertible (§5.1.8) to numeric types, then there are several cases: 14 | > * If one of the operands is of type byte or Byte and the other is of type short or Short, then the type of the conditional expression is short. 15 | > * If one of the operands is of type T where T is byte, short, or char, and the other operand is a constant expression (§15.28) of type int whose value is representable in type T, then the type of the conditional expression is T. 16 | > * If one of the operands is of type T, where T is Byte, Short, or Character, and the other operand is a constant expression (§15.28) of type int whose value is representable in the type U which is the result of applying unboxing conversion to T, then the type of the conditional expression is U. 17 | > * Otherwise, binary numeric promotion (§5.6.2) is applied to the operand types, and the type of the conditional expression is the promoted type of the second and third operands. 18 | > _Note that binary numeric promotion performs value set conversion (§5.1.13) and may perform unboxing conversion (§5.1.8)._ 19 | 20 | _The Java™ Language Specification, Java SE 7 Edition_ 21 | 22 | A third operand is a `char`, and a second operand is "constant expression of type `int`", so the whole expression is evaluated into `char`. 23 | 24 | *** 25 | 26 | ``` 27 | int b = 97; 28 | System.out.println(true ? b : 'c'); 29 | ``` 30 | 31 | > When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value that is convertible to a numeric type, the following rules apply, in order: 32 | > * If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8). 33 | > * Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules: 34 | > * If either operand is of type double, the other is converted to double. 35 | > * Otherwise, if either operand is of type float, the other is converted to float. 36 | > * Otherwise, if either operand is of type long, the other is converted to long. 37 | > * Otherwise, both operands are converted to type int. 38 | 39 | _The Java™ Language Specification, Java SE 7 Edition_ 40 | 41 | "Binary numeric promotion" is performed, and the whole expression evaluates into `int` -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | pl.north93.javaxd 6 | JavaXD 7 | 1.0-SNAPSHOT 8 | 9 | 10 | 16 11 | 16 12 | UTF-8 13 | 14 | 15 | 16 | 17 | 18 | org.junit 19 | junit-bom 20 | 5.7.0 21 | pom 22 | import 23 | 24 | 25 | 26 | 27 | 28 | 29 | org.junit.jupiter 30 | junit-jupiter 31 | test 32 | 33 | 34 | 35 | 36 | 37 | 38 | org.apache.maven.plugins 39 | maven-surefire-plugin 40 | 2.22.2 41 | 42 | 43 | **/*.java 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/test/java/DoubleMinValue.java: -------------------------------------------------------------------------------- 1 | import static org.junit.jupiter.api.Assertions.assertTrue; 2 | 3 | 4 | import org.junit.jupiter.api.Test; 5 | 6 | public class DoubleMinValue 7 | { 8 | @Test 9 | public void doubleMinValue() 10 | { 11 | assertTrue(Double.MIN_VALUE > 0); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/test/java/FinallyExitMethod.java: -------------------------------------------------------------------------------- 1 | import static org.junit.jupiter.api.Assertions.assertTrue; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | public class FinallyExitMethod 6 | { 7 | 8 | @Test 9 | public void test() 10 | { 11 | assertTrue(finallyExitMethod() == 2); 12 | } 13 | 14 | private static int finallyExitMethod() 15 | { 16 | try 17 | { 18 | throw new Exception(); 19 | } 20 | catch (final Exception exception) 21 | { 22 | System.out.println("catch"); 23 | return printAndGetNumber(1); 24 | } 25 | finally 26 | { 27 | System.out.println("finally"); 28 | return printAndGetNumber(2); 29 | } 30 | } 31 | 32 | private static int printAndGetNumber(int number) 33 | { 34 | System.out.println("number: " + number); 35 | return number; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/IntegersEquality.java: -------------------------------------------------------------------------------- 1 | import static org.junit.jupiter.api.Assertions.assertFalse; 2 | import static org.junit.jupiter.api.Assertions.assertTrue; 3 | 4 | 5 | import org.junit.jupiter.api.Test; 6 | 7 | public class IntegersEquality 8 | { 9 | @Test 10 | public void twoPrimitives100() 11 | { 12 | int i1 = 100; 13 | int i2 = 100; 14 | assertTrue(i1 == i2); 15 | } 16 | 17 | @Test 18 | public void twoObjects100() 19 | { 20 | Integer i1 = 100; 21 | Integer i2 = 100; 22 | assertTrue(i1 == i2); 23 | } 24 | 25 | @Test 26 | public void twoPrimitives1000() 27 | { 28 | int i1 = 1000; 29 | int i2 = 1000; 30 | assertTrue(i1 == i2); 31 | } 32 | 33 | @Test 34 | public void twoObjects1000() 35 | { 36 | Integer i1 = 1000; 37 | Integer i2 = 1000; 38 | assertFalse(i1 == i2); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/StringEquality.java: -------------------------------------------------------------------------------- 1 | import static org.junit.jupiter.api.Assertions.assertFalse; 2 | import static org.junit.jupiter.api.Assertions.assertTrue; 3 | 4 | 5 | import org.junit.jupiter.api.Test; 6 | 7 | public class StringEquality 8 | { 9 | @Test 10 | public void stringEquality() 11 | { 12 | final String s1 = "test"; 13 | final String s2 = new String("test"); 14 | 15 | assertTrue(s1 == "test"); 16 | assertFalse(s2 == "test"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/java/TypesAreHard.java: -------------------------------------------------------------------------------- 1 | import java.io.ByteArrayOutputStream; 2 | import java.io.PrintStream; 3 | import java.nio.charset.StandardCharsets; 4 | import java.util.function.Consumer; 5 | 6 | import org.junit.jupiter.api.Assertions; 7 | import org.junit.jupiter.api.Test; 8 | 9 | public class TypesAreHard 10 | { 11 | @Test 12 | public void finalLocalVariable() 13 | { 14 | assertEquals("a", out -> 15 | { 16 | final int a = 97; 17 | out.print(true ? a : 'c'); 18 | }); 19 | } 20 | 21 | @Test 22 | public void nonFinalLocalVariable() 23 | { 24 | assertEquals("97", out -> 25 | { 26 | int b = 97; 27 | out.print(true ? b : 'c'); 28 | }); 29 | } 30 | 31 | // this method provides PrintStream to test, so we don't have to use System.out 32 | private void assertEquals(final String expected, final Consumer testBody) 33 | { 34 | final ByteArrayOutputStream outBuffer = new ByteArrayOutputStream(); 35 | testBody.accept(new PrintStream(outBuffer)); 36 | 37 | Assertions.assertEquals(expected, outBuffer.toString(StandardCharsets.UTF_8)); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/test/java/WhereIsTheAnnotation.java: -------------------------------------------------------------------------------- 1 | import static org.junit.jupiter.api.Assertions.assertFalse; 2 | import static org.junit.jupiter.api.Assertions.assertTrue; 3 | 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | import org.junit.jupiter.api.Test; 11 | 12 | public class WhereIsTheAnnotation 13 | { 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Target({ElementType.TYPE_USE, ElementType.PARAMETER}) 16 | @interface Lel 17 | { 18 | } 19 | 20 | public static void a(@Lel String args) {} 21 | public static void b(@Lel String[] args) {} 22 | 23 | @Test 24 | public void whereIsTheAnnotation() throws Exception 25 | { 26 | final Class clazz = WhereIsTheAnnotation.class; 27 | 28 | assertTrue(clazz.getDeclaredMethod("a", String.class) 29 | .getAnnotatedParameterTypes()[0].isAnnotationPresent(Lel.class)); 30 | 31 | assertFalse(clazz.getDeclaredMethod("b", String[].class) 32 | .getAnnotatedParameterTypes()[0].isAnnotationPresent(Lel.class)); 33 | } 34 | } 35 | --------------------------------------------------------------------------------