рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд▓рд┐рдП рдХрдиреЗрдХреНрд╢рди рдХреЗ рдкреВрд▓ - рдХреНрдпреЛрдВ рдФрд░ рдХреНрдпреЛрдВ

рдЬрдм рдЖрдкрдХреА рдкрд░рд┐рдпреЛрдЬрдирд╛ рд▓реЛрдХрдкреНрд░рд┐рдп рд╣реЛрдиреЗ рд▓рдЧрддреА рд╣реИ рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реЗ рдЕрдиреБрд░реЛрдз рдХреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдорд┐рд▓реАрд╕реЗрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдмрд╛рдзрд╛рдУрдВ рдХреА рддрд▓рд╛рд╢ рдХрд░рдиреА рд╣реЛрдЧреАред рдЕрдХреНрд╕рд░ рдбреЗрдЯрд╛рдмреЗрд╕ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕реЗ SQL рдХреНрд╡реЗрд░реА рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХрд╛ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдордп рд▓рдЧрддрд╛ рд╣реИред рдЖрдЗрдП рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ рдХрд┐ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп рдХрд╛рд░реНрдпрдХреНрд░рдо рдореЗрдВ рдХреНрдпрд╛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рд╕рд┐рджреНрдзрд╛рдВрдд


рдПрдХ рдмреЗрд╣рддрд░ рд╕рдордЭ рдХреЗ рд▓рд┐рдП, рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ рдХрд┐ рдЬрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдХреНрд╡реЗрд░реА рдХрд░рддрд╛ рд╣реИ, рддреЛ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХреНрд╡реЗрд░реА рдХреНрдпрд╛ рд╣реИ:
  1. рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд▓рд┐рдП рдПрдХ рдХрдиреЗрдХреНрд╢рди рдЦреЛрд▓рдирд╛ рдФрд░ рд╕рд░реНрд╡рд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдиреБрд░реЛрдз рднреЗрдЬрдирд╛ред
  2. рд╕рд░реНрд╡рд░ SQL рдХреНрд╡реЗрд░реА рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рддрд╛ рд╣реИред
  3. рд╕рд░реНрд╡рд░ рдирд┐рдпрдореЛрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдХреНрд╡реЗрд░реА рдХрд╛ рдЕрдиреБрдХреВрд▓рди рдХрд░рддрд╛ рд╣реИ, рд╕рд╛рде рд╣реА рд╕рд╛рде рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдкрд░ рдЖрдВрдХрдбрд╝реЗ рднреАред рдирддреАрдЬрддрди, рдПрдХ рдХреНрд╡реЗрд░реА рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЬрдирд╛ рдмрдирд╛рдИ рдЧрдИ рд╣реИред
  4. рд╕рд░реНрд╡рд░ рдкрд╣рд▓реЗ рд╕реЗ рдмрдирд╛рдИ рдЧрдИ рдпреЛрдЬрдирд╛ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдЕрдиреБрд░реЛрдз рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдкрд░рд┐рдгрд╛рдо рднреЗрдЬрддрд╛ рд╣реИред

рдЖрдк рд╕рдордп рдХреИрд╕реЗ рдмрдЪрд╛ рд╕рдХрддреЗ рд╣реИрдВ?
рд╕рд░реНрд╡рд░ рд╕реЗ рдХрдиреЗрдХреНрд╢рди рдЦреЛрд▓рдиреЗ рдХрд╛ рдкрд╣рд▓рд╛ рдЪрд░рдг рдХрд╛рдлреА рд▓рдВрдмрд╛ рд╣реИ рдФрд░ рд╣рдо рдЗрд╕реЗ рдкрд╣рд▓реЗ рд╕реЗ рдЦреБрд▓реЗ рдХрдиреЗрдХреНрд╢рдиреЛрдВ рдХрд╛ рдПрдХ рдкреВрд▓ рддреИрдпрд╛рд░ рдХрд░рдХреЗ рдФрд░ рдЖрд╡реЗрджрди рд╕реЗ рдЖрд╡рд╢реНрдпрдХрддрд╛рдиреБрд╕рд╛рд░ рдХрдиреЗрдХреНрд╢рди рдкреНрд░рджрд╛рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдпрджрд┐ рд╣рдо рдкреНрд░рд╢реНрди рд▓рд┐рдЦрддреЗ рд╕рдордп рд╕рдВрдмрдВрдзрд┐рдд рдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЪрд░рдг рддреАрди рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдХреИрд╢ рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рд╣рдореЗрдВ рд╕рд░реНрд╡рд░ рд╕реЗ рдорд┐рд▓рддрд╛ рд╣реИ, рддреЛ рдЪрд░рдг рджреЛ рдФрд░ рддреАрди рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рд╕реЗ рдмрдЪрдирд╛ рднреА рд╕рдВрднрд╡ рд╣реИред

рд╡рд░реНрддрдорд╛рди рдореЗрдВ, рдХрдиреЗрдХреНрд╢рди рдкреВрд▓ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рд╕рдорд░реНрдерди рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХрд╛рдВрд╢ рдбреНрд░рд╛рдЗрд╡рд░ред рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╣рдореЗрд╢рд╛ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдкреНрд░рд▓реЛрднрди рд╣реЛрддрд╛ рд╣реИ, рдЬреЛ рддреЗрдЬреА рд╕реЗ рдХрд╛рдо рдХрд░реЗрдЧрд╛ред рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рд╣рдо рдХрдиреЗрдХреНрд╢рди рд╡рд╛рд▓реЗ рдкреВрд▓ рдФрд░ рдХреИрд╢рд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рддрдирд╛ рдЬреАрддреЗрдВрдЧреЗ, рджреЛрдиреЛрдВ рдПрдХ рдмреЙрдХреНрд╕рд┐рдВрдЧ рд╕рдорд╛рдзрд╛рди рдФрд░ рдПрдХ рд╕реНрд╡-рд▓рд┐рдЦрд┐рдд рдореЗрдВред

рдорд╛рдкрдиреЗ рдХреА рд╡рд┐рдзрд┐


рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд▓рд┐рдП, рд╣рдо рдирд┐рд╢реБрд▓реНрдХ PostgreSQL DBMS рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рд╣рдо рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рдЬрд╛рд╡рд╛ рдореЗрдВ рд▓рд┐рдЦреЗрдВрдЧреЗред рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ, рдкреНрд░рд╛рдердорд┐рдХ рдХреБрдВрдЬреА рдЖрдИрдбреА рдФрд░ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдорд╛рди рдорд╛рди рд╕реЗ рдорд┐рд▓рдХрд░ рдПрдХ рдЫреЛрдЯреА рддрд╛рд▓рд┐рдХрд╛ test.test_table (рд▓рдЧрднрдЧ 10 рдкрдВрдХреНрддрд┐рдпрд╛рдБ) рдмрдирд╛рдПрдБред рд╣рдорд╛рд░реЗ рдЧреНрд░рд╛рд╣рдХ рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ рдбреЗрдЯрд╛рдмреЗрд╕ рдкрд░ рдкреНрд░рд╢реНрдиреЛрдВ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рдХреЗ рд▓рд┐рдП рд╣рдо рдереНрд░реЗрдб рдмрдирд╛рдПрдВрдЧреЗ рдЬреЛ рдЗрд╕ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдкреНрд░рд╛рдердорд┐рдХ рдХреБрдВрдЬреА рдХреЗ рд▓рд┐рдП рд╕рд░рд▓ рдЦреЛрдЬ рдХрд░реЗрдВрдЧреЗред рдзрд╛рдЧреЗ рдмрдирд╛рддреЗ рд╕рдордп, рд╣рдо рдХрдиреЗрдХреНрд╢рди рдкреВрд▓ рдХреЗ рд╡рд┐рднрд┐рдиреНрди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░реЗрдВрдЧреЗ, рдЬреЛ рд╣рдореЗрдВ рдкреНрд░рджрд░реНрд╢рди рдХреА рддреБрд▓рдирд╛ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдереНрд░реЗрдб 100 рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдкрд░ рдЦрд░реНрдЪ рдХрд┐рдП рдЧрдП рдХреБрд▓ рд╕рдордп рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдЧрд╛ред

class TestThread extends Thread { private DBPool pool; private long workTime = 0; private long foundStr = 0; @Override public void run() { workTime = System.currentTimeMillis(); //   Connection con = null; PreparedStatement st = null; ResultSet rs = null; Random rnd = new Random();//        for (int i = 0; i < 100; i++) { try { con = pool.getConnection();//     //         st = con.prepareStatement("SELECT a.* FROM test.test_table a WHERE id =?"); st.setObject(1, rnd.nextInt(10)); rs = st.executeQuery();//   if (rs.next()) { String tmp = (rs.getString(2)); //   if (tmp != null) { foundStr++; } } } catch (SQLException ex) { //  ,    System.out.println("Pool " + pool + " exeption " + ex); } finally { //   ,       try { if (rs != null) rs.close(); } catch (SQLException e) { //ignore } try { if (st != null) st.close(); } catch (SQLException e) { //ignore } try { if (con != null) pool.putConnection(con); //      } catch (SQLException e) { //ignore } } } workTime = System.currentTimeMillis() - workTime; //    } } 

рдЕрдм рдХреБрдЫ рдкреВрд▓ рдмрдирд╛рддреЗ рд╣реИрдВ, рдФрд░ рдкреНрд░рджрд░реНрд╢рди рдХреА рддреБрд▓рдирд╛ рдХрд░рддреЗ рд╣реИрдВред
рдкрд╣рд▓рд╛ рдХреНрд▓рд╛рд╕рд┐рдХ рдПрдХ рд╣реЛрдЧрд╛, рдЬреЛ рдкреНрд░рддреНрдпреЗрдХ рдЕрдиреБрд░реЛрдз рдХреЗ рд▓рд┐рдП рд╕рд░реНрд╡рд░ рд╕реЗ рдПрдХ рдХрдиреЗрдХреНрд╢рди рдЦреЛрд▓рддрд╛ рд╣реИ рдФрд░ рдЕрдиреБрд░реЛрдз рдкреВрд░рд╛ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рдЗрд╕реЗ рдмрдВрдж рдХрд░ рджреЗрддрд╛ рд╣реИред
  class DBPool { private String url, user, password; DBPool(String url, String user, String password) throws ClassNotFoundException { this.url = url; this.user = user; this.password = password; Class.forName("org.postgresql.Driver"); } public Connection getConnection() throws SQLException { return DriverManager.getConnection(url, user, password); } public void putConnection(Connection connection) throws SQLException { connection.close(); } } 

рджреВрд╕рд░рд╛ JDBC рдбреНрд░рд╛рдЗрд╡рд░ рд╕реЗ PostgreSQL - PGPoolingDataSource рддрдХ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдХреИрд╢рд┐рдВрдЧ рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд рд╡рд░реНрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЬреЛ рдЖрдкрдХреЛ рдХрдиреЗрдХреНрд╢рди рдкреВрд▓ рдХрд╛ рдЖрдХрд╛рд░, рд╕рд╛рде рд╣реА рдХрдиреЗрдХреНрд╢рди рдХреА рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╕рдВрдЦреНрдпрд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдореЗрдВ, ReadyedStatement рдореЗрдВ рдПрдХ рд╕реЗрдЯрдкреНрд░реАрдкрд░рдереНрд░реЗрд╢реЛрд▓реНрдб рд╕реЗрдЯрд┐рдВрдЧ рд╣реЛрддреА рд╣реИ - рдЬреЛ рдЕрдиреБрд░реЛрдз рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛрдиреЗ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реЛрддреА рд╣реИ, рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рдЕрдиреБрд░реЛрдз рдХреЛ рдХреИрд╢ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЬрдирд╛ рдмрдирд╛рдиреЗ рдпрд╛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред
  class DBPoolCache extends DBPool { private PGPoolingDataSource source; DBPoolCache(String host, String database, String user, String password) { source = new PGPoolingDataSource(); source.setDataSourceName("A Data Source"); source.setServerName(host); source.setDatabaseName(database); source.setUser(user); source.setPassword(password); source.setMaxConnections(20);//  source.setInitialConnections(20);//     } public Connection getConnection() throws SQLException { return source.getConnection(); } public void putConnection(Connection connection) throws SQLException { connection.close(); } } 

рдЦреИрд░, рдЕрдВрдд рдореЗрдВ, рдкреВрд▓ рдХреЗ рд╣рдорд╛рд░реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди, рдЬрдм рд╣рдо рдЦреБрдж рдХреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдХрдиреЗрдХреНрд╢рди рдХреЗ рд╕рд╛рде-рд╕рд╛рде SQL рдХреНрд╡реЗрд░реА (рд░реЗрдбреАрд╕реНрдЯреЗрдореЗрдВрдЯ) рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреИрд╢ рдХрд░рддреЗ рд╣реИрдВред
  class DBPoolCacheMy extends DBPool { private String url, user, password; private PGSimpleDataSource source; private BlockingQueue<Connection> connections = new ArrayBlockingQueue<Connection>(20); DBPoolCacheMy(String host, String database, String user, String password) throws SQLException { source = new PGSimpleDataSource(); source.setServerName(host); source.setDatabaseName(database); source.setUser(user); source.setPassword(password); for (int i = 0; i < 20; i++) {//  connections.add(new MyConnection(source.getConnection())); } } public Connection getConnection() throws SQLException { try { //     return connections.poll(2, TimeUnit.SECONDS); } catch (InterruptedException e) { return null; } } public void putConnection(Connection connection) throws SQLException { connections.add(connection); } } 

рдЖрдкрдХреЛ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдХрдиреЗрдХреНрд╢рди рд╡рд░реНрдЧ рдХреЛ рднреА рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдЬреЛ рдХрд┐ рд░реЗрдбреАрд╕реНрдЯреЗрдбрдореЗрдВрдЯ рдХреИрд╢рд┐рдВрдЧ рд▓рд╛рдЧреВ рдХрд░реЗрдЧрд╛ред
  class MyConnection implements Connection { private Connection connection; protected MyConnection(Connection connection) { this.connection = connection; } private ConcurrentHashMap<String, PreparedStatement> statements = new ConcurrentHashMap<String, PreparedStatement>(); public PreparedStatement prepareStatement(String sql) throws SQLException { PreparedStatement statement = statements.get(sql); if (statement == null) { statement = new MyStatement(connection.prepareStatement(sql)); statements.put(sql, statement); } return statement; } ..... } 

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЗрд╕рдХрд╛ рд╡рд░реНрдЧ рд░реЗрдбреАрд╕реНрдЯреЗрдбрдореЗрдВрдЯ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдмрдВрдж рд╣реЛрдиреЗ рдкрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИ
  class MyStatement implements PreparedStatement { private PreparedStatement statement; MyStatement(PreparedStatement statement) throws SQLException { this.statement = statement; ((PGStatement) statement).setPrepareThreshold(1); } public void close() throws SQLException { //ignore } ..... } 


рдирд┐рд╖реНрдХрд░реНрд╖



рдФрд░ рдЕрдВрдд рдореЗрдВ, рд╣рдо рддреАрди рдЕрд▓рдЧ-рдЕрд▓рдЧ рдХрдиреЗрдХреНрд╢рди рдкреВрд▓ рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреА рддреБрд▓рдирд╛ рдХрд░рддреЗ рд╣реИрдВ, рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдЙрдирдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП 1 рд╕реЗ 10 рддрдХ рд╕рдорд╛рдирд╛рдВрддрд░ рдереНрд░реЗрдбреНрд╕ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕рд╛рде рдЪрд▓рд╛рддреЗ рд╣реИрдВред рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдереНрд░реЗрдбреНрд╕ рдХреА рд╕рдВрдЦреНрдпрд╛ рдкрд░ рдХреБрд▓ рдХрд╛рд░реНрдп рдирд┐рд╖реНрдкрд╛рджрди рд╕рдордп рдХреА рдирд┐рдореНрди рдирд┐рд░реНрднрд░рддрд╛ рдкреНрд░рд╛рдкреНрдд рдХреА рдЧрдИ рдереАред



рдЧреНрд░рд╛рдлрд╝ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ рдХрд┐ рдбреЗрдЯрд╛рдмреЗрд╕ рдХрдиреЗрдХреНрд╢рди рдХреЛ рдХреИрд╢ рдХрд░рдирд╛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рдЗрд╕рд╕реЗ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рдЙрд▓реНрд▓реЗрдЦрдиреАрдп рд╡реГрджреНрдзрд┐ рд╣реЛрддреА рд╣реИред рд▓реЗрдХрд┐рди рдХрдиреЗрдХреНрд╢рди рдХреИрд╢рд┐рдВрдЧ рдФрд░ рд░реЗрдбреАрд╕реНрдЯреЗрдбрдореЗрдВрдЯ рдХреЗ рд╕реНрд╡-рд▓рд┐рдЦрд┐рдд рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдореВрд░реНрдд рд▓рд╛рдн рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИред

Source: https://habr.com/ru/post/In194142/


All Articles