Cet article est l'article du 22ème jour du Calendrier de l'Avent étendu Fujitsu 2016. Veuillez noter que le contenu suivant n'est pas représentatif de la société / organisation à laquelle vous appartenez et constitue ma propre opinion.
Vous devez obtenir au moins une qualification (par exemple, examen d’ingénieur en technologies de l’information appliquée) spécifiée en rejoignant la société en tant que nouveau diplômé, et le titre Java SE 8 Programmer II Certification Oracle qui peut être obtenue en passant /pls/web_prod-plq-dad/db_pages.getpage?page_id=5001&get_params=p_exam_id:1Z0-809&p_org_id=70) Qualifié ** Oracle Certified Java Programmer, Gold SE 8 ** (ci-après dénommé Gold), et un rang en dessous [Java SE 8 Programmer I](http://education.oracle.com/pls/web_prod- Ils incluent également ** Oracle Certified Java Programmer, Silver SE 8 ** (ci-après dénommé Silver), qui peut être obtenu en passant plq-dad / db_pages.getpage ?[id = 5001 & get_params = p_exam_id: 1Z0-808 & p_org_id = 70). Je vais. Un aperçu des certifications Java 8 certifiées par Oracle est également disponible sur cette URL, mais également dans le tableau ci-dessous. J'ai essayé de le résumer à ma manière.
Nom | Qualifications préalables | Examen de qualification | cible |
---|---|---|---|
Java Programmer, Bronze SE 7/8 | Aucun | Java SE 7 / 8 Bronze | Pour les débutants qui peuvent comprendre de la grammaire de base telle que l'instruction if à l'orientation objet. |
Java Programmer, Silver SE 8 | Aucun | Java SE 8 Programmer I | Des classes comme le polymorphisme et le downcast(interface)Relations etString 、ArrayList Classe, expression lambda de Java8, date/Pour les développeurs qui comprennent les spécifications de base des méthodes standard telles que l'utilisation de base de l'API time. |
Java Programmer, Gold SE 8 | Java Programmer, Silver SE 8 | Java SE 8 Programmer II | Conception d'objets immuables, génériques, classes internes, etc., Java I/O(NIO.Y compris 2 systèmes), Cadre d'exécution, etc. Pour les experts qui peuvent comprendre la grammaire et la conception détaillées. |
Comme ci-dessus | Java Programmer, Gold SE 7 | Upgrade to Java SE 8 Programmer | Comme ci-dessus |
Comme ci-dessus | Java Programmer(SE 6 ou antérieur) | Upgrade to Java SE 8 OCP ( Java SE 6 and all prior versions) | Comme ci-dessus |
Quand j'étais étudiant, j'avais l'expérience de développer moi-même des applications Android simples en utilisant Java, et je gère souvent Java dans mon travail, donc je voulais atteindre la norme de qualification pour les nouveaux arrivants dès le début. Par conséquent, je souhaitais acquérir de l'argent, qui est une condition préalable à l'or. En conséquence, j'ai passé Silver relativement facilement au début de septembre de cette année, ce qui n'était pas suffisant pour m'améliorer, donc je veux étudier des connaissances plus avancées de la grammaire Java et récemment (Java8, Java9) la conception d'interface Java Afin d'appréhender la tendance, j'ai décidé de viser l'or, qui est plus difficile que l'argent.
URL officielle d'Oracle Il est décrit avec des notes sur. Dans cette chronique, je citerai les bulletins des sujets qui y figurent et les expliquerai. J'espère que ceux qui passeront l'examen Gold seront invités de cette façon, et ceux qui ne passeront pas l'examen auront le sentiment que la dernière API officielle Java est comme ça. De plus, l'or ne peut pas être acquis sans acquérir de l'argent, nous allons donc bien entendu partir du principe que vous comprenez toute la gamme de questions en argent comme décrit dans le tableau ci-dessus.
- Implémenter l'encapsulation
- Implémenter l'héritage, y compris les modificateurs d'accès et les compositions
- Implémenter le polymorphisme
- Remplacer les méthodes
hashCode
, ʻequalset
toString` de la classe d'objets- Créer et utiliser des classes singleton et immuables
- Utilisez le mot-clé
static
dans les blocs d'initialisation, les variables, les méthodes et les classes- Ecrire du code qui utilise des classes et des méthodes abstraites
- Ecrire du code utilisant le mot-clé
final
- Créez des classes internes telles que des classes internes statiques, des classes locales, des classes imbriquées, des classes internes anonymes, etc.
- Utilisez des types d'énumération, y compris ceux dont les méthodes et les constructeurs sont dans des types d'énumération.
- Ecrire du code qui déclare, implémente et étend les interfaces. Utilisez l'annotation
@ Override
- Créer et utiliser des expressions lambda
Il y a beaucoup de chevauchement avec Silver, mais la création d'une classe anonyme est fortement liée à l'interface fonctionnelle et à l'API de flux qui apparaîtront plus tard, vous devez donc bien la comprendre. En outre, je me souviens avoir eu des problèmes tels que la façon de concevoir une classe existante dans une classe immuable. De plus, dans le type d'énumération (classe ʻEnum`), le constructeur doit recevoir un modificateur privé, mais il est en fait public, donc la bonne réponse est de sélectionner "Erreur de compilation sur la ligne XX". Il y avait également un problème selon lequel vous ne remarqueriez pas la bonne réponse à moins de lire les détails tels que. Java 8 vous permet de définir des méthodes statiques par défaut et concrètes dans votre interface. Alors
interface A {
void foo();
}
interface B extends A {
@Override
default void foo() {}
}
interface C extends A {
@Override
default void foo() {}
}
class D implements B, C {}
Vous pouvez hériter de diamants comme celui-ci. Naturellement, la ligne class D implémente B, C {}
entraînera une erreur de compilation. Aussi,
interface E {
default void x(String s) {}
static void y(String s) {}
void z(String s);
}
Une définition d'interface comme ʻE e = s-> System.out.println (s); est parce que c'est une interface fonctionnelle (la méthode
default et la méthode concrète
statique` sont ignorées). Vous pouvez écrire des expressions lambda. Je pense qu'il y avait un problème basé sur ce contenu même dans l'examen proprement dit.
À propos, les spécifications de compilation des classes locales et des classes anonymes ont changé entre Java 7 et Java 8.
class Outer {
private static String a = "A";
public static void main(String[] args) {
Outer q = new Outer();
q.foo("B");
}
public static void foo(String b) { //Affectation implicite du modificateur final à la variable b à partir de Java 8
String c = "C"; //Affectation implicite du modificateur final à la variable c à partir de Java 8
Inner inner = new Inner(){
@Override
public void bar(String d) {
System.out.println(a + b + c + d);
}
};
//b = "BB";
//c = "CC";
inner.bar("D");
}
interface Inner {
public void bar(String d);
}
}
Lorsque je compile avec le compilateur de la version 1.7, j'obtiens une erreur de compilation indiquant que les variables locales b
et c
doivent être déclarées final
, mais dans la version 1.8, la compilation réussit. C'est parce que Java 8 est devenu une spécification pour ajouter implicitement le modificateur "final" aux variables locales "b" et "c" au moment de la compilation, et que l'arrière-plan est l'introduction de l'expression lambda décrite plus loin. Je pense que c'était parce que je voulais que cela ait l'air naturel comme si je passais une classe anonyme en tant que fonction. Cependant, il n'est pas normal de décommenter «b =« BB »» et «c =« CC »» parce que les variables locales «b» et «c» reçoivent implicitement le modificateur «final». Une erreur de compilation se produira indépendamment du fait que la version de javac
soit 1.7 ou 1.8. À propos, lorsque le code source ci-dessus est compilé et exécuté, ʻABCD` est sorti.
- Créer et utiliser des classes génériques
- Créer et utiliser les objets ʻArrayList
,
TreeSet,
TreeMapet ʻArrayDeque
- Utiliser les interfaces
java.util.Comparator
etjava.lang.Comparable
En Java, les tableaux sont covariants, mais je me souviens avoir eu des problèmes avec les génériques immuables. En d'autres termes
Number[] array = new Integer[3];
Compilera, mais
ArrayList<Number> list = new ArrayList<Integer>(3);
Cela entraînera une erreur de compilation. Il y avait aussi un joker et un joker de limite. Par exemple
ArrayList<?> list = new ArrayList<Integer>();
Compilera, mais
ArrayList<Integer> list = new ArrayList<?>();
ArrayList<?> list = new ArrayList<?>();
Cela entraînera une erreur de compilation sur les deux lignes. C'est parce que le côté droit de =
ne doit pas utiliser de caractères génériques. Aussi,
ArrayList<? extends Number> list = new ArrayList<Integer>();
Compilera, et d'ailleurs
List<? super Integer> list = new ArrayList<Number>();
Compilera également.
Il est recommandé de bien comprendre les spécifications des interfaces java.lang.Comparable
et java.util.Comparator
. À cet égard, la classe de clé que vous ajoutez à l'instance java.util.TreeMap
doit avoir une interface ʻimplements java.lang.Comparable
, mais si vous ne le faites pas,
implémente au moment de l'exécution
Une exception lava.lang.ClassCastException` est lancée (notez qu'il ne s'agit pas d'une erreur de compilation).
À propos, aucune question relative à «Deque» n'a été posée. C'est peut-être juste un caprice.
- Utilisez les interfaces intégrées incluses dans le package
java.util.function
, telles quePredicate
,Consumer
,Function
,Supplier
- Utiliser une interface fonctionnelle qui gère les types primitifs
- Utiliser une interface fonctionnelle avec deux arguments
- Ecrire du code utilisant l'interface 'UnaryOperator'
Puisqu'il s'agit d'une description nécessaire pour l'API de flux décrite plus tard, je pense que c'était le champ avec le deuxième plus grand nombre de questions **. N'oubliez pas les quatre noms d'interface suivants, que je nomme personnellement ** Four Tenno **, et leurs noms de méthodes abstraites. Si vous vous souvenez au moins de ces quatre, les interfaces avec Bi
telles que BiConsumer <T, U> ʻet les types primitifs (ʻint
, long
, double
, boolean
) Vous n'avez pas à vous souvenir des interfaces telles que DoublePredicate
et LongToDoubleFunction
qui sont spécialisées pour.
Nom de l'interface | Nom de la méthode abstraite | Remarques |
---|---|---|
Function<T, R> |
R apply(T t) |
Quatre TennoUn des |
Consumer<T> |
void accept(T t) |
Quatre TennoUn des |
Supplier<T> |
T get() |
Quatre TennoUn des |
Predicate<T> |
boolean test(T t) |
Quatre TennoUn seul d'entre eux, ce gars sera demandé en Argent |
BiFunction<T, U, R> |
R apply(T t, U u) |
- |
UnaryOperator<T> |
T apply(T t) |
Function<T, T> Sous-interface de |
BinaryOperator<T> |
T apply(T t1, T t2) |
BiFunction<T, T, T> Sous-interface de |
IntFunction<R> |
R apply(int value) |
- |
ToDoubleFunction<T> |
double applyAsDouble(T t) |
double apply(T t) n'est pas |
IntToDoubleFunction |
double applyAsDouble(int value) |
double apply(T t) n'est pas |
IntConsumer<T> |
void accept(int value) |
- |
IntSupplier<T> |
int getAsInt() |
int get() n'est pas |
IntPredicate<T> |
boolean test(int value) |
- |
java.util.function
est [Official API Collection](https://docs.oracle.com/javase/jp/8/docs/api /java/util/function/package-summary.html).Plus important que cette connaissance, il est naturel que l'interface fonctionnelle puisse être associée à l'expression lambda (ou voir la méthode décrite plus loin), mais inversement, l'expression lambda peut être associée à quelle interface fonctionnelle a été utilisée. Est d'être. Par exemple, s'il s'agit d'une interface Supplier <String>
, vous pouvez renvoyer le type String
à partir du type void
.
Supplier<String> a = () -> "HelloWorld!"
Être capable de définir des expressions lambda comme
b = s -> s.concat("World!")
Regardez simplement l'expression lambda dans et associez le type de variable de la variable b
avec Function <String, String> ʻou
UnaryOperator . Et il est également important de pouvoir associer comment les méthodes abstraites devraient être utilisées pour appliquer réellement une interface fonctionnelle. Si vous souhaitez utiliser l'expression lambda dans l'exemple précédent pour affecter la chaîne de
HelloWorld!À la variable de type
String`` str, alors
String str = a.get (); ou
String str = b. Vous pouvez écrire apply ("Hello"); `.
Poursuivre l'application des connaissances ci-dessus
DoubleFunction<BiConsumer<Integer, Double>> func = x -> (y, z) -> System.out.println(x / z + y);
Il y avait aussi une expression lambda imbriquée comme. Si vous voulez afficher le résultat du calcul de 5.0 / 2.0 + 3 = 5.5
, écrivez func.apply (5.0) .accept (3, 2.0);
.
- Décrire les interfaces de flux et les pipelines
- Utiliser des expressions lambda pour filtrer les collections
- Utiliser des références de méthode avec des flux
- Extraire les données d'un objet en utilisant les méthodes
peek ()
etmap ()
, y compris la version de base de la méthodemap ()
- Rechercher des données en utilisant des méthodes de recherche telles que
findFirst
,findAny
, ʻanyMatch, ʻallMatch
,noneMatch
- ʻUtiliser la classe facultative`
- Ecrire du code qui utilise les données du flux et les méthodes de calcul
- Trier les collections à l'aide de l'API de flux
- Utilisez la méthode
collect ()
pour enregistrer les résultats dans une collection. Grouper / partitionner les données en utilisant la classeCollectors
- Utilisez la méthode
flatMap ()
En partie parce qu'il s'agit d'une fonctionnalité de Java8 **, le nombre de questions est très important et je pense qu'environ 50% des problèmes étaient en fait liés à l'API de flux **. Je pense que toutes les colonnes que j'ai écrites dans les bulletins ci-dessus sont importantes.
Stream utilise l'interface Stream <T>
et l'interface ʻIntStream` spécialisée pour son type primitif, et fonctionne selon le flux suivant.
Cependant, veuillez noter les points suivants. Ce contenu doit également être rappelé en relation avec l'examen proprement dit.
Le plus grand avantage de l'API de flux est que vous pouvez coder 1 à 3 actions sur une seule ligne **, ce qui devrait améliorer la lisibilité du code et trouver immédiatement les bogues. Par exemple, supposons que vous souhaitiez écrire du code Java qui génère tous les fichiers / répertoires frères et sœurs à partir du répertoire actuel en utilisant NIO.2 ajouté à partir de Java 7, qui sera décrit plus tard. A cette époque, dans la version javac 1.7, il était nécessaire de coder un grand nombre de lignes en surchargeant les quatre méthodes abstraites de l'interface FileVisitor
comme indiqué ci-dessous.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
class Search7 {
public static void main(String[] srgs) {
try {
Files.walkFileTree(
Paths.get("./"),
new FileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
System.out.println(dir);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
System.out.println(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) {
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
return FileVisitResult.CONTINUE;
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}
En revanche, la version 1.8 ne nécessite qu'un ** très petit nombre de lignes ** comme indiqué ci-dessous.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
class Search8 {
public static void main(String[] srgs) {
try {
Files.walk(Paths.get("./")).forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Notez que System.out :: println
dans le code Java 8 est une notation ajoutée à partir de Java 8 et est appelée une référence de méthode. Cette notation a la même signification que l'expression lambda (Path path) -> System.out.println (path)
et peut être écrite encore plus courte que l'expression lambda. Veuillez noter que dans le test réel, il y avait pas mal de questions liées à l'interface fonctionnelle. Par exemple
ToDoubleFunction<String> ds = str -> Double.parseDouble(str);
Peut être réécrit comme suit.
ToDoublefunction<String> = Double::parseDouble;
D'après la description de l'expression lambda, il est bon que vous puissiez imaginer fermement dans votre esprit comment décrire la référence de la méthode et vice versa. Maintenant, revenons à l'explication de l'API stream, mais en guise de préparation au test, je vais l'expliquer selon 1 à 3 ci-dessus. Tout d'abord, jetez un œil au code à l'aide de l'API de flux ci-dessous.
Stream<String> stream1 = Arrays.asList("a", "bb", "ccc", "dddd").stream(); //Génération de flux
Stream<Integer> stream2 = stream1.map(str -> str.length()); //Opération intermédiaire partie 1
Stream<Integer> stream3 = stream2.filter(num -> num > 1); //Opération intermédiaire partie 2
Optional<Integer> result = stream3.max((num1, num2) -> num1 - num2); //Opération de terminaison
result.ifPresent(max -> System.out.println(max));
La fonction de génération de flux sur la première ligne est une instance du flux avec le paramètre de type T``stream1
parstream ()
nouvellement ajouté comme méthode par défaut
dans l'interfaceCollection <T>
de Java8. Est en cours de génération. Puisque la méthode ʻArrays.asList () retourne l'interface
List , qui est une sous-interface de l'interface
Collection , il y avait beaucoup de questions sur la création de flux en utilisant cette méthode. Dans l'opération intermédiaire «map ()» sur la deuxième ligne, une expression lambda est utilisée pour appeler le «length ()» de la classe «String» pour chacun des quatre éléments du type «String» contenus dans le «stream1». C'est précisé. En conséquence, les quatre éléments de type
String sont convertis en type ʻInteger
, qui est une classe wrapper de type ʻint, qui est la valeur de retour de
length (). Par conséquent, les valeurs détenues par "stream2" générées par "map ()" sont "1, 2, 3, 4". Notez que les types primitifs tels que ʻint
ne peuvent pas être décrits dans les génériques (une erreur de compilation se produira).
De plus, dans la deuxième opération intermédiaire «filter ()» sur la troisième ligne, les valeurs «1, 2, 3, 4» conservées par «stream2» sont filtrées pour réduire le nombre de valeurs conservées. Faire. La spécification de filtrage utilise également une expression lambda, qui dans cet exemple spécifie que seuls les éléments avec une valeur supérieure à 1 sont conservés et les autres sont ignorés. Par conséquent, les valeurs détenues par «stream3» sont «2, 3, 4».
Enfin, l'opération de terminaison «max ()» renvoie le maximum des valeurs «2», «3» et «4» détenues par «stream3». Cependant, lors de la recherche de la valeur maximale, la définition de maximum doit être spécifiée dans l'argument de max ()
. Cet argument est du type java.util.Comparator <T>
, et l'expression lambda (num1, num2) -> num1 --num2
représentant sa méthode abstraite ʻint compare (T num1, T num2)C'est précisé. Par cette spécification, la valeur maximale dans l'ordre naturel est calculée, le flux doit donc renvoyer «4». Une opération dans laquelle il a été confirmé que tous les éléments "2", "3" et "4" sont utilisés par l'opération de terminaison est appelée opération de réduction. Mais en regardant l'exemple ci-dessus,
max () retourne une instance
resultde type ʻOptional <T>
. La classe ʻOptional est une classe conteneur qui stocke le résultat de l'opération de terminaison de flux, et même si le résultat de l'opération de terminaison est
null, l'instance ʻOptional <T>
peut stocker null
. À ce moment-là, la plus grande caractéristique est que l'instance ʻOptional elle-même ne devient pas
nulle. Dans l'exemple ci-dessus, la dernière ligne appelle ʻifPresent (Consumer <? Super T> consumer)
de la classe ʻOptional , et si une valeur autre que
nullest stockée, elle est spécifiée par un argument. Si l'expression lambda de «consumer» est exécutée et que «null» est stocké, rien n'est fait. À partir de là, je pense que vous pouvez lire la conception qui ** élimine le risque de lancer
java.lang.NullPointerException` au moment de l'exécution **. D'après ce qui précède, puisque «4» est stocké dans «result», «4» est dans «max» de l'expression lambda «max-> System.out.println (max)» du type «Consumer
Optional<Integer> result =
Arrays.asList("a", "bb", "ccc", "dddd").stream() //Génération de flux
.map(String::length) //Opération intermédiaire partie 1
.filter(num -> num > 1) //Opération intermédiaire partie 2
.max((num1, num2) -> num1 - num2); //Opération de terminaison
result.ifPresent(System.out::println);
En plus de ce qui précède, il existe de nombreuses méthodes pour créer des flux, effectuer des opérations intermédiaires et effectuer des opérations de fin. Je vais l'omettre car il est difficile d'écrire des articles plus ~~, mais si vous voulez être fort dans l'API stream [Collection d'API officielle](https://docs.oracle.com/javase/jp/8/docs/api (/java/util/stream/Stream.html) Veuillez vous y référer. Dans l'examen proprement dit, j'estime que les 10 puces écrites en haut ont été attribuées.
- Utiliser les instructions try-catch et
throw
- Utiliser les clauses
catch
, multi-catch etfinally
Utiliser les ressources Autoclose avec l'instruction + try-with-resources- Créer des exceptions personnalisées et des ressources à fermeture automatique
- Tester des quantités immuables à l'aide d'assertions
Try-with-resource est une fonction pratique ajoutée à partir de Java 7, mais même dans l'examen SE8 Gold, il y avait pas mal de questions liées à JDBC, qui seront décrites plus tard. À ce stade, vous devez être prudent lorsque la méthode close ()
et la clause catch
remplacées sont exécutées.
class Main {
static class X implements AutoCloseable {
X() {
System.out.println("X : Constructor");
}
@Override
public void close() {
System.out.println("X : close()");
}
}
static class Y implements AutoCloseable {
Y() {
System.out.println("Y : Constructor");
}
@Override
public void close() {
System.out.println("Y : close()");
}
}
public static void main(String[] args) {
try (X x = new X();
Y y = new Y()) {
throw new Exception("Exception");
} catch (Exception e) {
System.out.println(e.getMessage());
} finally {
System.out.println("finally");
}
}
}
Lorsque le fichier source ci-dessus est compilé et exécuté
X : Constructor
Y : Constructor
Y : close()
X : close()
Exception
finally
Est sortie. Même si la variable «y» est définie après la variable «x», il est facile de se faire prendre sans connaître la spécification try-with-resource que la méthode «close ()» les appelle dans l'ordre inverse. De plus, il est facile de se méprendre sur le fait que ʻException est sortie avant
Y: close () car elle est dessinée dans l'ordre d'exécution de la clause
try → clause
catch→ clause
finally jusqu'à présent. .. Si vous vous souvenez de chacun des résultats ci-dessus, vous pouvez éviter d'être pris ou mal compris. De plus, lors de la substitution d'une méthode définie comme «throws Exception» ou «throws RuntimeException» dans une superclasse, il y a une question sur la façon de spécifier «throws» pour une méthode dans une sous-classe. fait. Étonnamment, il y avait deux questions liées aux assertions. Puisque vous avez seulement besoin d'apprendre la syntaxe du mot-clé ʻassert
, c'est une zone que vous souhaitez utiliser comme source de partition solide.
- Événements basés sur la date et sur l'heure, tels que l'utilisation de
LocalDate
,LocalTime
,LocalDateTime
, ʻInstant,
Periodet
Duration` pour combiner les dates et les heures en un seul objet. Créer et gérer- Manipuler la date et l'heure sur plusieurs fuseaux horaires. Gérer les modifications dues à l'heure d'été, telles que la mise en forme des valeurs de date et d'heure
- Utilisez ʻInstant
,
Period,
Durationet
TemporalUnit` pour définir, créer et gérer des événements basés sur la date et l'heure
C'est une API différente de l'API de flux nouvellement implémentée dans Java8, mais je pense que cela n'a pas été beaucoup demandé. Je ne pense pas avoir vu de problèmes avec la classe ZonedDateTime
, ʻInstant, le format date / heure et l'heure d'été qui incluent les informations de zone ... Cependant, comme ce fut le cas avec Silver, le problème d'accrochage utilisant le fait que la classe LocalXXX est une classe Immuable a également été posé dans Gold. De plus, «Période» est la date, «Durée» est l'intervalle de temps, et je pense qu'il suffit de se souvenir de la notation ISO 8601 de l'heure, donc si le seul but est d'acquérir des connaissances Or, Argent + α Je pense que cela suffit. De plus, la classe
Date et la classe
Calendar de l'ancien package
java.util` n'avaient pas de questions. Sera-t-il finalement «@ obsolète» à mesure que l'API date / heure ajoutée à SE 8 deviendra courante?
Java I/O、NIO.2
- Lire / écrire des données sur la console
- Utilisez
BufferedReader
,BufferedWriter
,File
,FileReader
,FileWriter
,FileInputStream
,FileOutputStream
, ʻObjectOutputStream, ʻObjectInputStream
etPrintWriter
dans le packagejava.io
Faire- Manipuler les chemins de fichiers et de répertoires à l'aide de l'interface
Path
- Utiliser l'API Stream avec NIO.2.
Malgré le fait qu'il existe de nombreux problèmes qui ne peuvent être résolus sans connaître les spécifications de la méthode, le nombre de questions de l'examen est étonnamment raisonnable. C'était le domaine dans lequel je n'étais pas bon à ce moment-là, alors j'ai en fait bougé la main en regardant la Official API Collection. Il est préférable de comprendre lors de la mise en œuvre de l'échantillon de test. Je pense que NIO.2 avait plus de questions que le flux d'entrée / sortie qui existait depuis longtemps que NIO.2 ajouté dans Java 7 (notez qu'il est complètement différent de l'API de flux ajoutée dans Java 8). Je vais.
Tout d'abord, l'ancien flux d'entrée / sortie, lorsqu'une instance BufferedReader
est créée pour un fichier donné,read ()
,readLine ()
,mark () à partir de la chaîne de caractères écrite dans le fichier. Il y avait en fait un problème avec la façon dont il était sorti en utilisant
,reset ()
, et skip ()
. Voici un bref résumé des différences entre read ()
et readLine ()
dans le tableau ci-dessous.
Nom de la méthode | Unité de lecture | Type de retour | À la fin du fichier |
---|---|---|---|
read() |
Un personnage | int (Ordinaire,char Cast explicitement pour taper sur un caractère) |
-1 rends le |
readLine() |
1 ligne | String (Le code de saut de ligne est automatiquement détecté et n'est pas inclus dans la valeur de retour.) |
null rends le |
Ici, BufferedReader
déclare l'interface Reader
ʻimplements et déclare
mark (),
reset (), etc. dans cette interface, mais toutes les classes d'implémentation de
Readersupportent les opérations. Pas toujours. Les exécuter avec une classe d'implémentation
Reader non prise en charge lèvera une
java.io.IOExceptionau moment de l'exécution. Ce statut de prise en charge peut être déterminé par la valeur de retour (type
booléen) de
markSupported (). Je ne me souviens pas du statut de la question des flux d'entrée / sortie autres que
BufferReader, mais je pense qu'au moins l'interface
java.io.Serializable et ʻObjectOutputStream
n'ont pas été posées. De plus, pour les relations d'entrée / sortie de la console, vous pouvez utiliser la variable System.in
du type ʻInputStream et la variable
System.out du type ʻOutputStream
, mais lajava.io.Console ajoutée depuis Java6 Vous pouvez également utiliser la classe
. Je pense que les points de cette classe sont les deux suivants.
Console
ne peut pas être initialisée en utilisant new
, elle est initialisée en substituant la valeur de retour deSystem.console ()
readline ()
, qui lit une ligne de la console, renvoie le type String
, tandis que readPassword ()
, qui le cache sur la console et lit une ligne, renvoie le typechar []
.Je pense que le NIO.2 restant est assez important. NIO.2 est stocké dans le package suivant java.nio
, et implémente une fonction qui peut manipuler les informations de fichier / répertoire qui ne peuvent pas être réalisées par les flux d'entrée / sortie. Dans le test réel, seule la méthode «statique» qui les opère est fournie. ... option) ʻest donné un par un, et il est nécessaire de faire attention aux résultats de l'exécution tels que LinkOption.NOFOLLOW_LINKS
et StandardCopyOption.REPLACE_EXISTING
qui peuvent spécifier des options comme arguments de longueur variable après le troisième argument. .. De plus, il existe des méthodes «readAllLines (chemin de chemin)» et «lines (chemin de chemin)» qui peuvent lire toutes les phrases du fichier ligne par ligne. Le tableau ci-dessous résume brièvement les différences entre eux.
Nom de la méthode | Type de retour | Version introduite |
---|---|---|
static readAllLines(Path path) throws IOException |
List<String> |
Java7 |
static lines(Path path) throws IOException |
Stream<String> |
Java8 |
Par ailleurs, l'interface Path
est spécifiée dans l'argument des méthodes de ces classes Files
. Il y avait quelques questions sur cette interface Path
seule. Bien sûr, il n'y a pas de constructeur dans l'interface Path
, et les instances peuvent être créées des deux manières suivantes.
get (String first, String ... more)
de la classe Paths
, qui est une classe d'usine (rappelez-vous juste ceci)getPath (String first, String ... more)
dans la classe d'implémentation de l'interface FileSystem
Notez que le chemin absolu / relatif spécifié dans l'argument d'interface Path
ne représente pas le 0ème répertoire racine, mais le répertoire / fichier le plus proche du répertoire racine. Par exemple
Path path = Paths.get("/usr/bin/java");
System.out.println(path.getName(0));
System.out.println(path.subpath(1, 3));
Produira la sortie suivante.
usr
bin/java
De plus, vous devez faire attention à la différence de comportement lorsque resolution ()
et normalize ()
sont exécutés pour l'objet Path
avec un chemin relatif et un chemin absolu.
- Créez un thread de travail en utilisant
Runnable
etCallable
. ʻExécuter des tâches simultanément avec ExecutorService`- Identifier les problèmes potentiels de threading tels que l'impasse, la stabilisation, le maintien en vie et les conditions de conflit
- Utilisez les mots-clés
synchronized
et le packagejava.util.concurrent.atomic
pour contrôler l'ordre d'exécution des threads- Utiliser les collections et classes
java.util.concurrent
, telles queCyclicBarrier
etCopyOnWriteArrayList
- Utiliser le cadre parallèle Fork / Join
- Utilisez des flux parallèles pour la réduction, la décomposition, le processus de fusion, le pipeline, les performances, etc.
Tout d'abord, apprenons l'utilisation de base du traitement parallèle à l'aide de threads en utilisant la classe Thread
et l'interface Runnable
, et l'utilisation de base du traitement exclusif et du traitement synchrone. Pour un traitement exclusif, spécifiez le modificateur «synchronized» sur la méthode ou le bloc, et pour le traitement synchrone, utilisez «java.util.concurrent.CyclicBarrier». Notez que l'interface Runnable
est une interface fonctionnelle avec une méthode abstraite,run ()
, donc l'attribution d'une expression lambda est possible.
Je pense qu'il y avait environ deux questions dans le cadre d'Executator, mais je ne pense pas que vous puissiez comprendre le mouvement sans le savoir. Le framework Execurator introduit le concept d'un pool de threads qui génère plusieurs threads à la fois pendant l'instanciation et les stocke jusqu'à ce qu'ils soient utilisés. De plus, il implémente la fonction de planification d'exécution de chaque thread et démontre d'excellentes performances avec une excellente réutilisabilité des threads. En tant que préparation de test, il est nécessaire de comprendre le comportement de ʻExecutor Service. Voir le code ci-dessous pour un exemple d'utilisation de ʻExecutorService
.
Runnable r = new Runnable() {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("Runnable : " + i);
}
}
};
Callable<Integer> c = new Callable<Integer>() {
@Override
public Integer call() {
int i = 0;
for (; i < 5; i++) {
System.out.println("Callable : " + i);
}
return i;
}
};
ExecutorService es = null;
try {
es = Executors.newFixedThreadPool(3);
es.execute(r);
Future<?> f1 = es.submit(r);
Future<Integer> f2 = es.submit(c);
System.out.println(f1.get() + " : " + f2.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} finally {
es.shutdown();
}
ʻExecutors.newFixedThreadPool (3) crée une instance ʻExecutorService
ʻesqui représente un pool de threads avec un nombre fixe de 3 threads. Exécutez les tâches prédéfinies
Runnable sur cette instance avec ʻexecute ()
en utilisant l'un des trois threads. Les tâches peuvent également utiliser l'interface Callable <T>
au lieu de l'interface Runnable
, et les différences sont indiquées dans le tableau ci-dessous.
Nom de l'interface fonctionnelle | Méthode abstraite | Type de retour | vérifié Jetabilité d'exception |
---|---|---|---|
java.lang.Runnable |
run() |
vous devezvoid À |
impossible |
java.util.concurrent.Callable |
call() |
Paramètres de typeT Spécifié par |
throws Possible par spécification |
À ce stade, la fonction d'exécution de thread a l'un des quatre modèles suivants.
Nom de la méthode | Type de retour | Après avoir exécuté la tâcheFuture Valeur stockée dans |
---|---|---|
execute(Runnable task) |
void |
- |
submit(Runnable task) |
Future<?> |
null |
submit(Runnable task, T t) |
Future<T> |
t |
submit(Callable<T> task) |
Future<T> |
Callable<T> deT call() Valeur renvoyée par |
Future <T>
est une interface qui représente le résultat de l'exécution de la tâche, et vous devez vous rappeler le mécanisme selon lequel le thread attend jusqu'à ce que la tâche soit terminée par get ()
, et quand elle est terminée, le résultat de type T
est retourné tel quel. est. De ce qui précède, dans la ligne System.out.println (f1.get () +": "+ f2.get ());
null : 5
Est sortie. Enfin, lancez shutdown ()
pour arrêter ʻeset arrêter d'accepter de nouvelles tâches. Si vous n'appelez pas la méthode
shutdown (), le programme ne se terminera pas et continuera d'attendre une fois que tous les threads auront terminé le traitement. Je pense que l'image sortira simplement en se souvenant de la série d'opérations décrite ci-dessus. En plus de
CyclicBarrier, le package
java.util.concurrent implémente les interfaces thread-safe
List,
Map,
Set et
Queue`. Par exemple, consultez le code ci-dessous.
List<Integer> list = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4));
new Thread(){
@Override
public void run() {
for (Integer num : list) {
System.out.println("Thread : " + num);
}
}
}.start();
for (Integer num : list) {
System.out.println("Remove : " + num);
list.remove(num);
}
À première vue, le résultat semble changer à chaque exécution, mais en réalité, l'exception java.util.ConcurrentModificationException
est toujours lancée.
Exception in thread "Thread-0" Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at Main.main(Main.java:18)
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at Main$1.run(Main.java:12)
L'instruction d'extension Java for
appelle l'itérateur (= interface ʻIterator) implémenté dans la collection, mais ajoute des éléments de la collection non thread-safe tels que ʻArrayList
pendant le traitement itératif par cet itérateur. / Ceci est dû au fait que la spécification lève une exception java.util.ConcurrentModificationException
lorsqu'elle est supprimée. Je pense personnellement que c'est l'une des douleurs que je ne peux pas comprendre tant que je ne l'ai pas réellement mise en œuvre. Comme solution de contournement
List<Integer> list = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4));
Vous pouvez remplacer la ligne par la classe thread-safe java.util.concurrent.CopyOnWriteArrayList
comme indiqué ci-dessous.
List<Integer> list = new CopyOnWriteArrayList<>(Arrays.asList(0, 1, 2, 3, 4));
Il existe de nombreuses collections thread-safe en plus de CopyOnWriteArrayList
, mais pour l'instant résumé des classes fourni dans le package java.util.concurrent
Il vous suffit de jeter un coup d'œil rapide à (/jp/8/docs/api/java/util/concurrent/package-summary.html) pour déterminer quelles collections sont thread-safe.
Je me souviens qu'une question a été donnée à partir de chacun des frameworks atomic et Fork / Join. Pour atomic (= une série d'opérations indivisibles), la classe ʻAtomicInteger, qui définit une méthode qui effectue un traitement exclusif tel que le modificateur
synchronized sur les types primitifs tels que ʻint
, a été définie. Le framework Fork / Join n'a besoin que d'une compréhension approximative de la façon d'écrire le code global.
- Décrit les interfaces de base de l'API JDBC, y compris les interfaces «Driver», «Connection», «Statement» et «ResultSet» et leur relation avec l'implémentation du fournisseur.
- Identifier les composants nécessaires pour se connecter à la base de données à l'aide de la classe
DriverManager
, comme l'URL JDBC- Émettre des requêtes et lire les résultats de la base de données, y compris la création d'instructions, la récupération des ensembles de résultats, la répétition des résultats et la fermeture correcte des ensembles de résultats / instructions / connexions
JDBC doit principalement comprendre les deux points de vue suivants.
Dans le test réel, je me souviens que seulement environ 4 questions sur la façon d'utiliser la dernière API JDBC ont été posées, mais la connaissance de la première peut également être posée sous forme de question à choix multiples, il est donc nécessaire de comprendre le fonctionnement du système. pense. Désormais, seul ce dernier sera expliqué dans cet article. Il est très important de comprendre comment utiliser l'API JDBC à partir du flux de codage de base qui peut connecter / faire fonctionner la base de données dans l'ordre suivant.
Connection
générée par DriverManager.getConnection ()
Statement
générée par` Connection.createStatement () ʻin 1.ResultSet
générée par`Statement.executeQuery () ʻin 2.Ces trois objets peuvent être essayés avec une ressource appliquée et close ()
exécutée. Sachez donc que l'exécution de n'importe quelle méthode sur chaque objet fermé lèvera une SQLException
. Par exemple, pour une «finale statique privée» donnée, la variable «URL» qui représente une URL pouvant se connecter à un JDBC de type «String»
try (Connection cn = DriverManager.getConnection(URL);
Statement st = cn.createStatement()) {
ResultSet rs1 = st.executeQuery("SELECT id FROM shop");
ResultSet rs2 = st.executeQuery("SELECT name FROM shop");
if (rs1.next()) {
System.out.println(rs1.getInt(1));
}
if (rs2.next()) {
System.out.println(rs2.getString(1));
}
} catch (SQLException e) {
e.pribntStackTrace();
}
Si vous réutilisez la variable de type Statement`` st
comme dans, rs1
sera fermé au point où rs2
est généré. Par conséquent, rs1.next ()
lance SQLException
.
Notez que «ResultSet» se soucie de l'index de ligne / colonne commençant à 1 et non à 0. Par conséquent, pour une variable rs
de type ResultSet
,rs.getString (0)
etc. sera compilée, mais SQLException
sera lancée au moment de l'exécution. Cependant, rs.absolute (0)
ne lance pas une SQLException
au moment de l'exécution, même pour les erreurs de compilation. C'est parce que l'exécution de rs.absolute (0)
vous amènera à la ligne vide avant la première ligne de rs
(au fait, cette méthode retourne un type booléen
et le résultat est un déplacement réussi. Renvoie «true» comme).
En plus de cela, les questions suivantes ont été posées, et les deux ont été posées une par une.
Statement.execeteQuery ()
ResultSet
- Expliquez les avantages de la localisation de votre application
- Utilisez l'objet
Locale
pour lire et définir les paramètres régionauxproperties
Créer et lire des fichiers- Créez un bundle de ressources pour chaque locale et chargez le bundle de ressources dans votre application
Il existe deux façons d'initialiser une instance de Locale
qui représente une région particulière:
Locale
(le pays, la langue et la variante peuvent être spécifiés comme arguments)static
de type Locale
telle que Locale.US
ou Locale.ENGLISH
Malgré le fait que la plupart des API standards java récentes n'utilisent pas new
, la classe Locale
nouvellement ajoutée dans Java 8 a une conception inhabituelle qui peut être initialisée à l'aide d'un constructeur. La méthode d'initialisation de la variable Locale
ci-dessus a été demandée. Il peut également être initialisé par la classe Locale.Builder
, qui est une classe imbriquée statique
de la classe Locale
, mais je pense qu'il n'y avait pas d'initialisation en l'utilisant dans les questions simulées et les tests réels décrits plus tard. ..
Bien qu'elle ne soit pas nouvellement ajoutée dans Java8, la classe abstraite ResourceBundle
qui représente un ensemble de ressources qui gère de manière centralisée des informations telles que la langue, la valeur numérique, les informations de passage pour chaque région spécifique est [API standard](https: //) Il existe sur docs.oracle.com/javase/jp/8/docs/api/java/util/ResourceBundle.html). Dans l'API standard Java, les deux méthodes suivantes existent depuis longtemps en tant que méthode de description des informations ci-dessus pour réaliser l'ensemble de ressources.
ListResourceBundle
, qui est une sous-classe de ResourceBundle
, à votre propre classe, remplacez la méthode abstraitepublic Object [] [] getcontents ()
, et ajoutez des informations à la définition dans cette méthode. Comment écrireproperties
Dans le test réel, je me souviens que seule la dernière des deux méthodes de conception ci-dessus a été demandée, mais on m'a également demandé comment utiliser l'ensemble de ressources en l'utilisant. Dans cet article, je voudrais donner les deux comme exemples. Tout d'abord, pour le premier, écrivez une classe qui représente les ressources suivantes.
Test_ja_JP.java
package com.gold.eight.java;
import java.util.ListResourceBundle;
public class Test_ja_JP extends ListResourceBundle {
@Override
protected Object[][] getContents() {
String[][] contents = {
{"capital", "Tokyo"},
{"currency", "yen"},
{"language", "Japanese"}
};
return contents;
}
}
Rappelez-vous que la raison pour laquelle la valeur de retour est ʻObject [] [] mais renvoie
String [] [] est parce que les tableaux Java sont covariants, comme décrit dans Génériques. Le 0ème élément est la valeur de la clé et le 1er élément est la valeur de la clé, telle que
java.util.Map <String, String>pour la
String []qui existe sous forme d'imbrication dans la
String [] []`. Entrez la valeur qui correspond à la valeur de clé. Ici, le nom de la classe est «Test_ja_JP», mais «Test» est appelé le nom de base, suivi du trait de soulignement pour décrire le code de langue et le code de pays des informations locales.
Maintenant, utilisons cette ressource comme un ensemble de ressources comme suit.
Main.java
package com.gold.eight.java;
import java.util.Locale;
import java.util.ResourceBundle;
public class Main {
public static void main(String[] args) {
ResourceBundle rb = ResourceBundle.getBundle("com.gold.eight.java.Test", Locale.JAPAN);
System.out.println(rb.getString("capital"));
System.out.println(rb.getString("currency"));
System.out.println(rb.getString("language"));
}
}
Lorsque vous compilez et exécutez les deux fichiers java ci-dessus, le résultat sera le suivant.
Tokyo
yen
Japanese
La ligne ResourceBundle rb = ResourceBundle.getBundle (" com.gold.eight.java.Test ", Locale.JAPAN);
charge la ressource précédente. À ce stade, vous devez écrire "nom du package. nom de la base" sous forme de chaîne de caractères dans le premier argument de getBundle ()
. De plus, comme l'instance Locale
peut être spécifiée comme deuxième argument, Locale.JAPAN
correspondant au code de langue et au code de pays mentionnés précédemment est écrit. Lors de la lecture des informations écrites dans la ressource, getString ()
de l'instance Resourcebundle
est utilisé pour spécifier la chaîne de valeur de clé comme argument, mais si une valeur de clé inexistante est spécifiée, java.util. MissingResourceException
est levée.
De plus, la dernière méthode de création d'un fichier properties
peut être décrite dans le format suivant au lieu de Test_ja_JP.java
.
Test_ja_JP.properties
capital=Tokyo
currency=yen
language=Japanese
Ici aussi, le nom du fichier est le nom de base suivi d'un trait de soulignement, et le code de langue et le code de pays des informations locales sont décrits. Si vous voulez l'utiliser comme un ensemble de ressources, c'est la même chose que Main.java
.
J'écrirai autant que je me souvienne comment j'ai passé du moment où j'ai commencé à étudier jusqu'à l'obtention de l'or.
2016/9/10〜
Bien que j'aie acquis Silver, je sentais que je n'étais pas satisfait de mon auto-amélioration, alors j'ai décidé d'acquérir de l'or le lendemain.
2016/9/17〜
J'ai reçu le Oracle Certification Textbook Java Programmer Gold SE 8 (communément appelé livre violet) que j'ai trouvé sur Amazon, alors étudiez a commencé. Cela ressemble plus à un manuel qu'à une collection de problèmes, alors je le lis à un rythme de trois ou quatre jours par semaine, quoique irrégulièrement. Je pense que j'ai commencé à lire le deuxième tour de mi à fin octobre 2016. Soulignez les classes et méthodes utilisées pour la première fois, et implémentez-les parfois vous-même tout en consultant la Collection d'API officielle. J'approfondissais ma compréhension.
2016/10/23〜 Lors de la lecture du deuxième tour du livre violet, c'est une version Gold de la collection de problèmes qui a été prise en charge au moment de Silver [Capture approfondie Java SE 8 Gold problem collection [1Z0-809] correspondance](https: // www .amazon.co.jp / dp / 4295000035 / ref = cm_sw_r_tw_dp_x_WjptybSP18FB5) (communément appelé Kuromoto) est sorti, et je l'ai immédiatement trouvé sur Amazon. Le livre noir de Silver a une explication polie, et des questions qui ressemblent exactement aux questions simulées à la fin du chapitre ont été posées dans l'examen proprement dit. J'ai donc décidé de le résoudre après avoir lu et compris le livre violet pendant deux tours. Je pense que c'est du début à la mi-novembre que j'ai ouvert la première page.
2016/11/23 J'ai lu des livres violets plus de deux tours et j'ai lu environ la moitié des livres noirs, alors j'ai décidé de postuler à l'examen. Mon objectif était d'obtenir l'or en novembre, mais je n'avais pas d'autre choix que de postuler le 3 décembre car il n'y avait pas de centre de test à proximité où je pourrais passer l'examen en novembre.
2016/12/3 jour de test. Quand je l'ai reçu, j'ai senti que c'était plus facile que prévu pour les livres violets et noirs. Avec environ 1 heure restante, je pense avoir tout résolu, y compris l'examen, et envoyé la réponse. Peu de temps après, CertView m'a envoyé les résultats et je savais que c'était passé.
Enfin, j'écrirai jusqu'à ce que je passe et ce que j'ai remarqué après mon passage.
Après tout, la première chose que j'ai remarquée est qu'au fur et à mesure que la conception officielle de l'API est devenue plus récente, j'ai en quelque sorte compris le flux de l'histoire de la conception, comme lancer une exception au moment de l'exécution au lieu de lancer une exception autant que possible **. Par exemple, le concept de bundles de ressources est apparu avant la sortie des génériques (Java 5), donc le type de retour de getContents ()
, qui est une méthode abstraite de ListResourceBundle
, est ʻObject [] []. C'est devenu ". Alors
@Override
protected Object[][] getContents() {
Object[][] contents = {
{"A", "1"},
{"B", 2},
{"C", 3.0}
};
return contents;
}
Vous pouvez compiler du code effrayant comme celui-ci, comme si vous me demandiez de déclencher une exception java.lang.ClassCastException
. Avec l'introduction des génériques ajoutés après cela, je comprends en quelque sorte le flux de conception pour réduire le risque de lancer java.lang.ClassCastException
en décidant où le type peut être déterminé statiquement au moment de la compilation ( Eh bien, vous pouvez lancer en utilisant ʻinstance de...). Plus récemment, Java 8 a également ajouté le type ʻOptimal <T>
, qui tente de réduire autant que possible la tristement célèbre java.lang.NullPointerException
. En conséquence, on peut s'attendre à une détection précoce des bogues dans le processus de développement, et le risque de panne du système d'exploitation est réduit.
De plus, ** les constructeurs tels que la classe Console
et la classe LocalDateTime
peuvent être masqués en spécifiant private
**, l'interface Path
, l'interface ʻExecuratorService, etc. ** Les classes abstraites et les interfaces utilisent
new`. Récemment, il existe un nombre croissant de conceptions qui n'utilisent pas autant que possible les constructeurs en profitant du fait que les instances ne peuvent pas être utilisées. C'est parce que cela empêche le concepteur d'utiliser des classes et des méthodes qui ont été redéfinies par des «extensions» / «implémentations» qui n'étaient pas prévues. Ce serait un problème pour les concepteurs d'API et les utilisateurs d'API si une exception due à un ordre incorrect d'exécution de méthode est toujours levée en exécutant une méthode avec une modification de définition incorrecte.
Même ainsi, la plupart des qualifications des fournisseurs coûtent cher aux nouveaux arrivants. J'ai appliqué un billet à prix réduit lorsque j'ai passé l'examen Gold, mais si je payais correctement les frais d'examen, cela coûterait 26 600 yens pour l'argent et 26 600 yens pour l'or, pour un total de 53 200 yens. Eh bien, il semble qu'il existe des conditions pour les frais d'examen qui sont beaucoup plus élevées que cela. .. À propos, il semble que Java 9 sortira en mars 2017, mais les qualifications Bronze, Silver et Gold de Java 9 apparaîtront-elles ainsi que Java 8? Si tel est le cas, je pense que vous pouvez obtenir Java 9 Gold en passant la mise à niveau vers Java SE 9 Programmer, mais si vous payez un par un les frais d'examen de 26 600 yens, vous devrez également payer les frais d'exploitation. Néanmoins, je voudrais me tenir au courant des dernières tendances en Java dans la mesure où je ne suis pas un passionné de qualification. Cela dit, s'il y avait une mise à niveau vers le programmeur Java SE 9, le problème avec Project Jigsaw, qui est la principale caractéristique de Java 9, serait-il le plus important? ~~ jshell, je ne pense pas que je puisse créer un problème en premier lieu. ~~
C'était un mauvais article, mais merci d'avoir lu jusqu'au bout.
Recommended Posts