├── .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 |
--------------------------------------------------------------------------------