La réflexion
57. Qu'est-ce que la réflexion?
La réflexion se réfère principalement à la capacité d'un programme à accéder, détecter et modifier son propre état ou comportement
Réflexion Java:
Dans l'environnement d'exécution Java, pour n'importe quelle classe, puis-je connaître les propriétés et les méthodes de cette classe? Pour tout objet, peut-il appeler l'une de ses méthodes
Le mécanisme de réflexion Java fournit principalement les fonctions suivantes:
-
Au moment de l'exécution, déterminez la classe à laquelle appartient tout objet.
-
Construisez un objet de n'importe quelle classe au moment de l'exécution.
-
Déterminez les variables membres et les méthodes de n'importe quelle classe au moment de l'exécution.
-
Appelez n'importe quelle méthode d'objet au moment de l'exécution.
58. Qu'est-ce que la sérialisation java? Quand la sérialisation est-elle requise?
En bref, il s'agit de sauvegarder l'état de divers objets en mémoire (c'est-à-dire les variables d'instance, pas les méthodes), et vous pouvez relire l'état de l'objet enregistré. Bien que vous puissiez utiliser vos propres méthodes pour enregistrer les états des objets, Java vous fournit un mécanisme qui devrait être meilleur que le vôtre pour enregistrer les états des objets, c'est-à-dire la sérialisation.
Quand sérialiser:
a) Lorsque vous souhaitez enregistrer l'état des objets en mémoire dans un fichier ou une base de données;
b) Lorsque vous souhaitez utiliser des sockets pour transférer des objets sur le réseau;
c) Lorsque vous souhaitez transférer des objets via RMI ;
59. Qu'est-ce qu'un agent dynamique? Quelles sont les applications?
Proxy dynamique:
Lorsque vous souhaitez ajouter un traitement supplémentaire à une méthode dans une classe qui implémente une interface. Par exemple, ajoutez des journaux, ajoutez des transactions, etc. Vous pouvez créer un proxy pour cette classe, le nom est donc de créer une nouvelle classe. Cette classe contient non seulement les fonctions des méthodes de classe d'origine, mais ajoute également une nouvelle classe pour un traitement supplémentaire sur la base d'origine. Cette classe proxy n'est pas définie, elle est générée dynamiquement. Il a le sens de découplage, de flexibilité et de forte expansibilité.
Application du proxy dynamique:
-
Spring 的 AOP
-
Transaction plus
-
Ajouter des autorisations
-
Ajouter un journal
60. Comment implémenter un proxy dynamique?
Tout d'abord, une interface doit être définie, et il doit également y avoir un InvocationHandler (lui passant l'objet de la classe qui implémente l'interface). Il existe une autre classe d'outils Proxy (habituellement appelée classe proxy, car appeler son newInstance () peut générer un objet proxy, en fait, il s'agit simplement d'une classe d'outils qui génère un objet proxy). Utilisez InvocationHandler, assemblez le code source de la classe proxy, compilez-le pour générer le code binaire de la classe proxy, chargez-le avec le chargeur et instanciez-le pour générer l'objet proxy, puis revenez.
Copie d'objet
61. Pourquoi utiliser le clonage?
Si vous souhaitez traiter un objet et conserver les données d'origine pour la prochaine opération, vous devez le cloner. En Java, le clonage fait référence à une instance d'une classe.
62. Comment réaliser le clonage d'objets?
Il y a deux façons:
1) .Implémentez l'interface Cloneable et remplacez la méthode clone () dans la classe Object;
La mise en œuvre de l'interface sérialisable, le clonage via la sérialisation et la désérialisation des objets, peut permettre un véritable clonage profond, le code est le suivant:
La
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class MyUtil {
private MyUtil() {
throw new AssertionError();
}
@SuppressWarnings("unchecked")
public static <T extends Serializable> T clone(T obj)
throws Exception {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bout);
oos.writeObject(obj);
ByteArrayInputStream bin =
new ByteArrayInputStream(bout.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bin);
return (T) ois.readObject();
// 说明:调用ByteArrayInputStream
//或ByteArrayOutputStream对象的close方法没有任何意义
// 这两个基于内存的流只要垃圾回收器清理对象就能够释放资源,
//这一点不同于对外部资源(如文件流)的释放
}
}
Voici le code de test:
La
import java.io.Serializable;
/**
* 人类
* @author nnngu
*
*/
class Person implements Serializable {
private static final long serialVersionUID
= -9102017020286042305L;
private String name; // 姓名
private int age; // 年龄
private Car car; // 座驾
public Person(String name, int age, Car car) {
this.name = name;
this.age = age;
this.car = car;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
@Override
public String toString() {
return "Person [name=" + name + ",
age=" + age + ", car=" + car + "]";
}
}
La
La
/**
* 小汽车类
* @author nnngu
*
*/
class Car implements Serializable {
private static final long serialVersionUID
= -5713945027627603702L;
private String brand; // 品牌
private int maxSpeed; // 最高时速
public Car(String brand, int maxSpeed) {
this.brand = brand;
this.maxSpeed = maxSpeed;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public int getMaxSpeed() {
return maxSpeed;
}
public void setMaxSpeed(int maxSpeed) {
this.maxSpeed = maxSpeed;
}
@Override
public String toString() {
return "Car [brand=" + brand + ",
maxSpeed=" + maxSpeed + "]";
}
}
La
class CloneTest {
public static void main(String[] args) {
try {
Person p1 = new Person("郭靖", 33,
new Car("Benz", 300));
Person p2 = MyUtil.clone(p1); // 深度克隆
p2.getCar().setBrand("BYD");
// 修改克隆的Person对象p2关联的汽车对象的品牌属性
// 原来的Person对象p1关联的汽车不会受到任何影响
// 因为在克隆Person对象时其关联的汽车对象也被克隆了
System.out.println(p1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Remarque: Le clonage basé sur la sérialisation et la désérialisation n'est pas seulement un clonage en profondeur, mais plus important encore, grâce à la qualification générique, vous pouvez vérifier si l'objet à cloner prend en charge la sérialisation. Cette vérification est effectuée par le compilateur, pas dans Des exceptions sont levées lors de l'exécution. Il s'agit d'une solution bien meilleure que le clonage d'objets à l'aide de la méthode clone de la classe Object. Il est toujours préférable d'exposer le problème au moment de la compilation plutôt que de le laisser au moment de l'exécution.
63. Quelle est la différence entre copie profonde et copie superficielle?
-
La copie superficielle copie uniquement l'adresse de référence de l'objet, deux objets pointent vers la même adresse mémoire, modifiez donc n'importe quelle valeur et l'autre valeur changera en conséquence. Il s'agit d'une copie superficielle (par exemple: assign ())
-
La copie profonde consiste à copier l'objet et la valeur. Si deux objets modifient l'une des valeurs, l'autre valeur ne changera pas. Il s'agit d'une copie complète (par exemple: JSON.parse () et JSON.stringify (), mais cette méthode ne peut pas copier la fonction Type)
Web Java
64. Quelle est la différence entre jsp et servlet?
-
Après la compilation, jsp devient un servlet. (L'essence de JSP est Servlet. La JVM ne peut reconnaître que la classe java, mais pas le code JSP. Le conteneur Web compile le code JSP en une classe java reconnue par la JVM)
-
jsp est meilleur pour afficher les pages et les servlets sont meilleurs pour le contrôle logique.
-
Il n'y a pas d'objets intégrés dans Servlet. Les objets intégrés dans Jsp doivent être obtenus via l'objet HttpServletRequest, l'objet HttpServletResponse et l'objet HttpServlet.
-
Jsp est une simplification de Servlet. L'utilisation de Jsp suffit de compléter le contenu dont le programmeur a besoin pour sortir vers le client. Comment installer le script Java dans Jsp dans une classe est fait par le conteneur Jsp. Le Servlet est une classe Java complète, la méthode Service de cette classe est utilisée pour générer une réponse au client.
65. De quels objets intégrés dispose jsp? Quel est le rôle?
JSP a 9 objets intégrés:
-
request: encapsule la requête du client, qui contient les paramètres de la requête GET ou POST;
-
réponse: encapsule la réponse du serveur au client;
-
pageContext: vous pouvez obtenir d'autres objets via cet objet;
-
session: l'objet qui encapsule la session de l'utilisateur;
-
application: objets qui encapsulent l'environnement d'exploitation du serveur;
-
out: objet de flux de sortie émis par la réponse du serveur;
-
config: objet de configuration de l'application web;
-
page: page JSP elle-même (équivalente à celle d'un programme Java);
-
exception: objet qui encapsule l'exception levée par la page.
66. Parlez-moi des 4 portées de jsp?
Les quatre étendues de JSP incluent la page, la demande, la session et l'application, en particulier:
-
La page représente les objets et les attributs liés à une page.
-
request représente les objets et les attributs liés à une requête émise par le client Web. Une demande peut s'étendre sur plusieurs pages et impliquer plusieurs composants Web; les données temporaires qui doivent être affichées sur la page peuvent être placées dans cette étendue.
-
session représente les objets et les attributs liés à une session établie entre un utilisateur et le serveur. Les données relatives à un utilisateur doivent être placées dans sa propre session.
-
demande au nom de l'ensemble des objets liés à l' application Web et les attributs, il est essentiellement à travers l'ensemble des applications Web, y compris les pages multiples, les demandes, et une portée globale de la session.
67. Quelle est la différence entre session et cookie?
-
Le protocole HTTP étant un protocole sans état, lorsque le serveur doit enregistrer l'état de l'utilisateur, il doit utiliser un mécanisme pour identifier l'utilisateur spécifique. Ce mécanisme est la session. Scénarios typiques tels que les paniers d'achat, lorsque vous cliquez sur le bouton de commande Étant donné que le protocole HTTP est sans état, il ne sait pas quel utilisateur fonctionne, le serveur doit donc créer une session spécifique pour un utilisateur spécifique, utilisé pour identifier cet utilisateur et suivre l'utilisateur, afin que nous sachions combien dans le panier. Le livre. Cette session est stockée sur le serveur et possède un identifiant unique. Il existe de nombreuses façons d'enregistrer la session sur le serveur, notamment la mémoire, la base de données et les fichiers. Lors du clustering, vous devez également envisager le transfert de session. Sur les grands sites Web, il y aura généralement un cluster de serveur de session dédié pour enregistrer les sessions utilisateur. À ce stade, les informations de session sont stockées en mémoire et certains services de cache tels que Memcached sont utilisés. Venez mettre Session.
-
Pensez à la façon dont le serveur identifie des clients spécifiques? À ce moment, Cookie est apparu. À chaque demande HTTP, le client enverra les informations correspondantes du cookie au serveur. En fait, la plupart des applications utilisent des cookies pour implémenter le suivi de session. Lors de la création d'une session pour la première fois, le serveur indiquera au client dans le protocole HTTP qu'un ID de session doit être enregistré dans le cookie. L'identifiant de session est envoyé au serveur et je sais qui vous êtes. Quelqu'un demande, que se passe-t-il si le navigateur du client désactive les cookies? Généralement, dans ce cas, une technique appelée réécriture d'URL est utilisée pour le suivi de session, c'est-à-dire que chaque interaction HTTP, l'URL sera ajoutée avec un paramètre tel que sid = xxxxx, et le serveur reconnaît l'utilisateur en fonction de cela.
-
Les cookies peuvent en fait être utilisés dans certains scénarios conviviaux. Imaginez que vous vous êtes connecté à un site Web une fois et que vous ne souhaitez pas saisir à nouveau votre numéro de compte la prochaine fois que vous vous connectez. Que devez-vous faire? Ces informations peuvent être écrites dans un cookie.Lorsque vous visitez le site Web, le script sur la page du site Web peut lire ces informations et il remplira automatiquement le nom d'utilisateur pour vous, ce qui peut faciliter la tâche de l'utilisateur. C'est aussi l'origine du nom du cookie, un peu de douceur pour l'utilisateur. Donc, pour résumer: la session est une structure de données enregistrée sur le serveur, utilisée pour suivre l'état de l'utilisateur, ces données peuvent être enregistrées dans le cluster, la base de données, le fichier; Le cookie est un mécanisme permettant au client de sauvegarder les informations de l'utilisateur, utilisé pour enregistrer Certaines informations utilisateur sont également un moyen d'implémenter Session.
68. Parlez-moi du fonctionnement de la session?
En fait, la session est un fichier ressemblant à une table de hachage stockée sur le serveur. Il contient les informations dont nous avons besoin et peut être retiré lorsque nous en avons besoin. Semblable à une grande carte, les clés à l'intérieur stockent l'identifiant de session de l'utilisateur, et l'utilisateur apportera cet identifiant de session lors de l'envoi d'une demande au serveur. À ce moment, la valeur correspondante peut en être retirée.
69. La session peut-elle être utilisée si le client interdit les cookies?
Cookie et Session sont généralement considérés comme deux choses distinctes: Session adopte le schéma de maintien de l'état côté serveur, tandis que Cookie adopte le schéma de maintien de l'état côté client. Mais pourquoi ne pouvez-vous pas obtenir Session si vous désactivez les cookies? Étant donné que la session utilise l'ID de session pour déterminer la session de serveur correspondant à la session en cours et que l'ID de session est transmis via le cookie, la désactivation du cookie équivaut à perdre l'ID de session et vous n'obtiendrez pas la session.
En supposant que l'utilisateur utilise la session lorsque le cookie est fermé, les méthodes de mise en œuvre sont les suivantes:
-
Définissez "session.use_trans_sid = 1" dans le fichier de configuration php.ini, ou ouvrez l'option "--enable-trans-sid" lors de la compilation et laissez PHP passer automatiquement l'ID de session sur les pages.
-
Passez manuellement la valeur via l'URL et passez l'ID de session sur le formulaire masqué.
-
Enregistrez l'ID de session sous forme de fichiers, de bases de données, etc. et appelez-le manuellement pendant le processus de cross-page.
70. Quelle est la différence entre le ressort mvc et les jambes de force?
-
Différents mécanismes d'interception
Struts2 est une interception au niveau de la classe. Chaque demande crée une action. Lors de l'intégration à Spring, la portée d'injection ActionBean de Struts2 est le prototype du mode prototype, puis les données de la demande sont injectées dans la propriété via le setter et le getter. Dans Struts2, une action correspond à un contexte de demande et de réponse. Lors de la réception de paramètres, elle peut être reçue via des attributs, ce qui signifie que les paramètres d'attribut sont partagés par plusieurs méthodes. Une méthode d'action dans Struts2 peut correspondre à une URL, mais son attribut de classe est partagé par toutes les méthodes, qui ne peuvent pas être utilisées pour identifier sa propre méthode à l'aide d'annotations ou d'autres méthodes, et ne peuvent être conçues que comme plusieurs cas.
SpringMVC est une interception au niveau de la méthode. Une méthode correspond à un contexte de demande, donc la méthode est fondamentalement indépendante, avec des données de demande et de réponse exclusives. Et chaque méthode correspond à quelle URL en même temps, le transfert de paramètres est directement injecté dans la méthode, qui est unique à la méthode. Le résultat du traitement est renvoyé au framework via ModeMap. Lors de l'intégration de Spring, le bean de contrôleur de Spring MVC utilise par défaut le mode singleton Singleton. Par défaut, pour toutes les demandes, un seul contrôleur sera créé et aucun attribut partagé ne devrait être créé, il est donc thread-safe. Si vous souhaitez modifier la portée par défaut, Besoin d'ajouter l'annotation @Scope à modifier.
Struts2 possède son propre mécanisme d'intercepteur. SpringMVC utilise une méthode Aop indépendante, qui conduit à une plus grande quantité de fichiers de configuration Struts2 que SpringMVC.
-
La différence entre le cadre sous-jacent
Struts2 est implémenté avec Filter (StrutsPrepareAndExecuteFilter) et SpringMVC (DispatcherServlet) est implémenté avec Servlet. Le filtre est initialisé après le démarrage du conteneur; le service se bloque après son arrêt, plus tard que le servlet. Le servlet est initialisé lors de son appel, avant l'appel du filtre, et détruit après l'arrêt du service.
-
Performances
Struts2 est une interception au niveau de la classe. Chaque demande correspond à une instance d'une nouvelle action. Toutes les injections de valeur d'attribut doivent être chargées. Spring MVC implémente une configuration nulle. En raison de l'interception basée sur les méthodes de Spring MVC, il y a une injection de bean singleton. Par conséquent, l'efficacité et les performances de développement de SpringMVC sont supérieures à Struts2.
-
Aspect de configuration
Spring MVC et Spring sont sans couture. La gestion et la sécurité de ce projet sont également supérieures à Struts2.
71. Comment éviter l'injection SQL?
-
PreparedStatement (méthode simple et efficace)
-
Utiliser des expressions régulières pour filtrer les paramètres entrants
-
Filtrage de chaînes
-
Appelez cette fonction dans JSP pour vérifier si le paquet est un caractère illégal
-
Code de jugement de page JSP
72. Qu'est-ce qu'une attaque XSS et comment l'éviter?
L'attaque XSS est également connue sous le nom de CSS, le nom complet de Cross Site Script (attaque de script intersite), le principe est que l'attaquant entre du code HTML malveillant dans un site Web avec une vulnérabilité XSS, lorsque l'utilisateur navigue sur le site Web, ce code HTML sera automatiquement exécuté Afin d'atteindre le but de l'attaque. Les attaques XSS sont similaires aux attaques par injection SQL. Dans les attaques par injection SQL, les instructions SQL sont utilisées comme entrée utilisateur pour atteindre l'objectif d'interrogation / modification / suppression de données. Dans les attaques xss, des scripts malveillants sont insérés pour contrôler les navigateurs des utilisateurs. Quelques informations utilisateur. XSS est une vulnérabilité courante dans les programmes Web. XSS est une méthode d'attaque passive et côté client.
L'idée générale de la prévention XSS est de filtrer l'entrée (et les paramètres URL) et d'encoder la sortie.
73. Qu'est-ce qu'une attaque CSRF et comment l'éviter?
CSRF (Cross-site request forgery) est également connu sous le nom d'attaque en un clic ou d'équitation de session. Le nom complet en chinois est appelé contrefaçon de demande intersite . De manière générale, un attaquant envoie une demande à un site Web qu'un utilisateur s'est authentifié pour visiter en forgeant le navigateur d'un utilisateur, de sorte que le site Web cible reçoive et pense à tort que c'est la véritable opération de l'utilisateur d'exécuter la commande. Couramment utilisé pour voler des numéros de compte, transférer des fonds, envoyer de faux messages, etc. L'attaquant utilise la vulnérabilité de vérification de la demande du site Web pour mettre en œuvre une telle attaque. Le site Web peut confirmer que la demande provient du navigateur de l'utilisateur, mais ne peut pas vérifier si la demande provient du comportement réel de l'utilisateur.
Comment éviter:
1. Vérifiez le champ HTTP Referer
Le champ Referer dans l'en-tête HTTP enregistre l'adresse source de la demande HTTP. Dans des circonstances normales, une demande d'accès à une page à sécurité limitée provient du même site Web, et si un pirate informatique veut mettre en œuvre une
attaque CSRF sur celle-ci, il ne peut généralement construire une demande que sur son propre site Web. Par conséquent, les attaques CSRF peuvent être évitées en vérifiant la valeur Referer.
2. Utilisez le code de vérification
Le code de vérification est ajouté à la page d'opération clé et le CSRF peut être défendu en jugeant le code de vérification après avoir reçu la demande en arrière-plan. Mais cette méthode n'est pas conviviale.
3. Ajoutez un jeton à l'adresse de demande et vérifiez
La raison pour laquelle l'attaque CSRF est réussie est que le pirate peut forger complètement la demande de l'utilisateur. Toutes les informations d'authentification de l'utilisateur contenues dans la demande se trouvent dans le cookie, afin que le pirate puisse utiliser directement le cookie de l'utilisateur sans connaître les informations d'authentification. Pour passer la vérification de sécurité. Pour se défendre contre CSRF, la clé est de mettre dans la demande des informations que le pirate ne peut pas falsifier, et les informations n'existent pas dans le cookie. Vous pouvez ajouter un jeton généré de manière aléatoire sous forme de paramètres à la demande HTTP et établir un intercepteur sur le serveur pour vérifier le jeton. S'il n'y a pas de jeton dans la demande ou si le contenu du jeton est incorrect, il est considéré qu'il peut s'agir d'une attaque CSRF et rejeter la demande. . Cette méthode est plus sûre que la vérification du référent. Le jeton peut être généré après que l'utilisateur se connecte et placé dans la session, puis le jeton est retiré de la session à chaque demande et comparé au jeton dans la demande, mais ceci La difficulté de cette méthode est de savoir comment ajouter le jeton à la requête sous forme de paramètres.
Pour les demandes GET, le jeton sera ajouté à l'adresse de la demande, de sorte que l'URL devienne http: // url? Csrftoken = tokenvalue.
Pour les demandes POST, ajoutez <input type = "hidden" name = "csrftoken" value = "tokenvalue" /> à la fin du formulaire, afin que le jeton soit ajouté à la demande en tant que paramètre.
4. Personnalisez les attributs dans l'en-tête HTTP et vérifiez
Cette méthode utilise également un jeton et effectue l'authentification. Contrairement à la méthode précédente, il ne s'agit pas de placer le jeton dans la requête HTTP en tant que paramètre, mais de le placer dans un attribut personnalisé dans l'en-tête HTTP. Grâce à la classe XMLHttpRequest, vous pouvez ajouter l'attribut d'en-tête HTTP csrftoken à toutes les demandes de ce type à la fois et y mettre la valeur du jeton. Cela résout l'inconvénient d'ajouter des jetons à la demande dans la méthode précédente. En même temps, l'adresse demandée via XMLHttpRequest ne sera pas enregistrée dans la barre d'adresse du navigateur, et il n'est pas nécessaire de s'inquiéter que le jeton soit divulgué à d'autres sites Web via le référent.