Improved Performance with a Connection Pool

视觉特征-自监督-掩码特征预测【2024-10】:D-JEPA【生成模型:下一Token组自回归预测(组内并行去噪),自回归合成图像】【JEPA、Diffusion损失均针对Mask处Token计算】 Dengsheng Chen1 Jie Hu2 Xiaoming Wei1 Enhua Wu2∗1Meituan 2Key Laboratory of System Software (Chinese Academy of Sciences) and State Key Laboratory of Computer Science, Institute of Software, Chinese Academy of Sciences {chendengsheng, weixiaoming}@meituan. 阅读详情

Improved Performance with a Connection Pool

by Hans Bergsten

If you have heard anything about Servlets you know that one of the advantages over CGI is that a Servlet can keep information between requests and share common resources. This article describes one common use of this feature, namely a database connection pool.
September 01, 1999

A dynamic web site generates HTML pages from information stored in a database. Each request for a page results in a database access. But connecting to a database is a time consuming activity since the database must allocate communication and memory resources as well as authenticate the user and set up the corresponding security context. The exact time varies, of course, but it is not unusual to see connection times of one or two seconds. Establishing the connection once and then use the same connection for subsequent requests can therefore dramatically improve the performance of a database driven web application. Since Servlets can keep information between requests, a database connection pool is a straight forward solution.

A Servlet is a Java class. A Servlet Engine (native to the web server or a separate add-on module) loads the class in the Java Virtual Machine (JVM) process and creates one instance of the Servlet class at start-up or the first time the Servlet is requested. Each request for the Servlet is then executed in a separate thread using the same Servlet instance. The Servlet remains resident between requests and can keep persistent data in instance variables or in separate helper objects, such as connection pool objects.

The Java Database Connect API (JDBC) is supported by all major database vendors as well as many small databases. To access a database through JDBC you first open a connection to the database, resulting in a Connection object. A Connection object represents a native database connection and provides methods for executing SQL statements. The database connection pool described in this article consists of manager class that provides an interface to multiple connection pool objects. Each pool manages a set of JDBC Connection objects that can be shared by any number of Servlets.

The database connection pool class, DBConnectionPool, provides methods to

  • get an open connection from the pool,
  • return a connection to the pool,
  • release all resources and close all connections at shutdown.
It also handles connection failures, such as time-outs, communication failures, etc. and can limit the number of connections in the pool to a predefined max value.

The manager class, DBConnectionManager, is a wrapper around the DBConnectionPool class that manages multiple connection pools. It

  • loads and registers all JDBC drivers,
  • creates DBConnectionPool objects based on properties defined in a properties file,
  • maps connection pool names to DBConnectionPool instances,
  • keeps track of connection pool clients to shut down all pools gracefully when the last client is done.
The rest of this article describes each class in detail, starting with the DBConnectionPool class. You will also see an example of how a Servlet is using the connection pool. The complete source code for the DBConnectionManager and the DBConnectionPool is also available here.

The DBConnectionPool class

The DBConnectionPool class represents a pool of connections to one database. The database is identified with a JDBC URL. A JDBC URL consists of three parts: the protocol identifier (always jdbc), the driver identifier (e.g. odbc, idb, oracle, etc.) and the database identifier (the format is driver specific). As an example, jdbc:odbc:demo, is the JDBC URL for a database named demo accessed through the JDBC-ODBC bridge driver. The pool also has a name used by the clients and optionally a user name and password and a max connection limit. If you develop a web application where all users can execute some database operations but others are restricted to authorized users, you can define one pool for the general user and another pool for the restricted group using the same JDBC URL but different user names and passwords.

Constructor

The DBConnectionPool constructor takes all values described above as its parameters:
        public DBConnectionPool(String name, String URL, String user, 
                String password, int maxConn) {
            this.name = name;
            this.URL = URL;
            this.user = user;
            this.password = password;
            this.maxConn = maxConn;
        }
It saves all parameter values in its instance variables.

Get an open connection from the pool

The DBConnectionPool class provides two methods for checking out a connection. They both return an existing Connection if one is available, otherwise they create a new Connection. If no Connection is available and the max number of connections have been reached, the first method returns null but the other waits until an existing Connection is checked in.
        public synchronized Connection getConnection() {
            Connection con = null;
            if (freeConnections.size() > 0) {
                // Pick the first Connection in the Vector
                // to get round-robin usage
                con = (Connection) freeConnections.firstElement();
                freeConnections.removeElementAt(0);
                try {
                    if (con.isClosed()) {
                        log("Removed bad connection from " + name);
                        // Try again recursively
                        con = getConnection();
                    }
                }
                catch (SQLException e) {
                    log("Removed bad connection from " + name);
                    // Try again recursively
                    con = getConnection();
                }
            }
            else if (maxConn == 0 || checkedOut < maxConn) {
                con = newConnection();
            }
            if (con != null) {
                checkedOut++;
            }
            return con;
        }
All Connection objects in the pool are kept in a Vector, named freeConnections, when they are checked in. If there is at least one Connection in the Vector getConnection() picks the first one. As you will see later, Connections are added to the end of the Vector when they are checked in so picking the first ensures an even utilization to minimize the risk that the database disconnects a connection due to inactivity.

Before returning the Connection to the client, the isClosed() method is used to verify that the connection is okay. If the connection is closed, or an exception is thrown, the method calls itself again to get another connection.

If no Connection is available in the freeConnections Vector the method checks if the max connection limit is specified, and if so, if it's been reached. A maxConn value of 0 means "no limit". If no limit has been specified or the limit has not been reached, the method tries to create a new Connection. If it's successful, it increments the counter for the number of checked out connections and returns the Connection to the client. Otherwise it returns null.

The newConnection() method is used to create a new Connection. This is a private method that creates a Connection based on if a user name and a password have been specified or not.

        private Connection newConnection() {
            Connection con = null;
            try {
                if (user == null) {
                    con = DriverManager.getConnection(URL);
                }
                else {
                    con = DriverManager.getConnection(URL, user, password);
                }
                log("Created a new connection in pool " + name);
            }
            catch (SQLException e) {
                log(e, "Can't create a new connection for " + URL);
                return null;
            }
            return con;
        }
The JDBC DriverManager provides a set of getConnection() methods that takes a JDBC URL plus other parameters, for instance a user name and a password. The DriverManager uses the URL to locate a JDBC driver matching the database and opens a connection.

The second getConnection() method takes a time-out parameter, with a value in milliseconds for how long the client is willing to wait for a connection. It's implemented as a wrapper around the first getConnection() method:

        public synchronized Connection getConnection(long timeout) {
            long startTime = new Date().getTime();
            Connection con;
            while ((con = getConnection()) == null) {
                try {
                    wait(timeout);
                }
                catch (InterruptedException e) {}
                if ((new Date().getTime() - startTime) >= timeout) {
                    // Timeout has expired
                    return null;
                }
            }
            return con;
        }
The local startTime variable is initialized with the current time. A while loop first try to get a connection. If it fails, wait() is called with the the number of milliseconds we are prepared to wait. wait() returns either when another thread calls notify() or notifyAll(), as you will see later, or when the time has elapsed. To figure out if wait() returned due to a time-out or a notification, the start time is subtracted from current time and if the result is greater than the time-out value the method returns null. Otherwise getConnection() is called again.

Return a connection to the pool

The DBConnectionPool class also provides a method for returning a connection to the pool. The freeConnection() method takes the returned Connection object as its parameter.
        public synchronized void freeConnection(Connection con) {
            // Put the connection at the end of the Vector
            freeConnections.addElement(con);
            checkedOut--;
            notifyAll();
        }
The Connection is added to the end of the freeConnections Vector and the counter for number of checked out connections is decremented. The notifyAll() is called to notify other clients waiting for a connection.

Shutdown

Most Servlet Engines provide some method for graceful shutdown. The database connection pools need to be notified about this event so that all connections can be closed correctly. The DBConnectionManager class is responsible for coordinating the shutdown but it's the DBConnectionPool class that closes all connections in the pool. The release() method is called by the DBConnectionManager.
        public synchronized void release() {
            Enumeration allConnections = freeConnections.elements();
            while (allConnections.hasMoreElements()) {
                Connection con = (Connection) allConnections.nextElement();
                try {
                    con.close();
                    log("Closed connection for pool " + name);
                }
                catch (SQLException e) {
                    log(e, "Can't close connection for pool " + name);
                }
            }
            freeConnections.removeAllElements();
        }
This method loops through the freeConnections Vector and closes all Connections. When all Connections have been closed they are removed from the Vector.

The DBConnectionManager class

The DBConnectionManager class is implemented according to the Singleton pattern described in many design books. A Singleton is a class with just one instance. Other objects can get a reference to the single instance through a static method (class method).

Constructor and getInstance()

The DBConnectionManager constructor is private to prevent other objects to create instances of the class.
    private DBConnectionManager() {
        init();
    }
Clients of the DBConnectionManager calls the getInstance() method to get a reference to the single instance.
    static synchronized public DBConnectionManager getInstance() {
        if (instance == null) {
            instance = new DBConnectionManager();
        }
        clients++;
        return instance;
    }
The single instance is created the first time this method is called and a reference is then kept in the static variable named instance. A counter for the number of DBConnectionManager clients is incremented before the reference is returned. This counter is later used to coordinate the shutdown of the pools.

Initialization

The constructor calls a private method called init() to initialize the object.
    private void init() {
        InputStream is = getClass().getResourceAsStream("/db.properties");
        Properties dbProps = new Properties();
        try {
            dbProps.load(is);
        }
        catch (Exception e) {
            System.err.println("Can't read the properties file. " +
                "Make sure db.properties is in the CLASSPATH");
            return;
        }
        String logFile = dbProps.getProperty("logfile", 
            "DBConnectionManager.log");
        try {
            log = new PrintWriter(new FileWriter(logFile, true), true);
        }
        catch (IOException e) {
            System.err.println("Can't open the log file: " + logFile);
            log = new PrintWriter(System.err);
        }
        loadDrivers(dbProps);
        createPools(dbProps);
    }
The getResourceAsStream() method is a standard method for locating an external file and open it for input. How the file is located depends on the class loader but the standard class loader for local classes searches for the file in the CLASSPATH, starting in the directory where the class file is located. The db.properties file is a file in the Properties format containing key-value pairs that define the connection pools. The following common properties can be defined:
drivers  A space separated list of JDBC driver class names
logfile  The absolute path for a log file

Another set of properties are used for each pool. The property name starts with the name of the connection pool:

<poolname>.url  The JDBC URL for the database
<poolname>.maxconn  The max number of connections in the pool. 0 means no limit.
<poolname>.user  The user name for the pool
<poolname>.password  The corresponding password

The url property is mandatory but all the others are optional. The user name and the matching password must be valid for the database defined by the URL.

Below is an example of a db.properties file for a Windows platform, with one pool for an InstantDB database and one pool for an MS Access database accessed through an ODBC Data Source Name (DSN) demo.

drivers=sun.jdbc.odbc.JdbcOdbcDriver jdbc.idbDriver
logfile=D://user//src//java//DBConnectionManager//log.txt

idb.url=jdbc:idb:c://local//javawebserver1.1//db//db.prp
idb.maxconn=2

access.url=jdbc:odbc:demo
access.user=demo
access.password=demopw
Note that the backslashes (/) in a Windows path must be duplicated since a backslash in a properties file is also used as an escape character.

The init() method creates a Properties object and loads the db.properties file. It then reads the logfile property. If a log file hasn't been specified a file named DBConnectionManager.log in the current directory is used instead. As a last resort, System.err is used for log messages.

The loadDrivers() method loads and registers all JDBC drivers specified by the drivers property.

    private void loadDrivers(Properties props) {
        String driverClasses = props.getProperty("drivers");
        StringTokenizer st = new StringTokenizer(driverClasses);
        while (st.hasMoreElements()) {
            String driverClassName = st.nextToken().trim();
            try {
                Driver driver = (Driver) 
                    Class.forName(driverClassName).newInstance();
                DriverManager.registerDriver(driver);
                drivers.addElement(driver);
                log("Registered JDBC driver " + driverClassName);
            }
            catch (Exception e) {
                log("Can't register JDBC driver: " +
                    driverClassName + ", Exception: " + e);
            }
        }
    }
loadDrivers() uses a StringTokenizer to split the drivers property value into a string for each driver class name and and then loops through all class names. Each class is loaded into the JVM and an instance is created. The instance is then registered with the JDBC DriverManager and added to a private Vector. The drivers Vector is used at shutdown to deregister all drivers from the DriverManager.

Next the DBConnectionPool objects are created by the private createPools() method.

    private void createPools(Properties props) {
        Enumeration propNames = props.propertyNames();
        while (propNames.hasMoreElements()) {
            String name = (String) propNames.nextElement();
            if (name.endsWith(".url")) {
                String poolName = name.substring(0, name.lastIndexOf("."));
                String url = props.getProperty(poolName + ".url");
                if (url == null) {
                    log("No URL specified for " + poolName);
                    continue;
                }
                String user = props.getProperty(poolName + ".user");
                String password = props.getProperty(poolName + ".password");
                String maxconn = props.getProperty(poolName + ".maxconn", "0");
                int max;
                try {
                    max = Integer.valueOf(maxconn).intValue();
                }
                catch (NumberFormatException e) {
                    log("Invalid maxconn value " + maxconn + " for " + 
                        poolName);
                    max = 0;
                }
                DBConnectionPool pool = 
                    new DBConnectionPool(poolName, url, user, password, max);
                pools.put(poolName, pool);
                log("Initialized pool " + poolName);
            }
        }
    }
An Enumeration of all property names is created and scanned for property names ending with .url. When such a property is found, the pool name is extracted, all properties for the corresponding connection pool are read and a DBConnectionPool object is created and saved in an instance variable named pools. pools is a Hashtable, using the pool name as the key and the DBConnectionPool object as the value.

Get and return a connection

The DBConnectionManager provides the getConnection() and freeConnection() methods used by the clients. All of them take a pool name parameter and relay the call to the corresponding DBConnectionPool object.
    public Connection getConnection(String name) {
        DBConnectionPool pool = (DBConnectionPool) pools.get(name);
        if (pool != null) {
            return pool.getConnection();
        }
        return null;
    }
    
    public Connection getConnection(String name, long time) {
        DBConnectionPool pool = (DBConnectionPool) pools.get(name);
        if (pool != null) {
            return pool.getConnection(time);
        }
        return null;
    }

    public void freeConnection(String name, Connection con) {
        DBConnectionPool pool = (DBConnectionPool) pools.get(name);
        if (pool != null) {
            pool.freeConnection(con);
        }
    }

Shutdown

Finally, the DBConnectionManager has a method called release(). This method is used for graceful shutdown of the connection pools. Each DBConnectionManager client must call the static getInstance() method to get a reference to the manager. As you could see above, a client counter variable is used in this method to keep track of the number of clients. The release() method is called by each client during shutdown and the client counter is decremented. When the last client calls release(), the DBConnectionManager calls release() on all DBConnectionPool objects to close all connections.
    public synchronized void release() {
        // Wait until called by the last client
        if (--clients != 0) {
            return;
        }
        
        Enumeration allPools = pools.elements();
        while (allPools.hasMoreElements()) {
            DBConnectionPool pool = (DBConnectionPool) allPools.nextElement();
            pool.release();
        }
        Enumeration allDrivers = drivers.elements();
        while (allDrivers.hasMoreElements()) {
            Driver driver = (Driver) allDrivers.nextElement();
            try {
                DriverManager.deregisterDriver(driver);
                log("Deregistered JDBC driver " + driver.getClass().getName());
            }
            catch (SQLException e) {
                log(e, "Can't deregister JDBC driver: " + 
                    driver.getClass().getName());
            }
        }
    }
When all DBConnectionPool objects have been released, all JDBC drivers are deregistered.

Example of a Servlet using the connection pool

The Servlet API defines a Servlet's life cycle like this:
  1. Servlet is created then initialized (the init() method).
  2. Zero or more service calls from clients are handled (the service() method).
  3. Servlet is destroyed then garbage collected and finalized (the destroy() method).
A Servlet using the connection pool described in this article typically performs the following actions in these methods:
  1. in init(), calls DBConnectionManager.getInstance() and saves the reference in an instance variable.
  2. in service(), calls getConnection(), performs all database operations, and returns the Connection to the pool with freeConnection().
  3. in destroy(), calls release() to release all resources and close all connections.
The following is an example of a simple Servlet using the connection pool classes this way.
import java.io.*;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class TestServlet extends HttpServlet {
    private DBConnectionManager connMgr;
    
    public void init(ServletConfig conf) throws ServletException {
        super.init(conf);
        connMgr = DBConnectionManager.getInstance();
    }
    
    public void service(HttpServletRequest req, HttpServletResponse res) 
            throws IOException {

        res.setContentType("text/html");
        PrintWriter out = res.getWriter();
        Connection con = connMgr.getConnection("idb");
        if (con == null) {
            out.println("Can't get connection");
            return;
        }
        ResultSet rs = null;
        ResultSetMetaData md = null;
        Statement stmt = null;
        try {
            stmt = con.createStatement();
            rs = stmt.executeQuery("SELECT * FROM EMPLOYEE");
            md = rs.getMetaData();
            out.println("<H1>Employee data</H1>");
            while (rs.next()) {
                out.println("<BR>");
                for (int i = 1; i < md.getColumnCount(); i++) {
                    out.print(rs.getString(i) + ", ");
                }
            }
            stmt.close();
            rs.close();
        }
        catch (SQLException e) {
            e.printStackTrace(out);
        }
        connMgr.freeConnection("idb", con);
    }
    
    public void destroy() {
        connMgr.release();
        super.destroy();
    }
} 

Class loader considerations

Most Servlet Engines use a special class loader for Servlets to be able to automatically reload a Servlet when it is modified. This class loader handles all class files located in a special directory, typically named servlets. A common mistake among new Servlet developers is to also put helper classes, such as the connection pool classes described here, in the servlets directory. This doesn't work at all when static variables are involved since the special class loader creates a separate class instance for each Servlet. To avoid this problem you should place all helper classes in the regular CLASSPATH used by the Servlet Engine. How you set the CLASSPATH varies between Servlet Engines so read the documentation for the product you use.
视觉特征-自监督-掩码特征预测【2026-03】:V-JEPA2.1【2B】【全Token稠密预测损失】【多层深度自监督】【图像/视频多模态Tokenizer】【160万小时视频】【1.42亿张图像】 Lorenzo Mur-Labadia1,2,∗, Matthew Muckley1, Amir Bar1, Mido Assran1, Koustuv Sinha1, Mike Rabbat1, Yann LeCun1, Nicolas Ballas1,†, Adrien Bardes1,†1FAIR at Meta, 2Universidad de Zaragoza ∗Work done at Meta, †Joint last authorWe present V-JEPA 2.1, a family 阅读详情

相关推荐

视觉特征-自监督-掩码特征预测【2024-04】:V-JEPA【潜空间】【≈90%多块时空掩码】【上下文目标块预测】【特征空间预测≠像素重建】【EMA目标编码器+停梯度】

Adrien Bardes 1,2,3, Quentin Garrido 1,4, Jean Ponce 3,5,6, Xinlei Chen 1, Michael Rabbat 1, Yann LeCun 1,5,6, Mahmoud Assran 1,†, Nicolas Ballas 1,† 1 FAIR at Meta, 2 Inria, 3 École normale supérieure, CNRS, PSL Research University, 4 Univ. Gustave Eiffel

u013250861的博客 245

java escape html_慎用StringEscapeUtils.escapeHtml方法【转】

推荐使用Apache commons-lang的StringUtils来增强Java字符串处理功能,也一直在项目中大量使用StringUtils和StringEscapeUtils这两个实用类。最近在数据库里发现某个表的内容全都成了HTML entity表示,中文也全被转换成了”我”这样的格式,而在页面上显示一切正常。最终发现造成这个后果的原因是在将字符串保存到 数据库之前,用StringEsca...

weixin_35218304的博客 2289

2021.02.03丨quast报错module ‘cgi‘ has no attribute ‘escape‘解决办法

最近采购了新服务器,在上面第一次跑组装,按正常流程要进行组装评估,在使用quast的过程中发生了报错,报错如下: 抓重点,问题在于cgi.escape,里面其实有提示,‘html’:cgi.escape, 解决方法: 根据报错路径,找到最后一个报错文件 /home/yangxin/miniconda3/lib/python3.8/site-packages/quast-5.0.2-py3.8.egg/quast_libs/site_packages/jsontemplate/jsontemplat

3470

使用Servlet实现重定向到另一个Servlet文件下载服务端下载

场景:使用Servlet实现重定向到另一个Servlet文件下载服务端下载,重定向的Servlet只做验证处理功能,        而实际下载功能是内部服务。 1.创建一个spring的web项目,确保可正常运行。 2.实现一个Servlet文件下载服务端   可参考: 使用Servlet实现文件下载服务端 3.实现一个重定向Servlet   本例是DownloadRedirectServlet...

zhangbeizhen18的博客 1701

【信息科学与工程学】【通信工程】第一百五十五篇 网络拓扑学10

编号类型领域问题问题的数学分析(拓扑学+其他)参数列表及参数的数值范围关联知识A401图论/拓扑量子纠缠计算+存储+网络融合(全域共享内存)如何用GHZ纠缠态优化全域共享内存的原子广播?​1. 拓扑学分析(详细): - 拓扑纠缠视角:全域共享内存(如CXL.mem)需要原子广播以保证一致性。GHZ纠缠态GHZ⟩ = (0...0⟩+A402图论/拓扑序计算+存储融合(近存储计算)如何用拓扑序的长程纠缠优化近存储计算的数据一致性?​1. 拓扑学分析(详细): - 拓扑序视角:近存储计算(Near-

weixin_49199313的博客 329

产业园区在推动科技成果转化过程中,如何实现企业与高校的精准对接?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

Java 重写ServletResponse中的内容

Java 重写ServletResponse中的内容 ,修改response中的内容

我就是我不一样的美男子! 6393

项目实战:用西门子S7协议开发基于PLC的上位机.pdf

项目实战:用西门子S7协议开发基于PLC的上位机.pdf

Improved Performance with a Connection Pool (转)

Improved Performance with a Connection Pool by Hans Bergsten If you have heard anything about Servlets you know that one of the advantages over CGI is that a Servlet can keep information between req

J2nix的笔记 868

该数据集收录了国内主要期货商品和股指指数的日频行情 商品期货覆盖有色、黑色、能化、农产品等板块,包含铜、螺纹钢、原油、豆粕等活跃合约 股指指数部分涵盖沪深300、上证50、中证500等品种 每个品种提

该数据集收录了国内主要期货商品和股指指数的日频行情。商品期货覆盖有色、黑色、能化、农产品等板块,包含铜、螺纹钢、原油、豆粕等活跃合约。股指指数部分涵盖沪深300、上证50、中证500等品种。每个品种提供统一字段:合约代码、交易日期、开盘价、最高价、最低价、收盘价、结算价、成交量和持仓量。数据按交易日顺次排列,未做复权处理,直接反映交易所原始发布信息。 数据源:CMES金融数据库

KernelSU.zip

KernelSU.zip

MySQL Install之基础知识

MySQL的基础操作安装MySQL服务删除MySQL服务MySQL启动用mysqld命令启动以服务的方式启动启动异常MySQL停止客户端连接 安装MySQL服务 MySQL8 是服务名,在Windows服务中则生成一个MySQL8,后续可以通过mysql命令操作该服务。 D:\mysql\bin> mysqld -install MySQL8 --defaults-file="D:\mysql\my.ini" 删除MySQL服务 D:\mysql-8.0.21-winx64\bin> mysq

MyFreeIT 920

产业园区运营负责人如何精准匹配产业需求与科技成果?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

Grok 4.5 AI编程助手:速度与成本双优的工程实践指南

AI编程助手作为现代软件开发的重要工具,通过深度学习技术理解代码语义和编程逻辑。其核心原理基于大规模代码库训练,能够根据上下文生成符合语法规范的代码片段。在技术价值层面,AI编程助手显著提升开发效率,减少重复性编码工作,降低人为错误率。特别是在代码自动补全、错误检测和算法实现等应用场景中表现突出。Grok 4.5作为新一代AI编程工具,在模型架构优化和推理引擎改进方面实现突破,将响应速度控制在1-3秒内,同时保持合理的成本结构。该工具支持Python、JavaScript等主流语言,在代码生成质量和上下文感

weixin_33672109的博客 485

单相PWM整流器基于直流电流控制+虚拟dq两种闭环控制仿真【2个仿真+参考资料】

内容概要:本文介绍了单相PWM整流器的两种闭环控制策略仿真研究,即基于直流电流控制和虚拟dq变换的闭环控制方法。资源包含两个独立的Simulink仿真模型及相关参考资料,旨在对比和分析两种控制策略在动态响应、稳态精度及抗干扰能力等方面的性能差异。通过构建完整的主电路、控制回路与信号处理模块,展示了如何实现单位功率因数运行、直流侧电压稳定控制以及交流侧电流正弦化等关键目标,适用于电力电子变换器控制系统的学习与科研验证。; 适合人群:电气工程、自动化及相关专业的研究生、科研人员以及从事电力电子与新能源系统开发的工程师,具备一定的电路理论、自动控制原理和Simulink仿真基础者更佳。; 使用场景及目标:①深入理解单相PWM整流器的工作原理及其闭环控制机制;②掌握直流电流控制与虚拟dq控制两种方法的设计思路与实现步骤;③为相关课题的仿真建模、算法优化与论文写作提供参考依据和技术支持; 阅读建议:建议结合仿真模型与参考资料同步学习,重点分析控制器参数整定过程、坐标变换环节的实现方式,并尝试修改负载条件或输入扰动以测试系统鲁棒性,从而加深对控制策略本质的理解。

红日-VulnStack靶场-ATT&CK(二):从Weblogic漏洞到域控渗透实战

本文详细解析了红日安全团队VulnStack靶场中从Weblogic漏洞到域控渗透的完整攻击链。通过实战演示Weblogic反序列化漏洞利用、Cobalt Strike持久化控制、域内信息收集及PsExec横向移动等关键技术,复现了企业内网渗透的典型场景,并提供了防御建议。

tgb3456789的博客 936

如何高效配置反检测浏览器绕过网站防护:实战配置与高级策略

在当今数据驱动的商业环境中,网站防护系统日益复杂,传统的爬虫技术面临着严峻的指纹检测挑战。**Camoufox反检测浏览器**通过C++层面的指纹轮换技术,在浏览器内核级别实现无法被JavaScript检测的指纹伪装,为数据采集工程师提供了突破网站防护的有效解决方案。本项目采用模块化设计,结合Firefox定制浏览器核心与指纹注入技术,显著提升了网络数据采集的成功率和稳定性。 ## 问题场景:当

gitblog_00062的博客 722

JS自动化生成大疆WPML航线文件实战(附完整代码与云台控制解析)

本文详细介绍了如何利用JavaScript自动化生成大疆WPML航线文件,以解决手动规划航线效率低、易出错的问题。通过解析WPML文件结构,特别是云台控制等核心参数,并封装可复用的JS模板函数,开发者能够快速批量生成复杂航线,如倾斜摄影五向飞行,实现航测与巡检任务的标准化与高效执行。

weixin_29007243的博客 299

Free LLM Balancer:构建高可用大语言模型服务的智能调度方案

负载均衡是分布式系统中的核心技术概念,通过智能分配请求到多个服务节点来提升系统整体性能。其核心原理基于健康检查、路由决策和故障转移机制,确保服务的高可用性和稳定性。在AI应用领域,负载均衡技术能有效解决大语言模型服务的成本控制、性能优化和数据安全等关键问题。随着本地部署与云端API混合架构的普及,智能调度层成为平衡资源利用与服务质量的重要组件。Free LLM Balancer方案通过动态权重调整和熔断机制,实现了本地推理集群与云端降级服务的无缝切换,为生产环境提供了可靠的LLM服务保障。该方案特别适用于需

congjukun0600的博客 401

计算机视觉:AI生成内容(AIGC)对视觉领域的冲击

计算机视觉:AI生成内容(AIGC)对视觉领域的冲击​ 人工智能,计算机视觉,大模型,AI,在信息技术日新月异的当下,计算机视觉作为人工智能领域的关键分支,已经深度融入了我们生活与工作的各个层面。从安防监控系统里精准的人脸识别,助力维护公共安全;到工业生产线上高效的产品质量检测,保障产品品质;再到医疗影像分析中为疾病诊断提供有力支持,计算机视觉技术凭借其对视觉信息的强大处理与理解能力,不断推动着各行业的发展与变革。

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 17万+

YOLO26改进策略【YOLO和Mamba】| CVPR 2025:EfficientViM 压缩隐藏状态空间进行通道混合、单头设计减少内存操作,提升目标检测效率与精度

本文记录的是利用模块优化的目标检测网络模型。EfficientViM Block(基于隐藏状态混合器的状态空间对偶性模块) 的设计旨在,提升特征提取效率,同时兼顾全局依赖捕捉与局部细节保留。本文将深入研究的原理,并将其应用到中,通过重构特征提取流程、减少内存绑定操作、融合多阶段特征,增强模型在资源受限环境下的检测性能与速度。EfficientViM: Efficient Vision Mamba with Hidden State Mixer based State Space DualityEfficie

Limiiiing的博客 399

设置ODBC的自定义类CSetODBC

何志丹一,功能描述用于配置数据源用户名及密码.1,可以得到连接串,此串可用于CMyRecordset(派生于CRecordset)的GetDefaultConnect(),也可以用干CDataBase类OpenEx.2,如果用户配置正确,只需要配置一次,相关信息记录在文件.3,可以指定存储信息的文件名.因为有可能几个程序共用一个数据源.4,用户可以重新配置数据5,可以得到当前数据的类型.6

闻缺陷则喜何志丹 3139

DevExpress中使用BandGridView实现复合(多行)表头、设置多行表头背景颜色、表格边框颜色

一、实现效果 二、 实现方法 2.1、创建复合表头 ①将创建的GridControl下的GirdView1转化为BandGridView类型; ②创建需要展示的列(指定列的名称【Name】、描述【caption】、数据字段名称【FieldName】) ③绑定列实现复合表头。 注意:如果复合表头有多行,则需要设置新增Band的Row Count,然后设置【Band properties下的AutoFillDown=false】 详细操作如下: 注意:如果要隐藏表格的设计字段内容,则需.

提供C#相关开发 、云计算、运维测试、网络安全相关技术分享与服务,有意向可联系。 2895
上一篇: 超强存储过程!
leebons
博客等级 码龄26年 0粉丝 2原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值