聊聊mysql jdbc的prepareStatement

本文主要研究一下mysql jdbc的prepareStatement

prepareStatement

java/sql/Connection.java

    /*** Creates a <code>PreparedStatement</code> object for sending* parameterized SQL statements to the database.* <P>* A SQL statement with or without IN parameters can be* pre-compiled and stored in a <code>PreparedStatement</code> object. This* object can then be used to efficiently execute this statement* multiple times.** <P><B>Note:</B> This method is optimized for handling* parametric SQL statements that benefit from precompilation. If* the driver supports precompilation,* the method <code>prepareStatement</code> will send* the statement to the database for precompilation. Some drivers* may not support precompilation. In this case, the statement may* not be sent to the database until the <code>PreparedStatement</code>* object is executed.  This has no direct effect on users; however, it does* affect which methods throw certain <code>SQLException</code> objects.* <P>* Result sets created using the returned <code>PreparedStatement</code>* object will by default be type <code>TYPE_FORWARD_ONLY</code>* and have a concurrency level of <code>CONCUR_READ_ONLY</code>.* The holdability of the created result sets can be determined by* calling {@link #getHoldability}.** @param sql an SQL statement that may contain one or more '?' IN* parameter placeholders* @return a new default <code>PreparedStatement</code> object containing the* pre-compiled SQL statement* @exception SQLException if a database access error occurs* or this method is called on a closed connection*/PreparedStatement prepareStatement(String sql)throws SQLException;

java.sql.Connection定义了prepareStatement方法,根据sql创建PreparedStatement

ConnectionImpl

mysql-connector-java-5.1.21-sources.jar!/com/mysql/jdbc/ConnectionImpl.java

	/*** A SQL statement with or without IN parameters can be pre-compiled and* stored in a PreparedStatement object. This object can then be used to* efficiently execute this statement multiple times.* <p>* <B>Note:</B> This method is optimized for handling parametric SQL* statements that benefit from precompilation if the driver supports* precompilation. In this case, the statement is not sent to the database* until the PreparedStatement is executed. This has no direct effect on* users; however it does affect which method throws certain* java.sql.SQLExceptions* </p>* <p>* MySQL does not support precompilation of statements, so they are handled* by the driver.* </p>* * @param sql*            a SQL statement that may contain one or more '?' IN parameter*            placeholders* @return a new PreparedStatement object containing the pre-compiled*         statement.* @exception SQLException*                if a database access error occurs.*/public java.sql.PreparedStatement prepareStatement(String sql)throws SQLException {return prepareStatement(sql, DEFAULT_RESULT_SET_TYPE,DEFAULT_RESULT_SET_CONCURRENCY);}

mysql jdbc的ConnectionImpl实现了prepareStatement方法,根据注释,预编译主要是driver来处理

prepareStatement

mysql-connector-java-5.1.21-sources.jar!/com/mysql/jdbc/ConnectionImpl.java

	/*** JDBC 2.0 Same as prepareStatement() above, but allows the default result* set type and result set concurrency type to be overridden.* * @param sql*            the SQL query containing place holders* @param resultSetType*            a result set type, see ResultSet.TYPE_XXX* @param resultSetConcurrency*            a concurrency type, see ResultSet.CONCUR_XXX* @return a new PreparedStatement object containing the pre-compiled SQL*         statement* @exception SQLException*                if a database-access error occurs.*/public synchronized java.sql.PreparedStatement prepareStatement(String sql,int resultSetType, int resultSetConcurrency) throws SQLException {checkClosed();//// FIXME: Create warnings if can't create results of the given// type or concurrency//PreparedStatement pStmt = null;boolean canServerPrepare = true;String nativeSql = getProcessEscapeCodesForPrepStmts() ? nativeSQL(sql): sql;if (this.useServerPreparedStmts && getEmulateUnsupportedPstmts()) {canServerPrepare = canHandleAsServerPreparedStatement(nativeSql);}if (this.useServerPreparedStmts && canServerPrepare) {if (this.getCachePreparedStatements()) {synchronized (this.serverSideStatementCache) {pStmt = (com.mysql.jdbc.ServerPreparedStatement)this.serverSideStatementCache.remove(sql);if (pStmt != null) {((com.mysql.jdbc.ServerPreparedStatement)pStmt).setClosed(false);pStmt.clearParameters();}if (pStmt == null) {try {pStmt = ServerPreparedStatement.getInstance(getLoadBalanceSafeProxy(), nativeSql,this.database, resultSetType, resultSetConcurrency);if (sql.length() < getPreparedStatementCacheSqlLimit()) {((com.mysql.jdbc.ServerPreparedStatement)pStmt).isCached = true;}pStmt.setResultSetType(resultSetType);pStmt.setResultSetConcurrency(resultSetConcurrency);} catch (SQLException sqlEx) {// Punt, if necessaryif (getEmulateUnsupportedPstmts()) {pStmt = (PreparedStatement) clientPrepareStatement(nativeSql, resultSetType, resultSetConcurrency, false);if (sql.length() < getPreparedStatementCacheSqlLimit()) {this.serverSideStatementCheckCache.put(sql, Boolean.FALSE);}} else {throw sqlEx;}}}}} else {try {pStmt = ServerPreparedStatement.getInstance(getLoadBalanceSafeProxy(), nativeSql,this.database, resultSetType, resultSetConcurrency);pStmt.setResultSetType(resultSetType);pStmt.setResultSetConcurrency(resultSetConcurrency);} catch (SQLException sqlEx) {// Punt, if necessaryif (getEmulateUnsupportedPstmts()) {pStmt = (PreparedStatement) clientPrepareStatement(nativeSql, resultSetType, resultSetConcurrency, false);} else {throw sqlEx;}}}} else {pStmt = (PreparedStatement) clientPrepareStatement(nativeSql, resultSetType, resultSetConcurrency, false);}return pStmt;}

prepareStatement首先根据useServerPreparedStmts以及getEmulateUnsupportedPstmts来判断是否要通过canHandleAsServerPreparedStatement判断canServerPrepare;之后在useServerPreparedStmts及canServerPrepare为true时,根据cachePreparedStatements做ServerPreparedStatement的处理;如果不开启serverPrepare则执行clientPrepareStatement

canHandleAsServerPreparedStatement

mysql-connector-java-5.1.21-sources.jar!/com/mysql/jdbc/ConnectionImpl.java

	private boolean canHandleAsServerPreparedStatement(String sql) throws SQLException {if (sql == null || sql.length() == 0) {return true;}if (!this.useServerPreparedStmts) {return false;}if (getCachePreparedStatements()) {synchronized (this.serverSideStatementCheckCache) {Boolean flag = (Boolean)this.serverSideStatementCheckCache.get(sql);if (flag != null) {return flag.booleanValue();}boolean canHandle = canHandleAsServerPreparedStatementNoCache(sql);if (sql.length() < getPreparedStatementCacheSqlLimit()) {this.serverSideStatementCheckCache.put(sql, canHandle ? Boolean.TRUE : Boolean.FALSE);}return canHandle;}}return canHandleAsServerPreparedStatementNoCache(sql);}

canHandleAsServerPreparedStatement首先判断useServerPreparedStmts,之后若cachePreparedStatements为true则做serverSideStatementCheckCache判断,最后都会通过canHandleAsServerPreparedStatementNoCache进行判断

canHandleAsServerPreparedStatementNoCache

mysql-connector-java-5.1.21-sources.jar!/com/mysql/jdbc/ConnectionImpl.java

	private boolean canHandleAsServerPreparedStatementNoCache(String sql) throws SQLException {// Can't use server-side prepare for CALLif (StringUtils.startsWithIgnoreCaseAndNonAlphaNumeric(sql, "CALL")) {return false;}boolean canHandleAsStatement = true;if (!versionMeetsMinimum(5, 0, 7) && (StringUtils.startsWithIgnoreCaseAndNonAlphaNumeric(sql, "SELECT")|| StringUtils.startsWithIgnoreCaseAndNonAlphaNumeric(sql,"DELETE")|| StringUtils.startsWithIgnoreCaseAndNonAlphaNumeric(sql,"INSERT")|| StringUtils.startsWithIgnoreCaseAndNonAlphaNumeric(sql,"UPDATE")|| StringUtils.startsWithIgnoreCaseAndNonAlphaNumeric(sql,"REPLACE"))) {// check for limit ?[,?]/** The grammar for this (from the server) is: ULONG_NUM | ULONG_NUM* ',' ULONG_NUM | ULONG_NUM OFFSET_SYM ULONG_NUM*/int currentPos = 0;int statementLength = sql.length();int lastPosToLook = statementLength - 7; // "LIMIT ".length()boolean allowBackslashEscapes = !this.noBackslashEscapes;char quoteChar = this.useAnsiQuotes ? '"' : '\'';boolean foundLimitWithPlaceholder = false;while (currentPos < lastPosToLook) {int limitStart = StringUtils.indexOfIgnoreCaseRespectQuotes(currentPos, sql, "LIMIT ", quoteChar,allowBackslashEscapes);if (limitStart == -1) {break;}currentPos = limitStart + 7;while (currentPos < statementLength) {char c = sql.charAt(currentPos);//// Have we reached the end// of what can be in a LIMIT clause?//if (!Character.isDigit(c) && !Character.isWhitespace(c)&& c != ',' && c != '?') {break;}if (c == '?') {foundLimitWithPlaceholder = true;break;}currentPos++;}}canHandleAsStatement = !foundLimitWithPlaceholder;} else if (StringUtils.startsWithIgnoreCaseAndWs(sql, "CREATE TABLE")) {canHandleAsStatement = false;} else if (StringUtils.startsWithIgnoreCaseAndWs(sql, "DO")) {canHandleAsStatement = false;} else if (StringUtils.startsWithIgnoreCaseAndWs(sql, "SET")) {canHandleAsStatement = false;}return canHandleAsStatement;}

canHandleAsServerPreparedStatementNoCache方法针对call、create table、do、set返回false,其他的针对小于5.0.7版本的做特殊判断,其余的默认返回true

clientPrepareStatement

mysql-connector-java-5.1.21-sources.jar!/com/mysql/jdbc/ConnectionImpl.java

	/** A cache of SQL to parsed prepared statement parameters. */private CacheAdapter<String, ParseInfo> cachedPreparedStatementParams;public java.sql.PreparedStatement clientPrepareStatement(String sql,int resultSetType, int resultSetConcurrency, boolean processEscapeCodesIfNeeded) throws SQLException {checkClosed();String nativeSql = processEscapeCodesIfNeeded && getProcessEscapeCodesForPrepStmts() ? nativeSQL(sql): sql;PreparedStatement pStmt = null;if (getCachePreparedStatements()) {PreparedStatement.ParseInfo pStmtInfo = this.cachedPreparedStatementParams.get(nativeSql);if (pStmtInfo == null) {pStmt = com.mysql.jdbc.PreparedStatement.getInstance(getLoadBalanceSafeProxy(), nativeSql,this.database);this.cachedPreparedStatementParams.put(nativeSql, pStmt.getParseInfo());} else {pStmt = new com.mysql.jdbc.PreparedStatement(getLoadBalanceSafeProxy(), nativeSql,this.database, pStmtInfo);}} else {pStmt = com.mysql.jdbc.PreparedStatement.getInstance(getLoadBalanceSafeProxy(), nativeSql,this.database);}pStmt.setResultSetType(resultSetType);pStmt.setResultSetConcurrency(resultSetConcurrency);return pStmt;}

clientPrepareStatement在cachePreparedStatements为true时会从cachedPreparedStatementParams(缓存的key为nativeSql,value为ParseInfo)去获取ParseInfo,获取不到则执行com.mysql.jdbc.PreparedStatement.getInstance再放入缓存,获取到ParseInfo则通过com.mysql.jdbc.PreparedStatement(getLoadBalanceSafeProxy(), nativeSql,this.database, pStmtInfo)创建PreparedStatement;如果为false则直接通过com.mysql.jdbc.PreparedStatement.getInstance来创建

PreparedStatement.getInstance

mysql-connector-java-5.1.21-sources.jar!/com/mysql/jdbc/PreparedStatement.java

	/*** Creates a prepared statement instance -- We need to provide factory-style* methods so we can support both JDBC3 (and older) and JDBC4 runtimes,* otherwise the class verifier complains when it tries to load JDBC4-only* interface classes that are present in JDBC4 method signatures.*/protected static PreparedStatement getInstance(MySQLConnection conn, String sql,String catalog) throws SQLException {if (!Util.isJdbc4()) {return new PreparedStatement(conn, sql, catalog);}return (PreparedStatement) Util.handleNewInstance(JDBC_4_PSTMT_3_ARG_CTOR, new Object[] { conn, sql, catalog }, conn.getExceptionInterceptor());}

getInstance方法对于非jdbc4的直接new一个PreparedStatement,若使用了jdbc4则通过Util.handleNewInstance使用JDBC_4_PSTMT_3_ARG_CTOR的构造器反射创建

JDBC_4_PSTMT_3_ARG_CTOR

mysql-connector-java-5.1.21-sources.jar!/com/mysql/jdbc/PreparedStatement.java

public class PreparedStatement extends com.mysql.jdbc.StatementImpl implementsjava.sql.PreparedStatement {private static final Constructor<?> JDBC_4_PSTMT_2_ARG_CTOR;private static final Constructor<?> JDBC_4_PSTMT_3_ARG_CTOR;private static final Constructor<?> JDBC_4_PSTMT_4_ARG_CTOR;static {if (Util.isJdbc4()) {try {JDBC_4_PSTMT_2_ARG_CTOR = Class.forName("com.mysql.jdbc.JDBC4PreparedStatement").getConstructor(new Class[] { MySQLConnection.class, String.class });JDBC_4_PSTMT_3_ARG_CTOR = Class.forName("com.mysql.jdbc.JDBC4PreparedStatement").getConstructor(new Class[] { MySQLConnection.class, String.class,String.class });JDBC_4_PSTMT_4_ARG_CTOR = Class.forName("com.mysql.jdbc.JDBC4PreparedStatement").getConstructor(new Class[] { MySQLConnection.class, String.class,String.class, ParseInfo.class });} catch (SecurityException e) {throw new RuntimeException(e);} catch (NoSuchMethodException e) {throw new RuntimeException(e);} catch (ClassNotFoundException e) {throw new RuntimeException(e);}} else {JDBC_4_PSTMT_2_ARG_CTOR = null;JDBC_4_PSTMT_3_ARG_CTOR = null;JDBC_4_PSTMT_4_ARG_CTOR = null;}}//......
}	

com.mysql.jdbc.PreparedStatement在static方法初始化了JDBC_4_PSTMT_3_ARG_CTOR,其构造器有三个参数,分别是MySQLConnection.class, String.class,String.class,使用的类是com.mysql.jdbc.JDBC4PreparedStatement

JDBC4PreparedStatement

mysql-connector-java-5.1.21-sources.jar!/com/mysql/jdbc/JDBC4PreparedStatement.java

public class JDBC4PreparedStatement extends PreparedStatement {public JDBC4PreparedStatement(MySQLConnection conn, String catalog) throws SQLException {super(conn, catalog);}public JDBC4PreparedStatement(MySQLConnection conn, String sql, String catalog)throws SQLException {super(conn, sql, catalog);}public JDBC4PreparedStatement(MySQLConnection conn, String sql, String catalog,ParseInfo cachedParseInfo) throws SQLException {super(conn, sql, catalog, cachedParseInfo);}public void setRowId(int parameterIndex, RowId x) throws SQLException {JDBC4PreparedStatementHelper.setRowId(this, parameterIndex, x);}/*** JDBC 4.0 Set a NCLOB parameter.* * @param i*            the first parameter is 1, the second is 2, ...* @param x*            an object representing a NCLOB* * @throws SQLException*             if a database error occurs*/public void setNClob(int parameterIndex, NClob value) throws SQLException {JDBC4PreparedStatementHelper.setNClob(this, parameterIndex, value);}public void setSQLXML(int parameterIndex, SQLXML xmlObject)throws SQLException {JDBC4PreparedStatementHelper.setSQLXML(this, parameterIndex, xmlObject);}
}	

JDBC4PreparedStatement的三个参数构造器主要是调用了父类PreparedStatement的对应的构造器;JDBC4PreparedStatement主要是支持了setNClob、setSQLXML

new PreparedStatement

mysql-connector-java-5.1.21-sources.jar!/com/mysql/jdbc/PreparedStatement.java

	/*** Constructor for the PreparedStatement class.* * @param conn*            the connection creating this statement* @param sql*            the SQL for this statement* @param catalog*            the catalog/database this statement should be issued against* * @throws SQLException*             if a database error occurs.*/public PreparedStatement(MySQLConnection conn, String sql, String catalog)throws SQLException {super(conn, catalog);if (sql == null) {throw SQLError.createSQLException(Messages.getString("PreparedStatement.0"), //$NON-NLS-1$SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor());}detectFractionalSecondsSupport();this.originalSql = sql;if (this.originalSql.startsWith(PING_MARKER)) {this.doPingInstead = true;} else {this.doPingInstead = false;}this.dbmd = this.connection.getMetaData();this.useTrueBoolean = this.connection.versionMeetsMinimum(3, 21, 23);this.parseInfo = new ParseInfo(sql, this.connection, this.dbmd,this.charEncoding, this.charConverter);initializeFromParseInfo();this.compensateForOnDuplicateKeyUpdate = this.connection.getCompensateOnDuplicateKeyUpdateCounts();if (conn.getRequiresEscapingEncoder())charsetEncoder = Charset.forName(conn.getEncoding()).newEncoder();}

这里主要是用了connection的metaData、以及构造ParseInfo

StatementImpl

mysql-connector-java-5.1.21-sources.jar!/com/mysql/jdbc/StatementImpl.java

	public StatementImpl(MySQLConnection c, String catalog) throws SQLException {if ((c == null) || c.isClosed()) {throw SQLError.createSQLException(Messages.getString("Statement.0"), //$NON-NLS-1$SQLError.SQL_STATE_CONNECTION_NOT_OPEN, null); //$NON-NLS-1$ //$NON-NLS-2$}this.connection = c;this.connectionId = this.connection.getId();this.exceptionInterceptor = this.connection.getExceptionInterceptor();this.currentCatalog = catalog;this.pedantic = this.connection.getPedantic();this.continueBatchOnError = this.connection.getContinueBatchOnError();this.useLegacyDatetimeCode = this.connection.getUseLegacyDatetimeCode();if (!this.connection.getDontTrackOpenResources()) {this.connection.registerStatement(this);}//// Adjust, if we know it//if (this.connection != null) {this.maxFieldSize = this.connection.getMaxAllowedPacket();int defaultFetchSize = this.connection.getDefaultFetchSize();if (defaultFetchSize != 0) {setFetchSize(defaultFetchSize);}if (this.connection.getUseUnicode()) {this.charEncoding = this.connection.getEncoding();this.charConverter = this.connection.getCharsetConverter(this.charEncoding);}boolean profiling = this.connection.getProfileSql()|| this.connection.getUseUsageAdvisor() || this.connection.getLogSlowQueries();if (this.connection.getAutoGenerateTestcaseScript() || profiling) {this.statementId = statementCounter++;}if (profiling) {this.pointOfOrigin = new Throwable();this.profileSQL = this.connection.getProfileSql();this.useUsageAdvisor = this.connection.getUseUsageAdvisor();this.eventSink = ProfilerEventHandlerFactory.getInstance(this.connection);}int maxRowsConn = this.connection.getMaxRows();if (maxRowsConn != -1) {setMaxRows(maxRowsConn);}this.holdResultsOpenOverClose = this.connection.getHoldResultsOpenOverStatementClose();}version5013OrNewer = this.connection.versionMeetsMinimum(5, 0, 13);}

这里会获取connection的一系列配置,同时对于需要trackOpenResources的会执行registerStatement(这个在realClose的时候会unregister)

参数值

isJdbc4

com/mysql/jdbc/Util.java

private static boolean isJdbc4 = false;try {Class.forName("java.sql.NClob");isJdbc4 = true;} catch (Throwable t) {isJdbc4 = false;}

isJdbc4默认为false,在检测到java.sql.NClob类的时候为true;jdk8版本支持jdbc4

useServerPreparedStmts

com/mysql/jdbc/ConnectionPropertiesImpl.java

	private BooleanConnectionProperty detectServerPreparedStmts = new BooleanConnectionProperty("useServerPrepStmts", //$NON-NLS-1$false,Messages.getString("ConnectionProperties.useServerPrepStmts"), //$NON-NLS-1$"3.1.0", MISC_CATEGORY, Integer.MIN_VALUE); //$NON-NLS-1$

useServerPreparedStmts默认为false

cachePrepStmts

com/mysql/jdbc/ConnectionPropertiesImpl.java

	private BooleanConnectionProperty cachePreparedStatements = new BooleanConnectionProperty("cachePrepStmts", //$NON-NLS-1$false,Messages.getString("ConnectionProperties.cachePrepStmts"), //$NON-NLS-1$"3.0.10", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); //$NON-NLS-1$

cachePrepStmts默认为false

小结

  • mysql的jdbc driver的prepareStatement首先根据useServerPreparedStmts以及getEmulateUnsupportedPstmts来判断是否要通过canHandleAsServerPreparedStatement判断canServerPrepare;之后在useServerPreparedStmts及canServerPrepare为true时,根据cachePreparedStatements做ServerPreparedStatement的处理;如果不开启serverPrepare则执行clientPrepareStatement(useServerPreparedStmts及cachePrepStmts参数默认为false)
  • clientPrepareStatement在cachePreparedStatements为true时会从cachedPreparedStatementParams(缓存的key为nativeSql,value为ParseInfo)去获取ParseInfo,获取不到则执行com.mysql.jdbc.PreparedStatement.getInstance再放入缓存,获取到ParseInfo则通过com.mysql.jdbc.PreparedStatement(getLoadBalanceSafeProxy(), nativeSql,this.database, pStmtInfo)创建PreparedStatement;如果为false则直接通过com.mysql.jdbc.PreparedStatement.getInstance来创建
  • useServerPreparedStmts为true时,创建的是ServerPreparedStatement(创建的时候会触发prepare操作,往mysql服务端发送COM_PREPARE指令),本地通过serverSideStatementCache类来缓存ServerPreparedStatement,key为sql

doc

  • 预编译语句(Prepared Statements)介绍,以MySQL为例

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/68670.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot之RestTemplate使用Apache的HttpClient连接池

SpringBoot自带的RestTemplate是没有使用连接池的&#xff0c;只是SimpleClientHttpRequestFactory实现了ClientHttpRequestFactory、AsyncClientHttpRequestFactory 2个工厂接口&#xff0c;因此每次调用接口都会创建连接和销毁连接&#xff0c;如果是高并发场景下会大大降低性…

Vue/React 项目部署到服务器后,刷新页面出现404报错

问题描述&#xff1a;在本地启动项目一切正常&#xff0c;部署到服务器上线后出现BUG&#xff0c;项目刷新页面出现404。 起初以为是自己路由守卫或是token丢失问题&#xff0c;找了一圈终于解决了 产生原因&#xff1a;我们打开vue/react打包后生成的dist文件夹&#xff0c;可…

论文开题:成功之门的五大关键策略

研究生、博士生、学者或任何从事研究的人都会面临一个不可避免的环节——论文开题。这一阶段不仅定义了接下来研究的方向&#xff0c;还可能影响到整个项目的成功与否。那么&#xff0c;如何确保你的开题过程能够无瑕通过&#xff0c;还能打动评审人呢&#xff1f;本文将揭示论…

MEMS传感器的原理与构造——单片式硅陀螺仪

一、前言 机械转子式陀螺仪在很长的一段时间内都是唯一的选项&#xff0c;也正是因为它的结构和原理&#xff0c;使其不再适用于现代小型、单体、集成式传感器的设计。常规的机械转子式陀螺仪包括平衡环、支撑轴承、电机和转子等部件&#xff0c;这些部件需要精密加工和…

文件包含漏洞利用的几种方法

文章目录 安装环境启动环境漏洞花式利用蚁剑连接图片马读取敏感文件&#xff08;hosts&#xff09;读取该网站的php源码 代码审计 安装环境 安装phpstudy&#xff0c;下载MetInfo 5.0.4版本软件&#xff0c;复制到phpstudy目录下的www目录中。 打开phpstudy&#xff0c;访问浏…

JVM的故事—— 内存分配策略

内存分配策略 文章目录 内存分配策略一、对象优先在Eden分配二、大对象直接进入老年代三、长期存活的对象将进入老年代四、动态对象年龄判定五、空间分配担保 一、对象优先在Eden分配 堆内存有新生代和老年代&#xff0c;新生代中有一个Eden区和一个Survivor区(from space或者…

恒运资本:北交所股票全红!不到10分钟30%涨停,“认房不认贷”发力了!

今天早盘&#xff0c;A股震荡上扬&#xff0c;上证指数、深证成指等重要股指高开高走&#xff0c;并均涨超1%&#xff0c;两市成交略有增加。 盘面上&#xff0c;房地产、家居用品、煤炭、钢铁等板块涨幅居前&#xff0c;光刻机、软件服务、半导体、机器视觉等板块跌幅居前。北…

【Linux系列】vmware虚拟机网络配置详解

非原创 原文地址[1] 首发博客地址[2] 系列文章地址[3] vmware 为我们提供了三种网络工作模式&#xff0c;它们分别是&#xff1a;Bridged&#xff08;桥接模式&#xff09;、NAT&#xff08;网络地址转换模式&#xff09;、Host-Only&#xff08;仅主机模式&#xff09;。 打开…

【能用Python就可以轻松解决这5个常见运维!】

许多运维工程师会使用 Python 脚本来自动化运维任务。Python 是一种流行的编程语言&#xff0c;具有丰富的第三方库和强大的自动化能力&#xff0c;适用于许多不同的领域。 在运维领域&#xff0c;Python 脚本可以用来实现各种自动化任务&#xff0c;例如&#xff1a; 连接远…

Cyber RT学习笔记---7、Component组件认知与实践

7、Component组件认知与实践 前言 本文是对Cyber RT的学习记录,文章可能存在不严谨、不完善、有缺漏的部分&#xff0c;还请大家多多指出。 课程地址: https://apollo.baidu.com/community/course/outline/329?activeId10200 更多还请参考: [1] Apollo星火计划学习笔记——第…

网络渗透day12-高级问题2

当然&#xff0c;继续提供更多高级网络渗透测试问题和回答&#xff1a; 在渗透测试中&#xff0c;您如何评估目标系统的人工智能&#xff08;AI&#xff09;模型的隐私保护机制&#xff0c;以查找可能的隐私泄露和数据滥用风险&#xff1f; - 回答&#xff1a;我会分析AI模型的…

Web自动化 —— Selenium元素定位与防踩坑

1. 基本元素定位一 from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.by import By # selenium Service("../../chromedriver.exe") # driver webdriver.Chrome(serviceService) # driver.…

【Unity3D】UI Toolkit元素

1 前言 UI Toolkit简介 中介绍了 UI Builder、样式属性、UQuery、Debugger&#xff0c;UI Toolkit容器 中介绍了 VisualElement、ScrollView、ListView、GroupBox 等容器&#xff0c;UI Toolkit样式选择器 中介绍了简单选择器、复杂选择器、伪类选择器等样式选择器&#xff0c;…

宝塔面板linux在终端使用命令开启服务保持服务不关闭

我们经常在宝塔面板终端开启服务&#xff08;比如socket等服务时&#xff09;&#xff0c;如果关闭面板标签页或者关闭终端&#xff0c;服务也随之关闭了&#xff0c;要保持服务一直运行&#xff0c;就需要把终端进程放在linux后台执行&#xff0c;方法如下&#xff1a; 1、先…

Linux入门之进程信号|信号产生的方式

文章目录 一、信号入门 1.linux信号的基本概念 2.使用kill -l 命令可以查看系统定义的信号列表 3.信号处理常见方式 二、产生信号 1.通过终端按键产生信号 2.通过调用系统函数向进程发信号 3.由软条件产生信号 4.硬件异常产生信号 1. /0异常 2.模拟野指针 一、信号入门…

华为数通方向HCIP-DataCom H12-821题库(单选题:221-240)

第201题 BGP 协议用​​ beer default-route-advertise​​ 命令来给邻居发布缺省路由,那么以下关于本地 BGP 路由表变化的描述,正确的是哪一项? A、在本地 BGP 路由表中生成一条活跃的缺省路由并下发给路由表 B、在本地 BGP 路由表中生成一条不活跃的缺省路由,但不下发给…

【ES6】Promise.all用法

Promise.all()方法用于将多个 Promise 实例&#xff0c;包装成一个新的 Promise 实例。 const p Promise.all([p1, p2, p3]);上面代码中&#xff0c;Promise.all()方法接受一个数组作为参数&#xff0c;p1、p2、p3都是 Promise 实例&#xff0c;如果不是&#xff0c;就会先调…

Vue2+Vue3笔记(尚硅谷张天禹老师)day02

声明:只是记录&#xff0c;初心是为了让页面更好看,会有错误,我并不是一个会记录的人&#xff0c;所以有点杂乱无章的感觉&#xff0c;我先花点时间把视频迅速过掉&#xff0c;再来整理这些杂乱无章的内容 组件化编程 按照视频来的话&#xff0c;这里应该有一些概念的东西&…

Java设计模式之适配器模式

适配器模式&#xff08;Adapter Pattern&#xff09;是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式&#xff0c;它结合了两个独立接口的功能。 这种模式涉及到一个单一的类&#xff0c;该类负责加入独立的或不兼容的接口功能。举个真实的例子&#xff0…

数据结构零基础入门篇(C语言实现)

前言&#xff1a;数据结构属于C学习中较难的一部分&#xff0c;对应学习者的要求较高&#xff0c;如基础不扎实&#xff0c;建议着重学习C语言中的指针和结构体&#xff0c;万丈高楼平地起。 一&#xff0c;链表 1&#xff09;单链表的大致结构实现 用C语言实现链表一般是使…