代码拉取完成,页面将自动刷新
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>13 秒插入 30 万条数据</title>
<url>/posts/688df240/</url>
<content><![CDATA[<p>本文主要讲述通过MyBatis、JDBC等做大数据量数据插入的案例和结果。</p>
<p><strong># 30万条数据插入插入数据库验证</strong></p>
<p>实体类、mapper和配置文件定义</p>
<ul>
<li>User实体</li>
<li>mapper接口</li>
<li>mapper.xml文件</li>
<li>jdbc.properties</li>
<li>sqlMapConfig.xml</li>
<li>不分批次直接梭哈</li>
<li>循环逐条插入</li>
<li>MyBatis实现插入30万条数据</li>
<li>JDBC实现插入30万条数据</li>
<li>总结</li>
</ul>
<p>验证的数据库表结构如下:</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">CREATE TABLE `t_user` (</span><br><span class="line"> `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户id',</span><br><span class="line"> `username` varchar(64) DEFAULT NULL COMMENT '用户名称',</span><br><span class="line"> `age` int(4) DEFAULT NULL COMMENT '年龄',</span><br><span class="line"> PRIMARY KEY (`id`)</span><br><span class="line">) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户信息表';</span><br></pre></td></tr></table></figure>
<p>话不多说,开整!</p>
<p><strong># 实体类、mapper和配置文件定义</strong></p>
<p>User实体</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">/**</span><br><span class="line"> * <p>用户实体</p></span><br><span class="line"> *</span><br><span class="line"> * @Author zjq</span><br><span class="line"> * @Date 2021/8/3</span><br><span class="line"> */</span><br><span class="line">@Data</span><br><span class="line">public class User {</span><br><span class="line"> private int id;</span><br><span class="line"> private String username;</span><br><span class="line"> private int age;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>mapper接口</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">public interface UserMapper {</span><br><span class="line"> /**</span><br><span class="line"> * 批量插入用户</span><br><span class="line"> * @param userList</span><br><span class="line"> */</span><br><span class="line"> void batchInsertUser(@Param("list") List<User> userList);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>mapper.xml文件</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line"><!-- 批量插入用户信息 --></span><br><span class="line"><insert id="batchInsertUser" parameterType="java.util.List"></span><br><span class="line"> insert into t_user(username,age) values</span><br><span class="line"> <foreach collection="list" item="item" index="index" separator=","></span><br><span class="line"> (</span><br><span class="line"> #{item.username},</span><br><span class="line"> #{item.age}</span><br><span class="line"> )</span><br><span class="line"> </foreach></span><br><span class="line"></insert></span><br></pre></td></tr></table></figure>
<p>jdbc.properties</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">jdbc.driver=com.mysql.jdbc.Driver</span><br><span class="line">jdbc.url=jdbc:mysql://localhost:3306/test</span><br><span class="line">jdbc.username=root</span><br><span class="line">jdbc.password=root</span><br></pre></td></tr></table></figure>
<p>sqlMapConfig.xml</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line"><?xml version="1.0" encoding="UTF-8" ?></span><br><span class="line"><!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"></span><br><span class="line"><configuration></span><br><span class="line"> <!--通过properties标签加载外部properties文件--></span><br><span class="line"> <properties resource="jdbc.properties"></properties></span><br><span class="line"> <!--自定义别名--></span><br><span class="line"> <typeAliases></span><br><span class="line"> <typeAlias type="com.zjq.domain.User" alias="user"></typeAlias></span><br><span class="line"> </typeAliases></span><br><span class="line"> <!--数据源环境--></span><br><span class="line"> <environments default="developement"></span><br><span class="line"> <environment id="developement"></span><br><span class="line"> <transactionManager type="JDBC"></transactionManager></span><br><span class="line"> <dataSource type="POOLED"></span><br><span class="line"> <property name="driver" value="${jdbc.driver}"/></span><br><span class="line"> <property name="url" value="${jdbc.url}"/></span><br><span class="line"> <property name="username" value="${jdbc.username}"/></span><br><span class="line"> <property name="password" value="${jdbc.password}"/></span><br><span class="line"> </dataSource></span><br><span class="line"> </environment></span><br><span class="line"> </environments></span><br><span class="line"> <!--加载映射文件--></span><br><span class="line"> <mappers></span><br><span class="line"> <mapper resource="com/zjq/mapper/UserMapper.xml"></mapper></span><br><span class="line"> </mappers></span><br><span class="line"></configuration></span><br></pre></td></tr></table></figure>
<p><strong>不分批次直接梭哈</strong></p>
<p>MyBatis直接一次性批量插入30万条,代码如下:</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">@Test</span><br><span class="line">public void testBatchInsertUser() throws IOException {</span><br><span class="line"> InputStream resourceAsStream =</span><br><span class="line"> Resources.getResourceAsStream("sqlMapConfig.xml");</span><br><span class="line"> SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);</span><br><span class="line"> SqlSession session = sqlSessionFactory.openSession();</span><br><span class="line"> System.out.println("===== 开始插入数据 =====");</span><br><span class="line"> long startTime = System.currentTimeMillis();</span><br><span class="line"> try {</span><br><span class="line"> List<User> userList = new ArrayList<>();</span><br><span class="line"> for (int i = 1; i <= 300000; i++) {</span><br><span class="line"> User user = new User();</span><br><span class="line"> user.setId(i);</span><br><span class="line"> user.setUsername("共饮一杯无 " + i);</span><br><span class="line"> user.setAge((int) (Math.random() * 100));</span><br><span class="line"> userList.add(user);</span><br><span class="line"> }</span><br><span class="line"> session.insert("batchInsertUser", userList); // 最后插入剩余的数据</span><br><span class="line"> session.commit();</span><br><span class="line"> long spendTime = System.currentTimeMillis()-startTime;</span><br><span class="line"> System.out.println("成功插入 30 万条数据,耗时:"+spendTime+"毫秒");</span><br><span class="line"> } finally {</span><br><span class="line"> session.close();</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>可以看到控制台输出:</p>
<blockquote>
<p>Cause: com.mysql.jdbc.PacketTooBigException: Packet for query is too large (27759038 >yun 4194304). You can change this value on the server by setting the max_allowed_packet’ variable.</p>
</blockquote>
<p>超出最大数据包限制了,可以通过调整max_allowed_packet限制来提高可以传输的内容,不过由于30万条数据超出太多,这个不可取,梭哈看来是不行了 😅😅😅</p>
<p>既然梭哈不行那我们就一条一条循环着插入行不行呢</p>
<p><strong>循环逐条插入</strong></p>
<p>mapper接口和mapper文件中新增单个用户新增的内容如下:</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">/**</span><br><span class="line"> * 新增单个用户</span><br><span class="line"> * @param user</span><br><span class="line"> */</span><br><span class="line">void insertUser(User user);</span><br><span class="line"><!-- 新增用户信息 --></span><br><span class="line"><insert id="insertUser" parameterType="user"></span><br><span class="line"> insert into t_user(username,age) values</span><br><span class="line"> (</span><br><span class="line"> #{username},</span><br><span class="line"> #{age}</span><br><span class="line"> )</span><br><span class="line"></insert></span><br></pre></td></tr></table></figure>
<p>调整执行代码如下:</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">@Test</span><br><span class="line">public void testCirculateInsertUser() throws IOException {</span><br><span class="line"> InputStream resourceAsStream =</span><br><span class="line"> Resources.getResourceAsStream("sqlMapConfig.xml");</span><br><span class="line"> SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);</span><br><span class="line"> SqlSession session = sqlSessionFactory.openSession();</span><br><span class="line"> System.out.println("===== 开始插入数据 =====");</span><br><span class="line"> long startTime = System.currentTimeMillis();</span><br><span class="line"> try {</span><br><span class="line"> for (int i = 1; i <= 300000; i++) {</span><br><span class="line"> User user = new User();</span><br><span class="line"> user.setId(i);</span><br><span class="line"> user.setUsername("共饮一杯无 " + i);</span><br><span class="line"> user.setAge((int) (Math.random() * 100));</span><br><span class="line"> // 一条一条新增</span><br><span class="line"> session.insert("insertUser", user);</span><br><span class="line"> session.commit();</span><br><span class="line"> }</span><br><span class="line"> long spendTime = System.currentTimeMillis()-startTime;</span><br><span class="line"> System.out.println("成功插入 30 万条数据,耗时:"+spendTime+"毫秒");</span><br><span class="line"> } finally {</span><br><span class="line"> session.close();</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>执行后可以发现磁盘IO占比飙升,一直处于高位。</p>
<p><img src="/posts/688df240/640.png" alt="图片"></p>
<p>等啊等等啊等,好久还没执行完</p>
<p><img src="/posts/688df240/640-1690880454566-3.gif" alt="图片"></p>
<p>先不管他了太慢了先搞其他的,等会再来看看结果吧。</p>
<p>控制台输出如下:</p>
<p><img src="/posts/688df240/640-1690880456968-6.png" alt="图片"></p>
<p>总共执行了14909367毫秒,换算出来是4小时八分钟。太慢了。。</p>
<p><img src="/posts/688df240/640-1690880458846-9.png" alt="图片"></p>
<p>👇👇👇还是优化下之前的批处理方案吧</p>
<p><strong># MyBatis实现插入30万条数据</strong></p>
<p>先清理表数据,然后优化批处理执行插入:</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">-- 清空用户表</span><br><span class="line">TRUNCATE table t_user;</span><br></pre></td></tr></table></figure>
<p>以下是通过 MyBatis 实现 30 万条数据插入代码实现:</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">/**</span><br><span class="line"> * 分批次批量插入</span><br><span class="line"> * @throws IOException</span><br><span class="line"> */</span><br><span class="line">@Test</span><br><span class="line">public void testBatchInsertUser() throws IOException {</span><br><span class="line"> InputStream resourceAsStream =</span><br><span class="line"> Resources.getResourceAsStream("sqlMapConfig.xml");</span><br><span class="line"> SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);</span><br><span class="line"> SqlSession session = sqlSessionFactory.openSession();</span><br><span class="line"> System.out.println("===== 开始插入数据 =====");</span><br><span class="line"> long startTime = System.currentTimeMillis();</span><br><span class="line"> int waitTime = 10;</span><br><span class="line"> try {</span><br><span class="line"> List<User> userList = new ArrayList<>();</span><br><span class="line"> for (int i = 1; i <= 300000; i++) {</span><br><span class="line"> User user = new User();</span><br><span class="line"> user.setId(i);</span><br><span class="line"> user.setUsername("共饮一杯无 " + i);</span><br><span class="line"> user.setAge((int) (Math.random() * 100));</span><br><span class="line"> userList.add(user);</span><br><span class="line"> if (i % 1000 == 0) {</span><br><span class="line"> session.insert("batchInsertUser", userList);</span><br><span class="line"> // 每 1000 条数据提交一次事务</span><br><span class="line"> session.commit();</span><br><span class="line"> userList.clear();</span><br><span class="line"> // 等待一段时间</span><br><span class="line"> Thread.sleep(waitTime * 1000);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> // 最后插入剩余的数据</span><br><span class="line"> if(!CollectionUtils.isEmpty(userList)) {</span><br><span class="line"> session.insert("batchInsertUser", userList);</span><br><span class="line"> session.commit();</span><br><span class="line"> }</span><br><span class="line"> long spendTime = System.currentTimeMillis()-startTime;</span><br><span class="line"> System.out.println("成功插入 30 万条数据,耗时:"+spendTime+"毫秒");</span><br><span class="line"> } catch (Exception e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line"> } finally {</span><br><span class="line"> session.close();</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>使用了 MyBatis 的批处理操作,将每 1000 条数据放在一个批次中插入,能够较为有效地提高插入速度。同时请注意在循环插入时要带有合适的等待时间和批处理大小,以防止出现内存占用过高等问题。此外,还需要在配置文件中设置合理的连接池和数据库的参数,以获得更好的性能。</p>
<p><img src="/posts/688df240/640-1690880466109-12.png" alt="图片"></p>
<p>在上面的示例中,我们每插入1000行数据就进行一次批处理提交,并等待10秒钟。这有助于控制内存占用,并确保插入操作平稳进行。</p>
<p><img src="/posts/688df240/640-1690880505257-30.png" alt="图片"></p>
<p>五十分钟执行完毕,时间主要用在了等待上。</p>
<p>如果低谷时期执行,CPU和磁盘性能又足够的情况下,直接批处理不等待执行:</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">/**</span><br><span class="line"> * 分批次批量插入</span><br><span class="line"> * @throws IOException</span><br><span class="line"> */</span><br><span class="line">@Test</span><br><span class="line">public void testBatchInsertUser() throws IOException {</span><br><span class="line"> InputStream resourceAsStream =</span><br><span class="line"> Resources.getResourceAsStream("sqlMapConfig.xml");</span><br><span class="line"> SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);</span><br><span class="line"> SqlSession session = sqlSessionFactory.openSession();</span><br><span class="line"> System.out.println("===== 开始插入数据 =====");</span><br><span class="line"> long startTime = System.currentTimeMillis();</span><br><span class="line"> int waitTime = 10;</span><br><span class="line"> try {</span><br><span class="line"> List<User> userList = new ArrayList<>();</span><br><span class="line"> for (int i = 1; i <= 300000; i++) {</span><br><span class="line"> User user = new User();</span><br><span class="line"> user.setId(i);</span><br><span class="line"> user.setUsername("共饮一杯无 " + i);</span><br><span class="line"> user.setAge((int) (Math.random() * 100));</span><br><span class="line"> userList.add(user);</span><br><span class="line"> if (i % 1000 == 0) {</span><br><span class="line"> session.insert("batchInsertUser", userList);</span><br><span class="line"> // 每 1000 条数据提交一次事务</span><br><span class="line"> session.commit();</span><br><span class="line"> userList.clear();</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> // 最后插入剩余的数据</span><br><span class="line"> if(!CollectionUtils.isEmpty(userList)) {</span><br><span class="line"> session.insert("batchInsertUser", userList);</span><br><span class="line"> session.commit();</span><br><span class="line"> }</span><br><span class="line"> long spendTime = System.currentTimeMillis()-startTime;</span><br><span class="line"> System.out.println("成功插入 30 万条数据,耗时:"+spendTime+"毫秒");</span><br><span class="line"> } catch (Exception e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line"> } finally {</span><br><span class="line"> session.close();</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>则24秒可以完成数据插入操作:</p>
<p><img src="/posts/688df240/640-1690880469012-15.png" alt="图片"></p>
<p><img src="/posts/688df240/640-1690880470876-18.png" alt="图片"></p>
<p>可以看到短时CPU和磁盘占用会飙高。</p>
<p>把批处理的量再调大一些调到5000,在执行:</p>
<p><img src="/posts/688df240/640-1690880472421-21.png" alt="图片"></p>
<p>13秒插入成功30万条,直接芜湖起飞🛫🛫🛫</p>
<p><strong># JDBC实现插入30万条数据</strong></p>
<p>JDBC循环插入的话跟上面的mybatis逐条插入类似,不再赘述。</p>
<p>以下是 Java 使用 JDBC 批处理实现 30 万条数据插入的示例代码。请注意,该代码仅提供思路,具体实现需根据实际情况进行修改。</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">/**</span><br><span class="line"> * JDBC分批次批量插入</span><br><span class="line"> * @throws IOException</span><br><span class="line"> */</span><br><span class="line">@Test</span><br><span class="line">public void testJDBCBatchInsertUser() throws IOException {</span><br><span class="line"> Connection connection = null;</span><br><span class="line"> PreparedStatement preparedStatement = null;</span><br><span class="line"> String databaseURL = "jdbc:mysql://localhost:3306/test";</span><br><span class="line"> String user = "root";</span><br><span class="line"> String password = "root";</span><br><span class="line"> try {</span><br><span class="line"> connection = DriverManager.getConnection(databaseURL, user, password);</span><br><span class="line"> // 关闭自动提交事务,改为手动提交</span><br><span class="line"> connection.setAutoCommit(false);</span><br><span class="line"> System.out.println("===== 开始插入数据 =====");</span><br><span class="line"> long startTime = System.currentTimeMillis();</span><br><span class="line"> String sqlInsert = "INSERT INTO t_user ( username, age) VALUES ( ?, ?)";</span><br><span class="line"> preparedStatement = connection.prepareStatement(sqlInsert);</span><br><span class="line"> Random random = new Random();</span><br><span class="line"> for (int i = 1; i <= 300000; i++) {</span><br><span class="line"> preparedStatement.setString(1, "共饮一杯无 " + i);</span><br><span class="line"> preparedStatement.setInt(2, random.nextInt(100));</span><br><span class="line"> // 添加到批处理中</span><br><span class="line"> preparedStatement.addBatch();</span><br><span class="line"> if (i % 1000 == 0) {</span><br><span class="line"> // 每1000条数据提交一次</span><br><span class="line"> preparedStatement.executeBatch();</span><br><span class="line"> connection.commit();</span><br><span class="line"> System.out.println("成功插入第 "+ i+" 条数据");</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> // 处理剩余的数据</span><br><span class="line"> preparedStatement.executeBatch();</span><br><span class="line"> connection.commit();</span><br><span class="line"> long spendTime = System.currentTimeMillis()-startTime;</span><br><span class="line"> System.out.println("成功插入 30 万条数据,耗时:"+spendTime+"毫秒");</span><br><span class="line"> } catch (SQLException e) {</span><br><span class="line"> System.out.println("Error: " + e.getMessage());</span><br><span class="line"> } finally {</span><br><span class="line"> if (preparedStatement != null) {</span><br><span class="line"> try {</span><br><span class="line"> preparedStatement.close();</span><br><span class="line"> } catch (SQLException e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> if (connection != null) {</span><br><span class="line"> try {</span><br><span class="line"> connection.close();</span><br><span class="line"> } catch (SQLException e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><img src="/posts/688df240/640-1690880476797-24.gif" alt="图片"></p>
<p><img src="/posts/688df240/640-1690880477978-27.png" alt="图片"></p>
<p>上述示例代码中,我们通过 JDBC 连接 MySQL 数据库,并执行批处理操作插入数据。具体实现步骤如下:</p>
<ul>
<li>获取数据库连接。</li>
<li>创建 Statement 对象。</li>
<li>定义 SQL 语句,使用 PreparedStatement 对象预编译 SQL 语句并设置参数。</li>
<li>执行批处理操作。</li>
<li>处理剩余的数据。</li>
<li>关闭 Statement 和 Connection 对象。</li>
</ul>
<p>使用setAutoCommit(false) 来禁止自动提交事务,然后在每次批量插入之后手动提交事务。每次插入数据时都新建一个 PreparedStatement 对象以避免状态不一致问题。在插入数据的循环中,每 10000 条数据就执行一次 executeBatch() 插入数据。</p>
<p>另外,需要根据实际情况优化连接池和数据库的相关配置,以防止连接超时等问题。</p>
<p><strong># 总结</strong></p>
<p>实现高效的大量数据插入需要结合以下优化策略(建议综合使用):</p>
<p>1.批处理:批量提交SQL语句可以降低网络传输和处理开销,减少与数据库交互的次数。在Java中可以使用Statement或者PreparedStatement的addBatch()方法来添加多个SQL语句,然后一次性执行executeBatch()方法提交批处理的SQL语句。</p>
<ul>
<li>在循环插入时带有适当的等待时间和批处理大小,从而避免内存占用过高等问题:</li>
<li>设置适当的批处理大小:批处理大小指在一次插入操作中插入多少行数据。如果批处理大小太小,插入操作的频率将很高,而如果批处理大小太大,可能会导致内存占用过高。通常,建议将批处理大小设置为1000-5000行,这将减少插入操作的频率并降低内存占用。</li>
<li>采用适当的等待时间:等待时间指在批处理操作之间等待的时间量。等待时间过短可能会导致内存占用过高,而等待时间过长则可能会延迟插入操作的速度。通常,建议将等待时间设置为几秒钟到几十秒钟之间,这将使操作变得平滑且避免出现内存占用过高等问题。</li>
<li>可以考虑使用一些内存优化的技巧,例如使用内存数据库或使用游标方式插入数据,以减少内存占用。</li>
<li>总的来说,选择适当的批处理大小和等待时间可以帮助您平稳地进行插入操作,避免出现内存占用过高等问题。</li>
</ul>
<p>2.索引: 在大量数据插入前暂时去掉索引,最后再打上,这样可以大大减少写入时候的更新索引的时间。</p>
<p>3.数据库连接池:使用数据库连接池可以减少数据库连接建立和关闭的开销,提高性能。在没有使用数据库连接池的情况,记得在finally中关闭相关连接。</p>
<p>数据库参数调整:增加MySQL数据库缓冲区大小、配置高性能的磁盘和I/O等。</p>
<blockquote>
<p>来源:blog.csdn.net/qq_35427589/article/details/129665307</p>
</blockquote>
]]></content>
<categories>
<category>代码</category>
</categories>
<tags>
<tag>java</tag>
<tag>MyBatis</tag>
<tag>JDBC</tag>
</tags>
</entry>
<entry>
<title>DM8自动生成代码</title>
<url>/posts/2a7156f8/</url>
<content><![CDATA[<h3 id="代码地址"><a href="#代码地址" class="headerlink" title="代码地址"></a><strong>代码地址</strong></h3><p>后端代码开源地址:</p>
<blockquote>
<p><a href="https://gitee.com/azun/ruoyi-dameng">https://gitee.com/azun/ruoyi-dameng</a></p>
</blockquote>
<p>前端代码开源地址:</p>
<blockquote>
<p><a href="https://gitee.com/y_project/RuoYi-Vue/tree/master">https://gitee.com/y_project/RuoYi-Vue/tree/master</a></p>
</blockquote>
<h3 id="电脑需要搭配的软件"><a href="#电脑需要搭配的软件" class="headerlink" title="电脑需要搭配的软件"></a><strong>电脑需要搭配的软件</strong></h3><ol>
<li>IDEA代码编辑器</li>
<li>Node.js</li>
<li>Npm(下载Node.js自带)</li>
<li>DM8数据库</li>
<li>Redis</li>
</ol>
<h3 id="电脑配置"><a href="#电脑配置" class="headerlink" title="电脑配置"></a><strong>电脑配置</strong></h3><p>系统:windows10</p>
<p>内存:23G</p>
<p>硬盘:1T</p>
<h3 id="若依系统账号密码"><a href="#若依系统账号密码" class="headerlink" title="若依系统账号密码"></a><strong>若依系统账号密码</strong></h3><p><code>admin/admin123</code></p>
<h3 id="后端准备"><a href="#后端准备" class="headerlink" title="后端准备"></a><strong>后端准备</strong></h3><h4 id="后端代码端口号改为8080"><a href="#后端代码端口号改为8080" class="headerlink" title="后端代码端口号改为8080"></a>后端代码端口号改为8080</h4><p><img src="/posts/2a7156f8/wps2.jpg" alt="img"> </p>
<h4 id="导入达梦数据库表文件"><a href="#导入达梦数据库表文件" class="headerlink" title="导入达梦数据库表文件"></a>导入达梦数据库表文件</h4><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">文件名:imp_exp.dmp</span><br></pre></td></tr></table></figure>
<p><img src="/posts/2a7156f8/wps3.jpg" alt="img"> </p>
<h4 id="修改配置文件,数据库地址"><a href="#修改配置文件,数据库地址" class="headerlink" title="修改配置文件,数据库地址"></a>修改配置文件,数据库地址</h4><p><img src="/posts/2a7156f8/wps4.jpg" alt="img"> </p>
<h4 id="修改配置文件,redis地址"><a href="#修改配置文件,redis地址" class="headerlink" title="修改配置文件,redis地址"></a>修改配置文件,redis地址</h4><p><img src="/posts/2a7156f8/wps5.jpg" alt="img"> </p>
<h4 id="启动"><a href="#启动" class="headerlink" title="启动"></a>启动</h4><h3 id="前端准备"><a href="#前端准备" class="headerlink" title="前端准备"></a><strong>前端准备</strong></h3><ol>
<li><p>修改镜像,在终端执行 </p>
<p><code>npm --registry https://registry.npm.taobao.org install express</code></p>
<p>或: <code>npm config set registry https://registry.npm.taobao.org</code></p>
</li>
<li><p>进入RuoYi-Vue/ruoyi-iu目录,在终端执行</p>
<p> <code>cd ruoyi-ui </code></p>
</li>
<li><p>下载依赖,在终端执行 </p>
<p><code>npm install</code></p>
</li>
<li><p>解决node.js版本过高,在终端执行</p>
<p><code>$env:NODE_OPTIONS="--openssl-legacy-provider"</code></p>
</li>
<li><p>启动分支,在终端执行</p>
<p> <code>npm run dev</code></p>
</li>
</ol>
<h3 id="前端访问后端接口IP地址设置"><a href="#前端访问后端接口IP地址设置" class="headerlink" title="前端访问后端接口IP地址设置"></a><strong>前端访问后端接口IP地址设置</strong></h3><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">配置前端访问后端接口ip地址:编辑/ruoyi-ui/vue.config.js文件内的tartget属性</span><br><span class="line">proxy: {</span><br><span class="line"> // detail: https://cli.vuejs.org/config/#devserver-proxy</span><br><span class="line"> [process.env.VUE_APP_BASE_API]: {</span><br><span class="line"> target: `http://localhost:8089`,</span><br><span class="line"> changeOrigin: true,</span><br><span class="line"> pathRewrite: {</span><br><span class="line"> ['^' + process.env.VUE_APP_BASE_API]: ''</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br></pre></td></tr></table></figure>
<h3 id="已配置好的文件地址与教程"><a href="#已配置好的文件地址与教程" class="headerlink" title="已配置好的文件地址与教程"></a>已配置好的文件地址与教程</h3><p><a href="https://pan.baidu.com/s/12b1DT9drN8DkkRt29e6orA?pwd=gryw">链接: https://pan.baidu.com/s/12b1DT9drN8DkkRt29e6orA?pwd=gryw 提取码: gryw 复制这段内容后打开百度网盘手机App,操作更方便哦</a></p>
]]></content>
<categories>
<category>代码</category>
</categories>
<tags>
<tag>java</tag>
<tag>自动生成</tag>
<tag>IDEA</tag>
<tag>DM8</tag>
<tag>Node.js</tag>
<tag>redis</tag>
<tag>若依</tag>
</tags>
</entry>
<entry>
<title>Hexo+Algolia实现搜索</title>
<url>/posts/8b7ba7da/</url>
<content><![CDATA[<blockquote>
<p>示例主题<br><a href="https://github.com/fi3ework/hexo-theme-archer">https://github.com/fi3ework/hexo-theme-archer</a></p>
</blockquote>
<h3 id="第一步:到官网注册帐号-可以用github登录"><a href="#第一步:到官网注册帐号-可以用github登录" class="headerlink" title="第一步:到官网注册帐号(可以用github登录)"></a>第一步:到官网注册帐号(可以用github登录)</h3><p><a href="https://www.algolia.com/referrals/c57f7b70/join">官网地址</a>注册帐号</p>
<h4 id="创建一个新的-Index"><a href="#创建一个新的-Index" class="headerlink" title="创建一个新的 Index"></a>创建一个新的 Index</h4><p>这个 <strong>index name</strong> 之后会用到</p>
<p><img src="/posts/8b7ba7da/image-20230427145353506.png" alt="image-20230427145353506"></p>
<p>来到<code>API-KEYS</code>页面,上面有后面需要的信息(记得还有上面的INDEX名)。</p>
<p><img src="/posts/8b7ba7da/image-20230427132058012.png" alt="image-20230427132058012"></p>
<p><img src="/posts/8b7ba7da/image-20230427132138632.png" alt="image-20230427132138632"></p>
<h4 id="创建一个API-Key"><a href="#创建一个API-Key" class="headerlink" title="创建一个API Key"></a>创建一个API Key</h4><p>注:这里的Search-Only <strong>API Key</strong>不能直接用,需要新建一个</p>
<p><img src="/posts/8b7ba7da/image-20230427132359847.png" alt="image-20230427132359847"></p>
<h3 id="第二步:上传数据到Algolia"><a href="#第二步:上传数据到Algolia" class="headerlink" title="第二步:上传数据到Algolia"></a>第二步:上传数据到<code>Algolia</code></h3><h4 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h4><p>在Hexo工程目录的根目录下执行</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">npm install hexo-algolia --save</span><br></pre></td></tr></table></figure>
<h4 id="连接"><a href="#连接" class="headerlink" title="连接"></a>连接</h4><p>在根目录的_config.yml中加入如下配置,注意改成前面第一步注册成果数据(注:<strong>API Key</strong>,<strong>index name</strong>是刚才新建的)</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">algolia:</span><br><span class="line"> applicationID: 'your applicationID'</span><br><span class="line"> apiKey: 'your API Key'</span><br><span class="line"> adminApiKey: 'your Admin API Key'</span><br><span class="line"> indexName: 'your indexName'</span><br><span class="line"> chunkSize: 5000</span><br></pre></td></tr></table></figure>
<p>在Hexo工程目录的根目录下执行</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">export</span>(windows 为 <span class="built_in">set</span>) (Powershell 用 <span class="variable">$env</span>:) HEXO_ALGOLIA_INDEXING_KEY=你的API Key</span><br><span class="line"><span class="comment"># 查看是否设置成功如果没有值就设置失败</span></span><br><span class="line"><span class="built_in">set</span> (Mac和git bash 为 <span class="built_in">export</span>) (Powershell 用 <span class="variable">$env</span>:) HEXO_ALGOLIA_INDEXING_KEY</span><br><span class="line"><span class="comment"># 清理</span></span><br><span class="line">hexo clean</span><br><span class="line"><span class="comment"># 连接</span></span><br><span class="line">hexo algolia</span><br></pre></td></tr></table></figure>
<p>结果如下:</p>
<p><img src="/posts/8b7ba7da/image-20230427141328726.png" alt="image-20230427141328726"></p>
<h3 id="第三步:修改Hexo主题集成Algolia"><a href="#第三步:修改Hexo主题集成Algolia" class="headerlink" title="第三步:修改Hexo主题集成Algolia"></a>第三步:修改Hexo主题集成Algolia</h3><p>更改Next主题_config配置文件,找到 Algolia Search 配置部分:</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="comment"># Algolia Search</span></span><br><span class="line"><span class="attr">algolia_search:</span></span><br><span class="line"> <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line"> <span class="attr">hits:</span></span><br><span class="line"> <span class="attr">per_page:</span> <span class="number">10</span></span><br><span class="line"> <span class="attr">labels:</span></span><br><span class="line"> <span class="attr">input_placeholder:</span> <span class="string">Search</span> <span class="string">for</span> <span class="string">Posts</span></span><br><span class="line"> <span class="attr">hits_empty:</span> <span class="string">"我们没有找到任何搜索结果: ${query}"</span></span><br><span class="line"> <span class="attr">hits_stats:</span> <span class="string">"找到约${hits}条结果(用时${time}ms)"</span></span><br></pre></td></tr></table></figure>
<h3 id="完成"><a href="#完成" class="headerlink" title="完成"></a>完成</h3><p>部署<code>hexo d -g</code></p>
<h3 id="展示"><a href="#展示" class="headerlink" title="展示"></a>展示</h3><p><img src="/posts/8b7ba7da/image-20230427144415013.png" alt="image-20230427144415013"></p>
]]></content>
<categories>
<category>hexo</category>
</categories>
<tags>
<tag>搭建</tag>
<tag>插件</tag>
</tags>
</entry>
<entry>
<title>Hexo-零基础搭建个人博客(详解)</title>
<url>/posts/353f598a/</url>
<content><![CDATA[<h1 id="Hexo零基础搭建个人博客"><a href="#Hexo零基础搭建个人博客" class="headerlink" title="Hexo零基础搭建个人博客"></a>Hexo零基础搭建个人博客</h1><p>Hexo是一个基于 node.js的快速生成静态博客的开源框架,支持 Markdown和大多数 Octopress<br>插件,一个命令即可部署到 Github页面、 Giteee、 Heroku等,强大的APl,可无限扩展,拥有<br>数百个主题和插件。</p>
<p>简单来说就是一个不用你写代码,就能搭建一套属于你自己的个人博客网站 应用(零基础小白也会)。</p>
<p>你可以在上面编写文章,做笔记,写日记,码代码。(一个属于你的世界!一个可供别人访问的个人世界)</p>
<p>另外Hero还提供了大量主题模版供用户下载。你的博客网站将可以时不时的换一种主题风格,赏心悦目,简直完美!</p>
<h2 id="一、环境准备"><a href="#一、环境准备" class="headerlink" title="一、环境准备"></a>一、环境准备</h2><h3 id="1、安装Node-js"><a href="#1、安装Node-js" class="headerlink" title="1、安装Node.js"></a>1、安装Node.js</h3><p>直接到官网上下载安装即可<a href="https://nodejs.org/en/download/">https://nodejs.org/en/download/</a></p>
<p>Node.js (Node.js 版本需不低于 10.13,建议使用 Node.js 12.0 及以上版本)<br>Node自带npm</p>
<h3 id="2、安装Git"><a href="#2、安装Git" class="headerlink" title="2、安装Git"></a>2、安装Git</h3><p>Windows:下载并安装 git.<br>Mac:使用 Homebrew, MacPorts 或者下载 安装程序。<br>Linux (Ubuntu, Debian):<code>sudo apt-get install git-core</code><br>Linux (Fedora, Red Hat, CentOS):<code>sudo yum install git-core</code></p>
<p><img src="/posts/353f598a/image-20230421154720784.png" alt="image-20230421154720784"></p>
<p>npm下载慢的话也可以下载淘宝下载源cnpm</p>
<p><code>npm install -g cnpm --registry=https://registry.npm.taobao.org</code></p>
<p><img src="/posts/353f598a/image-20230421154822250.png" alt="image-20230421154822250"></p>
<h2 id="二、开始安装Hexo"><a href="#二、开始安装Hexo" class="headerlink" title="二、开始安装Hexo"></a>二、开始安装Hexo</h2><h3 id="1、安装hexo"><a href="#1、安装hexo" class="headerlink" title="1、安装hexo"></a>1、安装hexo</h3><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">npm install -g hexo-cli</span><br><span class="line">或者</span><br><span class="line">cnpm install -g hexo-cli</span><br></pre></td></tr></table></figure>
<p>安装完成可输入hexo -v查看版本</p>
<p><img src="/posts/353f598a/image-20230421154851996.png" alt="image-20230421154851996"></p>
<h3 id="2、初始化hexo,新建存储博客的文件夹"><a href="#2、初始化hexo,新建存储博客的文件夹" class="headerlink" title="2、初始化hexo,新建存储博客的文件夹"></a>2、初始化hexo,新建存储博客的文件夹</h3><p><code>hexo init myblog</code></p>
<p><img src="/posts/353f598a/image-20230421154928032.png" alt="image-20230421154928032"></p>
<h3 id="3、进入文件夹,安装一下npm"><a href="#3、进入文件夹,安装一下npm" class="headerlink" title="3、进入文件夹,安装一下npm"></a>3、进入文件夹,安装一下npm</h3><p><code>cd myblog</code><br><code>npm install</code><br>可以看到我们的hexo站点就已经安装好了,接下来就可以直接启动他了</p>
<p><img src="/posts/353f598a/image-20230421154938969.png" alt="image-20230421154938969"></p>
<h3 id="4、启动服务站点"><a href="#4、启动服务站点" class="headerlink" title="4、启动服务站点"></a>4、启动服务站点</h3><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">hexo g </span><br><span class="line">hexo server</span><br></pre></td></tr></table></figure>
<p><img src="/posts/353f598a/image-20230421155013829.png" alt="image-20230421155013829"></p>
<p>访问<a href="http://localhost:4000/">http://localhost:4000/</a> 至此hero就搭建好了。可以在本地访问了</p>
<p><img src="/posts/353f598a/image-20230421155047980.png" alt="image-20230421155047980"></p>
<h2 id="三、Gitee上建站访问"><a href="#三、Gitee上建站访问" class="headerlink" title="三、Gitee上建站访问"></a>三、Gitee上建站访问</h2><p>可在github或者gitee上建站,gitee国内访问快一些</p>
<h3 id="1、新建仓库"><a href="#1、新建仓库" class="headerlink" title="1、新建仓库"></a>1、新建仓库</h3><p>格式必须是:用户名+.gitee.io 只有这样,将来要部署到Gite e page的时候,才会被识别,也就是xxxx.gitee.io,其中xxx就是你注册Gitee的用户名。(这里是错的gitee只需要用户名就行,不需要加.gitee.io)</p>
<p><img src="/posts/353f598a/image-20230421155102661.png" alt="image-20230421155102661"></p>
<h3 id="2、将hexo博客站点上传到gitee上"><a href="#2、将hexo博客站点上传到gitee上" class="headerlink" title="2、将hexo博客站点上传到gitee上"></a>2、将hexo博客站点上传到gitee上</h3><p>这里需要安装一个hexo的上传插件deploy-git</p>
<p><code>npm install hexo-deployer-git --save</code></p>
<p><img src="/posts/353f598a/image-20230421155313944.png" alt="image-20230421155313944"></p>
<h3 id="3、修改hexo配置文件指定仓库路径"><a href="#3、修改hexo配置文件指定仓库路径" class="headerlink" title="3、修改hexo配置文件指定仓库路径"></a>3、修改hexo配置文件指定仓库路径</h3><p>可在文件夹中直接打开文件,也可通过vim直接编辑</p>
<p><img src="/posts/353f598a/image-20230421155320674.png" alt="image-20230421155320674"></p>
<p>找到Deployment加上(注意空格)</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">deploy:</span></span><br><span class="line"> <span class="attr">type:</span> <span class="string">git</span></span><br><span class="line"> <span class="attr">repo:</span> <span class="string">你的仓库路径</span></span><br><span class="line"> <span class="attr">branch:</span> <span class="string">master</span></span><br></pre></td></tr></table></figure>
<p><img src="/posts/353f598a/image-20230421155441995.png" alt="image-20230421155441995"></p>
<h3 id="4、推送hexo站点文件"><a href="#4、推送hexo站点文件" class="headerlink" title="4、推送hexo站点文件"></a>4、推送hexo站点文件</h3><p>之后就可以推送博客站点到gitee上了</p>
<p>推送命令<code>hexo d</code></p>
<blockquote>
<p> 扩展:</p>
<p>其中 hexo clean清除了你之前生成的东西,也可以不加。<br>hexo generate 顾名思义,生成静态文章,可以用 hexo g缩写<br>hexo deploy 部署文章,可以用hexo d缩写</p>
</blockquote>
<p>推送中会要求输入gitee的用户名和密码(如果不想每次都输可以配置ssh,我这里就不做演示了)</p>
<p><img src="/posts/353f598a/image-20230421155537841.png" alt="image-20230421155537841"></p>
<p>然后就可以看到gitee上有推上来的文件了</p>
<h3 id="5、配置Pages服务"><a href="#5、配置Pages服务" class="headerlink" title="5、配置Pages服务"></a>5、配置Pages服务</h3><p>目前我们站点还无法访问需要开启Gitee Pages(gitee需要开启,github不需要)</p>
<p><img src="/posts/353f598a/image-20230421155546437.png" alt="image-20230421155546437"></p>
<p>审核通过启动我们就可以访问啦。</p>
<p><img src="/posts/353f598a/image-20230421155610552.png" alt="image-20230421155610552"></p>
<p><img src="/posts/353f598a/image-20230421155621083.png" alt="image-20230421155621083"></p>
<p>gitee上传新文件之后,需要手动更新一下,更新后的页面才会生效</p>
<p><img src="/posts/353f598a/image-20230421155630198.png" alt="image-20230421155630198"></p>
<p>多说一句:如果觉得这个访问路径太长了,我们可以去买一个域名,将该路径绑定到域名上,即可通过域名访问了。</p>
<h2 id="四、GitHub上建站访问"><a href="#四、GitHub上建站访问" class="headerlink" title="四、GitHub上建站访问"></a>四、GitHub上建站访问</h2><p>在gitee上建站发现有限制条件,所有也可以采用github建站的方式。</p>
<p>步骤和gitee一样。</p>
<h3 id="1、新建guthub仓库"><a href="#1、新建guthub仓库" class="headerlink" title="1、新建guthub仓库"></a>1、新建guthub仓库</h3><p>仓库名称限制了为你的:用户名+.github.io</p>
<p><img src="/posts/353f598a/image-20230421155700686.png" alt="image-20230421155700686"></p>
<h3 id="2、安装hexo上传插件"><a href="#2、安装hexo上传插件" class="headerlink" title="2、安装hexo上传插件"></a>2、安装hexo上传插件</h3><p><code>npm install hexo-deployer-git --save</code></p>
<h3 id="3、修改hexo配置文件指定仓库路径-1"><a href="#3、修改hexo配置文件指定仓库路径-1" class="headerlink" title="3、修改hexo配置文件指定仓库路径"></a>3、修改hexo配置文件指定仓库路径</h3><p>可在文件夹中直接打开文件,也可通过vim直接编辑</p>
<p><code>vim _config.yml #找到Deploymentdeploy: type: git repo: 你的github仓库路径 branch: master</code></p>
<h3 id="4、推送站点到github"><a href="#4、推送站点到github" class="headerlink" title="4、推送站点到github"></a>4、推送站点到github</h3><p>推送命令<code>hexo d</code></p>
<p>推送过程中需要输入你的github用户名和密码。但是在2021年8月14日开始github官方就加强安全访问。不能通过原有账号密码git访问,密码需要用官方的token或者采用ssh公私钥访问。否则会出现下图:鉴权失败(用户名密码错误)</p>
<blockquote>
<p>官方原话:</p>
<p>近年来,GitHub 客户受益于 GitHub.com 的许多安全增强功能,例如双因素身份验证、登录警报、经过验证的设备、防止使用泄露密码和 WebAuthn 支持。 这些功能使攻击者更难获取在多个网站上重复使用的密码并使用它来尝试访问您的 GitHub 帐户。 尽管有这些改进,但由于历史原因,未启用双因素身份验证的客户仍能够仅使用其GitHub 用户名和密码继续对 Git 和 API 操作进行身份验证。</p>
<p>从 2021 年 8 月 13 日开始,我们将在对 Git 操作进行身份验证时不再接受帐户密码,并将要求使用基于令牌(token)的身份验证,例如个人访问令牌(针对开发人员)或 OAuth 或 GitHub 应用程序安装令牌(针对集成商) GitHub.com 上所有经过身份验证的 Git 操作。 您也可以继续在您喜欢的地方使用 SSH 密钥</p>
</blockquote>
<p><img src="/posts/353f598a/image-20230421155804259.png" alt="image-20230421155804259"></p>
<p>解决方式就是获取token,登录github设置setting->Developer Settings->Prosonal access tokens 创建一个新token。然后就可以拿这个token当密码输入了。</p>
<p><img src="/posts/353f598a/image-20230421155819983.png" alt="image-20230421155819983"></p>
<p><img src="/posts/353f598a/image-20230421155828748.png" alt="image-20230421155828748"></p>
<p>用户名和token输入后,上传成功。</p>
<p><img src="/posts/353f598a/image-20230421155851166.png" alt="image-20230421155851166"></p>
<p><img src="/posts/353f598a/image-20230421155857869.png" alt="image-20230421155857869"></p>
<h3 id="5、尝试访问"><a href="#5、尝试访问" class="headerlink" title="5、尝试访问"></a>5、尝试访问</h3><p>输入你的仓库名称,即可访问成功。</p>
<p><a href="https://lindaifeng.github.io/">https://lindaifeng.github.io/</a></p>
<p><img src="/posts/353f598a/image-20230421155907019.png" alt="image-20230421155907019"></p>
<h2 id="五、更换主题"><a href="#五、更换主题" class="headerlink" title="五、更换主题"></a>五、更换主题</h2><p>博客样式太死板,想换成属于自己的风格,没问题我们可以更换博客的主题,来达到我们想要的风格。</p>
<p>到GitHub上搜索hexo主题或者hero自带的主题<a href="https://hexo.io/themes/%EF%BC%8C%E6%89%BE%E4%B8%80%E4%B8%AA%E5%96%9C%E6%AC%A2%E7%9A%84%E3%80%82">https://hexo.io/themes/,找一个喜欢的。</a></p>
<h3 id="1-按照各自的主题文档上面一步步操作即可。"><a href="#1-按照各自的主题文档上面一步步操作即可。" class="headerlink" title="1.按照各自的主题文档上面一步步操作即可。"></a>1.按照各自的主题文档上面一步步操作即可。</h3><p><img src="/posts/353f598a/image-20230421155926605.png" alt="image-20230421155926605"></p>
<p>一般步骤:</p>
<ol>
<li><p>下载解压</p>
</li>
<li><p>放到主题包themes文件夹下</p>
</li>
<li><p>在hero配置文件_config.yml中修改为喜欢主题的名字</p>
</li>
<li><p><code>hero server</code>启动即可访问</p>
</li>
</ol>
<p><img src="/posts/353f598a/image-20230421155959714.png" alt="image-20230421155959714"></p>
<h2 id="六、更新仓库"><a href="#六、更新仓库" class="headerlink" title="六、更新仓库"></a>六、更新仓库</h2><p>本地调试完之后。就可以更新到github上了</p>
<h3 id="1-清理"><a href="#1-清理" class="headerlink" title="1. 清理"></a>1. 清理</h3><p><code>hexo clean</code></p>
<h3 id="2-构建静态文件"><a href="#2-构建静态文件" class="headerlink" title="2. 构建静态文件"></a>2. 构建静态文件</h3><p><code>hexo g</code></p>
<h3 id="3-上传至仓库"><a href="#3-上传至仓库" class="headerlink" title="3. 上传至仓库"></a>3. 上传至仓库</h3><p><code>hexo d</code></p>
<p>访问:</p>
<p><img src="/posts/353f598a/image-20230421160010733.png" alt="image-20230421160010733"></p>
<h2 id="七、写文章"><a href="#七、写文章" class="headerlink" title="七、写文章"></a>七、写文章</h2><p>在站点文件夹中打开 git ,输入如下命令创建文章,其中 我的第一篇博客 为文章的标题。hexo会在source文件夹下创建一个markdowm的文件。这就是你要编写的文章。</p>
<blockquote>
<p>Markdown 是一种可以使用普通文本编辑器编写的 标记语言,通过简单的 标记语法,它可以使普通文本内容具有一定的格式</p>
<p>基于 Markdown 语法的简洁性,它已经成为目前世界上最流行的用于书写博客的语言</p>
</blockquote>
<p><code>hexo new "我的第一篇博客"</code></p>
<p><img src="/posts/353f598a/image-20230421160116449.png" alt="image-20230421160116449"></p>
<p>用软件typora打开直接编写文章</p>
<p><img src="/posts/353f598a/image-20230421160122681.png" alt="image-20230421160122681"></p>
<p>在上传更新到github上立马能够查看到。</p>
<p>清理hexo clean//构建静态文件hexo g//上传至仓库(上传报错多位网络原因,多上传几次即可)<code>hexo d</code></p>
<p><img src="/posts/353f598a/image-20230421160151603.png" alt="image-20230421160151603"></p>
<h3 id="草稿箱"><a href="#草稿箱" class="headerlink" title="草稿箱"></a>草稿箱</h3><p>很多时候我们需要先写成草稿,而暂时不发布出去。draft page就可以满足我们的要求,我们的网站上是看不到草稿文件的。</p>
<p>新建草稿文件<code>hexo new draft b</code></p>
<p>预览草稿文件<code>hexo server --draft</code></p>
<p>发布草稿<code>hexo publish b</code></p>
<h2 id="八、新建页面"><a href="#八、新建页面" class="headerlink" title="八、新建页面"></a>八、新建页面</h2><p>有时我们不满足主题自由的一些页面,希望自己添加一些页面。</p>
<p>我们可以新建页面,新建页面则会在hexo的source中新建该页面文件并生成md文件,这就是你要编辑的博客页了。</p>
<p><code>hexo new page "resouces"</code><br><img src="/posts/353f598a/image-20230421160306199.png" alt="image-20230421160306199"></p>
<p>然后打开主题的配置文件_config.yml,在菜单属性menu中的添加如下(注意不是Hexo的配置文件)</p>
<p>将页面路径联接到页面上去</p>
<p><code>菜单自定义名称:/生成的页面名称</code></p>
<p><img src="/posts/353f598a/image-20230421160331608.png" alt="image-20230421160331608"></p>
<p>当我们点击资源时后会跳转到我们自定义的博客页了(该页面不一样是因为我跟换了主题)</p>
<p><img src="/posts/353f598a/image-20230421160337873.png" alt="image-20230421160337873"></p>
<p>至此Hexo的安装,建站,写博客,更新,新建菜单就全部介绍完毕。</p>
<blockquote>
<p>版权声明:本文为CSDN博主「〆清峰ㄟ」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。<br>原文链接:<a href="https://blog.csdn.net/weixin_45019350/article/details/121901433">https://blog.csdn.net/weixin_45019350/article/details/121901433</a></p>
</blockquote>
]]></content>
<categories>
<category>hexo</category>
</categories>
<tags>
<tag>搭建</tag>
</tags>
</entry>
<entry>
<title>Hexo加密</title>
<url>/posts/881f29f/</url>
<content><![CDATA[<h1 id="给Hexo博客文章加密"><a href="#给Hexo博客文章加密" class="headerlink" title="给Hexo博客文章加密"></a>给Hexo博客文章加密</h1><h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a><strong>安装</strong></h2><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">npm install --save hexo-blog-encrypt</span><br></pre></td></tr></table></figure>
<h2 id="快速使用"><a href="#快速使用" class="headerlink" title="快速使用"></a><strong>快速使用</strong></h2><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">---</span><br><span class="line">title: Hello World</span><br><span class="line">date: 2016-03-30 21:18:02</span><br><span class="line">password: hello</span><br><span class="line">---</span><br></pre></td></tr></table></figure>
<ul>
<li>再使用 <code>hexo clean && hexo g && hexo s</code> 在本地预览加密的文章.</li>
</ul>
<h2 id="设置优先级"><a href="#设置优先级" class="headerlink" title="设置优先级"></a>设置优先级</h2><p>文章信息头 > 按标签加密</p>
<h2 id="高级设置"><a href="#高级设置" class="headerlink" title="高级设置"></a>高级设置</h2><h3 id="文章信息头"><a href="#文章信息头" class="headerlink" title="文章信息头"></a>文章信息头</h3><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">---</span><br><span class="line">title: Hello World</span><br><span class="line">tags:</span><br><span class="line">- 作为日记加密</span><br><span class="line">date: 2016-03-30 21:12:21</span><br><span class="line">password: mikemessi</span><br><span class="line">abstract: 有东西被加密了, 请输入密码查看.</span><br><span class="line">message: 您好, 这里需要密码.</span><br><span class="line">wrong_pass_message: 抱歉, 这个密码看着不太对, 请再试试.</span><br><span class="line">wrong_hash_message: 抱歉, 这个文章不能被校验, 不过您还是能看看解密后的内容.</span><br><span class="line">---</span><br></pre></td></tr></table></figure>
<p>_config.yml<br>示例</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line"># Security</span><br><span class="line">encrypt: # hexo-blog-encrypt</span><br><span class="line"> abstract: 有东西被加密了, 请输入密码查看.</span><br><span class="line"> message: 您好, 这里需要密码.</span><br><span class="line"> tags:</span><br><span class="line"> - {name: tagName, password: 密码A}</span><br><span class="line"> - {name: tagName, password: 密码B}</span><br><span class="line"> wrong_pass_message: 抱歉, 这个密码看着不太对, 请再试试.</span><br><span class="line"> wrong_hash_message: 抱歉, 这个文章不能被校验, 不过您还是能看看解密后的内容.</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h3 id="对博文禁用-Tag-加密"><a href="#对博文禁用-Tag-加密" class="headerlink" title="对博文禁用 Tag 加密"></a>对博文禁用 Tag 加密</h3><p>只需要将博文头部的 password 设置为 “” 即可取消 Tag 加密.</p>
<p>Example:</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">---</span><br><span class="line">title: Callback Test</span><br><span class="line">date: 2019-12-21 11:54:07</span><br><span class="line">tags:</span><br><span class="line"> - A Tag should be encrypted</span><br><span class="line">password: ""</span><br><span class="line">---</span><br><span class="line"></span><br><span class="line">Use a "" to diable tag encryption. </span><br></pre></td></tr></table></figure>
<h3 id="配置优先级"><a href="#配置优先级" class="headerlink" title="配置优先级"></a>配置优先级</h3><p>文章信息头 > _config.yml (站点根目录下的) > 默认配置</p>
<h3 id="关于-Callback-函数"><a href="#关于-Callback-函数" class="headerlink" title="关于 Callback 函数"></a>关于 Callback 函数</h3><p>在部分博客中, 解密后部分元素可能无法正常显示或者表现, 这属于已知问题. 目前的解决办法是通过自行查阅自己的博客中的代码, 了解到在 onload 事件发生时调用了哪些函数, 并将这些函数挑选后写入到博客内容中. 如:</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">---</span><br><span class="line">title: Callback Test</span><br><span class="line">date: 2019-12-21 11:54:07</span><br><span class="line">tags:</span><br><span class="line"> - Encrypted</span><br><span class="line">---</span><br><span class="line"></span><br><span class="line">This is a blog to test Callback functions. You just need to add code at the last of your post like following:</span><br><span class="line"></span><br><span class="line">It will be called after the blog decrypted.</span><br><span class="line"></span><br><span class="line"><script></span><br><span class="line"> // 添加一个 script tag 与代码在文章末尾.</span><br><span class="line"> alert("Hello World");</span><br><span class="line"></script> </span><br></pre></td></tr></table></figure>
<p>例子在: Callback 例子.</p>
<h3 id="解密后的触发事件"><a href="#解密后的触发事件" class="headerlink" title="解密后的触发事件"></a>解密后的触发事件</h3><p>感谢 @f-dong, 我们现在会在解密完成后触发一个 hexo-blog-decrypt 事件, 你们可以编写 callback 来监听该事件.</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">// trigger event</span><br><span class="line">var event = new Event('hexo-blog-decrypt');</span><br><span class="line">window.dispatchEvent(event); </span><br></pre></td></tr></table></figure>
<h3 id="对-TOC-进行加密"><a href="#对-TOC-进行加密" class="headerlink" title="对 TOC 进行加密"></a>对 TOC 进行加密</h3><p>如果你有一篇文章使用了 TOC,你需要修改模板的部分代码。这里用 landscape 作为例子:</p>
<p>你可以在 hexo/themes/landscape/layout/_partial/article.ejs 找到 article.ejs。<br>然后找到 <% post.content %> 这段代码,通常在30行左右。<br>使用如下的代码来替代它:</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line"><% if(post.toc == true){ %></span><br><span class="line"> <div id="toc-div" class="toc-article" <% if (post.encrypt == true) { %>style="display:none" <% } %>></span><br><span class="line"> <strong class="toc-title">Index</strong></span><br><span class="line"> <% if (post.encrypt == true) { %></span><br><span class="line"> <%- toc(post.origin, {list_number: true}) %></span><br><span class="line"> <% } else { %></span><br><span class="line"> <%- toc(post.content, {list_number: true}) %></span><br><span class="line"> <% } %></span><br><span class="line"> </div></span><br><span class="line"><% } %></span><br><span class="line"><%- post.content %> </span><br></pre></td></tr></table></figure>
<h3 id="禁用-Log"><a href="#禁用-Log" class="headerlink" title="禁用 Log"></a>禁用 Log</h3><p>If you want to disable the logging, you can add a silent property in _config.yml and set it to true. 如果你想要禁止使用 Log, 你可以在 _config.yml 中增加一个 silent 属性, 并将其设置为 true.</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line"># Security</span><br><span class="line">encrypt: # hexo-blog-encrypt</span><br><span class="line"> silent: true</span><br></pre></td></tr></table></figure>
<p>这样就会禁止如 INFO hexo-blog-encrypt: encrypting “{Blog Name}” based on Tag: “EncryptedTag”. 的日志.</p>
<h3 id="加密主题"><a href="#加密主题" class="headerlink" title="加密主题"></a>加密主题</h3><p>之前, 我们尝试使用 template 关键字来让用户能修改自己的主题. 后来发现真不是一个好主意. 所以我们现在引入了主题: theme 关键字.</p>
<p>你可以简单的使用 theme 在 _config.yml 里或者文章头, 如下:</p>
<h3 id="文章信息头-1"><a href="#文章信息头-1" class="headerlink" title="文章信息头"></a>文章信息头</h3><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">---</span><br><span class="line">title: Hello World</span><br><span class="line">tags:</span><br><span class="line">- 作为日记加密</span><br><span class="line">date: 2016-03-30 21:12:21</span><br><span class="line">password: mikemessi</span><br><span class="line">abstract: 有东西被加密了, 请输入密码查看.</span><br><span class="line">message: 您好, 这里需要密码.</span><br><span class="line">theme: xray</span><br><span class="line">wrong_pass_message: 抱歉, 这个密码看着不太对, 请再试试.</span><br><span class="line">wrong_hash_message: 抱歉, 这个文章不能被校验, 不过您还是能看看解密后的内容.</span><br><span class="line">---</span><br></pre></td></tr></table></figure>
<p>在 _config.yml<br>示例</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line"># Security</span><br><span class="line">encrypt: # hexo-blog-encrypt</span><br><span class="line"> abstract: 有东西被加密了, 请输入密码查看.</span><br><span class="line"> message: 您好, 这里需要密码.</span><br><span class="line"> tags:</span><br><span class="line"> - {name: tagName, password: 密码A}</span><br><span class="line"> - {name: tagName, password: 密码B}</span><br><span class="line"> theme: xray</span><br><span class="line"> wrong_pass_message: 抱歉, 这个密码看着不太对, 请再试试.</span><br><span class="line"> wrong_hash_message: 抱歉, 这个文章不能被校验, 不过您还是能看看解密后的内容.</span><br></pre></td></tr></table></figure>
<blockquote>
<p>原文链接:<a href="https://blog.csdn.net/njpkhuan/article/details/132826408">https://blog.csdn.net/njpkhuan/article/details/132826408</a></p>
</blockquote>
]]></content>
<categories>
<category>hexo</category>
</categories>
<tags>
<tag>搭建</tag>
<tag>插件</tag>
<tag>hexo-blog-encrypt</tag>
</tags>
</entry>
<entry>
<title>Hexo搭配Typora图片问题</title>
<url>/posts/e5bae2ba/</url>
<content><![CDATA[<h1 id="Hexo搭配Typora图片问题"><a href="#Hexo搭配Typora图片问题" class="headerlink" title="Hexo搭配Typora图片问题"></a>Hexo搭配Typora图片问题</h1><h2 id="第一步:更改Hexo根目录-config-yml文件"><a href="#第一步:更改Hexo根目录-config-yml文件" class="headerlink" title="第一步:更改Hexo根目录_config.yml文件"></a>第一步:更改Hexo根目录_config.yml文件</h2><p>自动为文章中的图片提供绝对路径,需要设置 <code>_config.yml</code></p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">post_asset_folder:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure>
<p>比如新建一片博客名为 hexo-plugin,那么在创建文章 md 文件的同时会创建一个 hexo-plugin 的目录,文章对应的图片放入这个目录就行。</p>
<h2 id="第二步:安装插件hexo-asset-image。"><a href="#第二步:安装插件hexo-asset-image。" class="headerlink" title="第二步:安装插件hexo-asset-image。"></a>第二步:安装插件<code>hexo-asset-image</code>。</h2><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">在项目根目录下执行</span></span><br><span class="line">npm install https://github.com/xcodebuild/hexo-asset-image.git --save</span><br></pre></td></tr></table></figure>
<p>完成上述配置后,在使用命令<code>hexo new post</code>新建文章时,将会在<code>source/_posts</code>目录下创建一个与文章同名的目录。</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">hexo new post "测试文章"</span><br><span class="line">|____scaffolds</span><br><span class="line">|____source</span><br><span class="line">| |_____posts</span><br><span class="line">| | |____测试文章.md</span><br><span class="line">| | |____测试文章 # 与文章同名的目录,用于保存在文章中引入的本地图片资源</span><br><span class="line">|____themes</span><br></pre></td></tr></table></figure>
<h2 id="第三步:更改Typora设置"><a href="#第三步:更改Typora设置" class="headerlink" title="第三步:更改Typora设置"></a>第三步:更改Typora设置</h2><p>进入软件-文件-偏好设置</p>
<p><img src="/posts/e5bae2ba/image-20230421162303925.png" alt="image-20230421162303925"></p>
<p>Typora 可以将图像设为 <code>./${filename}</code> 便可自动适配</p>
<p>更改图像插入图片设置,方便把截图直接粘贴到.md文件里(这里直接按照下图配置就行)</p>
<p>如下图:</p>
<p><img src="/posts/e5bae2ba/image-20230427152628646.png" alt="image-20230427152628646"></p>
<h2 id="更新后上传到gitee"><a href="#更新后上传到gitee" class="headerlink" title="更新后上传到gitee"></a>更新后上传到gitee</h2><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">hexo g</span><br><span class="line">hexo d</span><br></pre></td></tr></table></figure>
<p>部署</p>
<p><img src="/posts/e5bae2ba/image-20230421164707366.png" alt="image-20230421164707366"></p>
<p>展示成果:</p>
<p><img src="/posts/e5bae2ba/image-20230421170923243.png" alt="image-20230421170923243"></p>
<h2 id="原理说明"><a href="#原理说明" class="headerlink" title="原理说明"></a>原理说明</h2><p>显然,在hexo中引入图片的方式稍微有点繁琐,即:必须在<code>_post</code>目录下新建一个与文章同名的目录,然后将需要引用的图片文件都放在该目录中。<br>还好使用插件<code>hexo-asset-image</code>能够帮助我们自动创建图片目录(每次都会自动创建,如果在文章中不需要引用图片资源,可以手动将该目录删除)。</p>
<p>那么,为什么需要将文章引用的图片放置在与文章同名的目录呢?<br>原因是:在执行<code>hexo g</code>命令的时候会将文章转换为一个<code>index.html</code>文件,该文件路径为<code>public/年/月/日/文章名称/index.html</code>,同时也会将文章中引用的图片文件拷贝到与<code>index.html</code>文件相同的目录中。<br>另外,转换后的<code>index.html</code>文件保存路径中有一个<code>年/月/日</code>,这是在项目配置文件<code>_config.yml</code>的<code>permalink</code>参数中配置的,默认值为:</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">permalink:</span> <span class="string">:year/:month/:day/:title/</span></span><br></pre></td></tr></table></figure>
<p>【参考】<br><a href="https://leay.net/2019/12/25/hexo/">https://leay.net/2019/12/25/hexo/</a> Hexo 引用本地图片以及引用本地任意位置图片的一点思路<br><a href="https://blog.csdn.net/LiuChengYu520/article/details/82657407">https://blog.csdn.net/LiuChengYu520/article/details/82657407</a> hexo-asset-image使用方法<br><a href="https://blog.glwsq.cn/2019/10/22/41cc6f18/">https://blog.glwsq.cn/2019/10/22/41cc6f18/</a> hexo-asset-image【让本地和网页都正常显示图片】<br><a href="http://www.itomtan.com/2017/09/29/the-problem-when-use-post-asset-folder/">http://www.itomtan.com/2017/09/29/the-problem-when-use-post-asset-folder/</a> Hexo开启post_asset_folder后, 安装hexo-asset-image,不起作用的问题</p>
<blockquote>
<p>转自:</p>
<p><a href="https://www.cnblogs.com/nuccch/p/17010471.html">https://www.cnblogs.com/nuccch/p/17010471.html</a></p>
</blockquote>
]]></content>
<categories>
<category>hexo</category>
</categories>
<tags>
<tag>搭建</tag>
<tag>插件</tag>
<tag>hexo-asset-image</tag>
</tags>
</entry>
<entry>
<title>JAVA计算大量数据接口怎么做</title>
<url>/posts/28c0f33e/</url>
<content><![CDATA[<h1 id="JAVA大量数据接口怎么做(原创)"><a href="#JAVA大量数据接口怎么做(原创)" class="headerlink" title="JAVA大量数据接口怎么做(原创)"></a><strong>JAVA大量数据接口怎么做(原创)</strong></h1><h2 id="Mysql数据同步到Redis"><a href="#Mysql数据同步到Redis" class="headerlink" title="Mysql数据同步到Redis"></a><strong>Mysql数据同步到Redis</strong></h2><p>①判断redis是否存在(RedisTemplate),使用redisTemplate.hasKey(key);,如果不存在,redis储存mysql中的数据。</p>
<p>②③取出集合进行处理</p>
<p>④处理后的数据储存到redis中,接口根据权限获取数据。 </p>
<p hidden>![img](./img/wps1-1682479201608-1.jpg)</p>
<h2 id="Mysql每天定时数据同步到redis"><a href="#Mysql每天定时数据同步到redis" class="headerlink" title="Mysql每天定时数据同步到redis"></a><strong>Mysql每天定时数据同步到redis</strong></h2><p>①查询出mysql所有数据为集合a</p>
<p>②查询出redis所有数据为集合b</p>
<p>③选出a与b的差集(mysql有redis没有的数据)</p>
<p>④差集保存到redis中</p>
<p>⑤选出b与a的差集(redis有mysql没有的数据)</p>
<p>⑥差集删除redis,刷新redis保存的集合。</p>
<p>优点:如果手动修改了数据,每天自动恢复与同步,改动小,速度快。</p>
<p hidden>![img](./img/wps2-1682479201608-2.jpg) </p>
<p>removeAll效率低(解决办法:实用工具类ListUtil.removeAll(集合1,集合2))</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span> ZHAI</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@date</span> 2021/11/15 11:12</span></span><br><span class="line"><span class="comment"> **/</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ListUtil</span> {</span><br><span class="line"></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">static</span> <T> List<T> <span class="title function_">removeAll</span><span class="params">(<span class="keyword">final</span> List<T> source, <span class="keyword">final</span> List<T> destination)</span> {</span><br><span class="line"></span><br><span class="line"> List<T> result = <span class="keyword">new</span> <span class="title class_">ArrayList</span><>();</span><br><span class="line"> Set<T> destinationSet = <span class="keyword">new</span> <span class="title class_">HashSet</span><T>(destination);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span>(T t : source) {</span><br><span class="line"> <span class="keyword">if</span> (!destinationSet.contains(t)) {</span><br><span class="line"> result.add(t);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> result;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h1 id="注(踩过的坑-):"><a href="#注(踩过的坑-):" class="headerlink" title="注(踩过的坑-_-||):"></a>注(踩过的坑-_-||):</h1><ol>
<li>不能在循环里面执行sql语句(解决办法:数据库取出数据后,使用java循环处理数据)</li>
<li>不能在java中过多的new,非常占用内存,大量的数据会出现程序内存溢出,需要重启解决(解决办法:集合可用lambda 表达式,例如:List<CfgDistrictListDTO> dtos3 = list.stream().filter(s -> s.getDistrictCode().equals(l3.getCode())).collect(Collectors.toList());)</CfgDistrictListDTO></li>
<li>数据库中除了等于号其他少用,只用作查询、表关联等操作,不进行数据处理。</li>
</ol>
]]></content>
<categories>
<category>代码</category>
</categories>
<tags>
<tag>java</tag>
<tag>redis</tag>
<tag>优化</tag>
</tags>
</entry>
<entry>
<title>Linux使用curl发起post请求的常用方式</title>
<url>/posts/c66d13f4/</url>
<content><![CDATA[<h1 id="Linux-使用curl发起post请求的4个常用方式"><a href="#Linux-使用curl发起post请求的4个常用方式" class="headerlink" title="Linux 使用curl发起post请求的4个常用方式"></a>Linux 使用curl发起post请求的4个常用方式</h1><h2 id="引言"><a href="#引言" class="headerlink" title="引言"></a>引言</h2><p>curl是一种命令行实用程序,用于使用一种受支持的协议,从远程服务器传输数据,或将数据传输到远程服务器。默认情况下,已安装在macOS和大多数Linux发行版上。</p>
<p>开发人员可以使用cURL来测试API接口,查看响应头和发出HTTP请求。</p>
<p>在本文中,我们将解释如何使用cURL发出POST请求。HTTP POST方法用于将数据发送到远程服务器</p>
<h2 id="发出POST请求"><a href="#发出POST请求" class="headerlink" title="发出POST请求"></a>发出POST请求</h2><p>curl 发出POST请求的命令的一般形式如下:</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">curl -X POST [options] [URL]</span><br></pre></td></tr></table></figure>
<p>该<code>-X</code>选项指定与远程服务器通信时将使用哪种HTTP请求方法。</p>
<p>请求主体的类型由其Content-Type标头指定。通常,POST请求是通过HTML表单发送的。发送到表单的数据通常以<code>multipart/form-data</code>或<code>application/x-www-form-urlencoded</code>内容类型进行编码。</p>
<p>要创建POST请求,请使用<code>-F</code>选项,然后使用<code>key=value</code>配对。下面的示例说明如何向具有“name”和“email”字段的表单发出POST请求:</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">curl -X POST -F 'name=Jason' -F 'email=jason@example.com' https://example.com/contact.php</span><br></pre></td></tr></table></figure>
<p>使用该<code>-F</code>选项时,<code>curl</code>使用 Content-Type 为“<code>multipart/form-data</code>”发送数据。</p>
<p>发出POST请求的另一种方法是使用<code>-d</code>选项。这导致<code>curl</code>使用<code>application/x-www-form-urlencoded</code>Content-Type发送数据。</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">curl -X POST -d 'name=Jason' -d 'email=jason@example.com' https://example.com/contact.php</span><br></pre></td></tr></table></figure>
<p>如果<code>-d</code>多次使用该选项,则可以使用<code>&</code>符号合并数据:</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">curl -X POST -d 'name=Jason&email=jason@example.com' https://example.com/contact.php </span><br></pre></td></tr></table></figure>
<h2 id="指定Content-Type"><a href="#指定Content-Type" class="headerlink" title="指定Content-Type"></a>指定Content-Type</h2><p>要设置特定的标题或Content-Type,请使用<code>-H</code>选项。以下命令将POST请求类型设置为,<code>application/json</code>并发送JSON对象:</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">curl -X POST -H "Content-Type: application/json" -d '{"name": "Jason", "email": "jason@example.com"}' https://example/contact</span><br></pre></td></tr></table></figure>
<h2 id="文件上传"><a href="#文件上传" class="headerlink" title="文件上传"></a>文件上传</h2><p>要使用curl来上传文件,只需在文件位置之前添加 at 符号。该文件可以是任何支持的类型。</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">curl -X POST -F 'image=@/home/user/Pictures/wallpaper.jpg' http://example.com/upload</span><br></pre></td></tr></table></figure>
<h2 id="写在最后"><a href="#写在最后" class="headerlink" title="写在最后"></a>写在最后</h2><p>本文通过实例展示了Linux下的curl工具的POST使用方法,可轻松应对表单提交,文件上传等等情形,非常实用,也是线上诊断的利器。</p>
<p>Happy ending :-)</p>
]]></content>
<categories>
<category>linux</category>
</categories>
</entry>
<entry>
<title>OpenVPN同时连多个vpn</title>
<url>/posts/74214fa/</url>
<content><![CDATA[<h1 id="方法一、OpenVPN同时连多个vpn(如果不好使用方法二)"><a href="#方法一、OpenVPN同时连多个vpn(如果不好使用方法二)" class="headerlink" title="方法一、OpenVPN同时连多个vpn(如果不好使用方法二)"></a>方法一、OpenVPN同时连多个vpn(如果不好使用方法二)</h1><p>当连接多个vpn时,OpenVPN报错:</p>
<p>All TAP-Windows adapters on this system are currently in use</p>
<p>xxxxxxxxxx List<BroadcastRuleTableDTO> broadcastRuleTableDTOS = convertList2List(broadcastRuleDTOS, BroadcastRuleTableDTO.class);java</BroadcastRuleTableDTO></p>
<p> 系统网络适配器已经被占用,导致启动不成功!</p>
<p><strong>解决方法:</strong></p>
<p><strong>1、确认安装VPN客户端的时候,已勾选 TAP Virtual Ethernet Adapter</strong></p>
<p><img src="/posts/74214fa/1684285445597.jpg" alt="img"></p>
<p><strong>2、如果是默认路径安装的话,打开:C:\Program Files\TAP-Windows\bin,显示如下图</strong></p>
<p><img src="/posts/74214fa/1684285462942.png" alt="img"></p>
<p><strong>3、以管理员身份运行,双击运行</strong></p>
<p>略</p>
<p><strong>4、设备管理查看,网络适配器,是否多出一块虚拟的网卡设备</strong></p>
<p><img src="/posts/74214fa/918540-20190530163231985-1525969970.jpg" alt="img"></p>
<p><strong>5、再去重新同时连接两个VPN,此时会发现,已成功支持同时登陆两个!</strong></p>
<p><img src="/posts/74214fa/918540-20190530163543123-1205137276.png" alt="img"></p>
<p><strong>注意:</strong></p>
<p> <strong>同时需要登陆多少个VPN客户端,就需要创建多少个虚拟网络适配器,创建方法同上!</strong></p>
<blockquote>
<p>转载:<a href="http://www.cnblogs.com/ygbh/p/10950439.html">www.cnblogs.com/ygbh/p/10950439.html</a></p>
</blockquote>
<h1 id="方法二、Windows10系统添加虚拟网卡"><a href="#方法二、Windows10系统添加虚拟网卡" class="headerlink" title="方法二、Windows10系统添加虚拟网卡"></a>方法二、Windows10系统添加虚拟网卡</h1><p>虚拟网卡相当于在系统中模拟了一个网卡,可以供我们做网络桥接。<br>1、在【计算机】图标上我们点击右键,紧跟着选择【设备管理器】。在PC图标上点击右键,选择【添加过时硬件】选项。</p>
<p><img src="/posts/74214fa/t_70-1692670860806-6.png" alt="img"></p>
<p><img src="/posts/74214fa/t_70-1692670854335-3.png" alt="img"></p>
<p>2、接着大家点选【安装我手动从列表选择的硬件】选项,并且点击【下一步】。</p>
<p><img src="/posts/74214fa/image-20230822102021033.png" alt="img"><br>3、其次选择【网络适配器】,然后点击【下一步】。</p>
<p><img src="/posts/74214fa/image-20230822102035017.png" alt="img"></p>
<p>4、在厂商处选择大家选择Microsoft,网络适配器处我们选择【TAP-Windows Provider V9】选项,紧接着点击【下一步】。</p>
<p><img src="/posts/74214fa/image-20230822102131545.png" alt="img"></p>
<p>5、如果适配器带感叹号重启就行</p>
<p><img src="/posts/74214fa/image-20230822102258176.png" alt="img"></p>
]]></content>
<categories>
<category>工具</category>
</categories>
<tags>
<tag>vpn</tag>
</tags>
</entry>
<entry>
<title>hexo+valine博客的评论功能</title>
<url>/posts/ba39e0a3/</url>
<content><![CDATA[<h1 id="hexo博客的评论功能"><a href="#hexo博客的评论功能" class="headerlink" title="hexo博客的评论功能"></a>hexo博客的评论功能</h1><h2 id="1-这里推荐的评论功能插件为valine"><a href="#1-这里推荐的评论功能插件为valine" class="headerlink" title="1.这里推荐的评论功能插件为valine"></a>1.这里推荐的评论功能插件为<a href="https://valine.js.org/">valine</a></h2><p>官网:<a href="https://valine.js.org/">https://valine.js.org/</a> </p>
<p>注册登录网站:<a href="https://leancloud.cn/">https://leancloud.cn/</a> </p>
<h2 id="2-去leancloud注册"><a href="#2-去leancloud注册" class="headerlink" title="2.去leancloud注册"></a>2.去<a href="https://leancloud.cn/">leancloud</a>注册</h2><p>注册完成后去创建应用,选择开发版就可以了。(需要实名登记才能创建应用)</p>
<p><img src="/posts/ba39e0a3/1682556265705.jpg" alt="1682556265705"></p>
<h2 id="3-获取-appkey-和-appid"><a href="#3-获取-appkey-和-appid" class="headerlink" title="3.获取 appkey 和 appid"></a>3.获取 appkey 和 appid</h2><p>创建完成应用后,<strong>进入应用->设置->应用 key,找到相应的 appkey 和 appid。</strong></p>
<p><img src="/posts/ba39e0a3/1682556287714.jpg" alt="1682556287714"></p>
<h2 id="4-配置主题文件-config-yml"><a href="#4-配置主题文件-config-yml" class="headerlink" title="4.配置主题文件_config.yml"></a>4.配置主题文件_config.yml</h2><p>搜索 valine,一般可看到如下,将 enbled:true, 并填写**appid **和 <strong>appkey</strong>(从 leancloud 中获取的 appid 和 appkey)。</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="comment"># The configuration of the Valine comment module is not activated by default.</span></span><br><span class="line"><span class="comment"># To use it, activate the configuration item and set appId and appKey.</span></span><br><span class="line"><span class="comment"># Valine 评论模块的配置,默认为不激活,如要使用,就请激活该配置项,并设置 appId 和 appKey.</span></span><br><span class="line"><span class="attr">valine:</span></span><br><span class="line"> <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line"> <span class="attr">appId:</span></span><br><span class="line"> <span class="attr">appKey:</span></span><br><span class="line"> <span class="attr">notify:</span> <span class="literal">false</span></span><br><span class="line"> <span class="attr">verify:</span> <span class="literal">false</span></span><br><span class="line"> <span class="attr">visitor:</span> <span class="literal">true</span></span><br><span class="line"> <span class="attr">avatar:</span> <span class="string">'mp'</span> <span class="comment"># Gravatar style : mp/identicon/monsterid/wavatar/retro/hide</span></span><br><span class="line"> <span class="attr">pageSize:</span> <span class="number">10</span></span><br><span class="line"> <span class="attr">placeholder:</span> <span class="string">'just go go'</span> <span class="comment"># Comment Box placeholder</span></span><br><span class="line"> <span class="attr">background:</span> <span class="string">/medias/comment_bg.png</span></span><br></pre></td></tr></table></figure>
<p>复制</p>
<h2 id="5-配置域名"><a href="#5-配置域名" class="headerlink" title="5.配置域名"></a>5.配置<a href="https://cloud.tencent.com/act/pro/domain-sales?from=20065&from_column=20065">域名</a></h2><p>在 Leancloud -> 设置 -> 安全中心 -> Web 安全域名 把你的域名加进去.</p>
<p><img src="/posts/ba39e0a3/1682556302951.jpg" alt="1682556302951"></p>
<h2 id="6-重启你的博客"><a href="#6-重启你的博客" class="headerlink" title="6.重启你的博客"></a>6.重启你的博客</h2><p>大功告成!!</p>
<p>评论数据在leancloud编辑</p>
<p><img src="/posts/ba39e0a3/image-20230427150229872.png" alt="image-20230427150229872"></p>
<blockquote>
<p>转自:腾讯云开发者社区</p>
<p><a href="https://cloud.tencent.com/developer/article/1953268">https://cloud.tencent.com/developer/article/1953268</a></p>
</blockquote>
]]></content>
<categories>
<category>hexo</category>
</categories>
<tags>
<tag>搭建</tag>
<tag>插件</tag>
</tags>
</entry>
<entry>
<title>hexo-abbrlink和hexo-asset-image插件冲突</title>
<url>/posts/a5a91285/</url>
<content><![CDATA[<h1 id="前提条件"><a href="#前提条件" class="headerlink" title="前提条件"></a>前提条件</h1><h2 id="1-hexo-abbrlink"><a href="#1-hexo-abbrlink" class="headerlink" title="1.hexo-abbrlink"></a>1.hexo-abbrlink</h2><p>可以优化博客路径,全自动生成惟一的不带中文的博客链接,默认路径 <code>https://xcmaster.com/2022/07/07/hexo必装插件</code>,还会带上标题,这款插件可以将路径优化为 <code>https://xcmaster.com/posts/51727</code> 等等,还支持 16进制。</p>
<p>安装</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">npm install hexo-abbrlink --save</span><br></pre></td></tr></table></figure>
<p><code>_config,yml</code> 加入配置</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">permalink: posts/:abbrlink.html # 此处可以自己设置,也可以直接使用 :/abbrlink</span><br><span class="line">abbrlink:</span><br><span class="line"> alg: crc32 #算法: crc16(default) and crc32</span><br><span class="line"> rep: hex #进制: dec(default) and hex</span><br></pre></td></tr></table></figure>
<p>详情请看 github: <a href="https://github.com/rozbo/hexo-abbrlink">https://github.com/rozbo/hexo-abbrlink</a></p>
<h2 id="2-hexo-asset-image"><a href="#2-hexo-asset-image" class="headerlink" title="2.hexo-asset-image"></a>2.hexo-asset-image</h2><p>安装</p>
<p><code> npm install https://github.com/xcodebuild/hexo-asset-image.git --save</code></p>
<p>自动为文章中的图片提供绝对路径,需要设置 <code>_config.yml</code></p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">post_asset_folder:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure>
<p>比如新建一片博客名为 hexo-plugin,那么在创建文章 md 文件的同时会创建一个 hexo-plugin 的目录,文章对应的图片放入这个目录就行。</p>
<p>Typora 可以将图像设为 <code>./${filename}</code> 便可自动适配</p>
<h1 id="使用hexo-abbrlink及解决与hexo-asset-image不适配的问题修复"><a href="#使用hexo-abbrlink及解决与hexo-asset-image不适配的问题修复" class="headerlink" title="使用hexo-abbrlink及解决与hexo-asset-image不适配的问题修复"></a>使用hexo-abbrlink及解决与hexo-asset-image不适配的问题修复</h1><h2 id="修改-config文件"><a href="#修改-config文件" class="headerlink" title="修改_config文件"></a>修改_config文件</h2><p>配置博客站点配置文件_config.yml:</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="comment">#------------可以优化博客路径https://github.com/rozbo/hexo-abbrlink---------------#</span></span><br><span class="line"><span class="attr">permalink:</span> <span class="string">posts/:abbrlink/</span> <span class="comment"># 此处可以自己设置,也可以直接使用 :/abbrlink</span></span><br><span class="line"><span class="attr">abbrlink:</span></span><br><span class="line"> <span class="attr">alg:</span> <span class="string">crc32</span> <span class="comment">#算法: crc16(default) and crc32</span></span><br><span class="line"> <span class="attr">rep:</span> <span class="string">hex</span> <span class="comment">#进制: dec(default) and hex</span></span><br></pre></td></tr></table></figure>
<h2 id="修改index-js文件"><a href="#修改index-js文件" class="headerlink" title="修改index.js文件"></a>修改index.js文件</h2><p>修改下面的文件\node_modules\hexo-asset-image\index.js</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">根目录</span><br><span class="line"> |node_modules</span><br><span class="line"> | |__hexo-asset-image</span><br><span class="line"> | | |__index.js</span><br></pre></td></tr></table></figure>
<ol>
<li>在源码的12行附近<code>var link = data.permalink;</code>这一行的下面,添加 一行<code>var abbrlink = data.abbrlink</code><br>(意思是定义一个变量abbrlink)</li>
<li>在44行附近,源码的<code>$(this).attr('src', config.root + link + src);</code>这一行,修改 为下面一行:<code>$(this).attr('src', config.root + 'posts/' + abbrlink + '/' + src);</code>//适配abbrlink<br>(意思是生成的图片链接中,拼接abbrlink)</li>
</ol>
<p>然后重新<code>hexo clean</code> 和 <code>hexo g</code>,即可生效。<br>_posts文件夹下的文章,按照自己喜欢的方式整理,生成的链接是正常的,在typora中可以正常显示。</p>
<p>参考链接:</p>
<p><a href="https://github.com/rozbo/hexo-abbrlink/issues/19">https://github.com/rozbo/hexo-abbrlink/issues/19</a></p>
<p><a href="https://www.shangmayuan.com/a/8863defeb3264ffd84335151.html">https://www.shangmayuan.com/a/8863defeb3264ffd84335151.html</a></p>
<blockquote>
<p>版权声明:本文为CSDN博主「zino00」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。<br>原文链接:<a href="https://blog.csdn.net/zino00/article/details/122730090">https://blog.csdn.net/zino00/article/details/122730090</a></p>
</blockquote>
]]></content>
<categories>
<category>hexo</category>
</categories>
<tags>
<tag>插件</tag>
</tags>
</entry>
<entry>
<title>java什么叫事务,事务有什么用</title>
<url>/posts/e55b8c2b/</url>
<content><![CDATA[<h1 id="java什么叫事务,事务有什么用"><a href="#java什么叫事务,事务有什么用" class="headerlink" title="java什么叫事务,事务有什么用"></a><strong>java什么叫事务,事务有什么用</strong></h1><p>比如微信转账,A给B转账,A扣钱B价钱这个操作是绑定在一起的,一个完成了另一个没完成会出现问题,两个步骤其实是一个事务,必须是都完成,或者都不完成</p>
<h2 id="什么是事务?"><a href="#什么是事务?" class="headerlink" title="什么是事务?"></a><strong>什么是事务?</strong></h2><p>事务(Transaction),一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用户程序的执行所引起,并用形如begin transaction和end transaction语句(或函数调用)来界定。事务由事务开始(begin transaction)和事务结束(end transaction)之间执行的全体操作组成。</p>
<h2 id="为什么要事务?"><a href="#为什么要事务?" class="headerlink" title="为什么要事务?"></a><strong>为什么要事务?</strong></h2><p>事务是为解决数据安全操作提出的,事务控制实际上就是控制数据的安全访问。</p>
<p>用一个简单例子说明:银行转帐业务,账户A要将自己账户上的1000元转到B账户下面,A账户余额首先要减去1000元,然后B账户要增加1000元。假如在中间网络出现了问题,A账户减去1000元已经结束,B因为网络中断而操作失败,那么整个业务失败,必须做出控制,要求A账户转帐业务撤销。这才能保证业务的正确性,完成这个操走就需要事务,将A账户资金减少和B账户资金增加放到同一个事务里,要么全部执行成功,要么全部撤销,这样就保证了数据的安全性。</p>
<h2 id="事务的4个特性(ACID):"><a href="#事务的4个特性(ACID):" class="headerlink" title="事务的4个特性(ACID):"></a><strong>事务的4个特性(ACID):</strong></h2><ol>
<li><p>原子性(atomicity):事务是数据库的逻辑工作单位,而且是必须是原子工作单位,对于其数据修改,要么全部执行,要么全部不执行。</p>
</li>
<li><p>一致性(consistency):事务在完成时,必须是所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。(实例:转账,两个账户余额相加,值不变。)</p>
</li>
<li><p>隔离性(isolation):一个事务的执行不能被其他事务所影响。</p>
</li>
<li><p>持久性(durability):一个事务一旦提交,事物的操作便永久性的保存在DB中。即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。</p>
</li>
</ol>
<h2 id="Java有几种类型的事务?"><a href="#Java有几种类型的事务?" class="headerlink" title="Java有几种类型的事务?"></a><strong>Java有几种类型的事务?</strong></h2><p>Java事务的类型有三种:JDBC事务、JTA(Java Transaction API)事务、容器事务。</p>
<h1 id="transactionTemplate用法"><a href="#transactionTemplate用法" class="headerlink" title="transactionTemplate用法"></a><strong>transactionTemplate用法</strong></h1><p>业务上需要两个表一起更新的时候最好加事务,单个表不用,数据库有默认的事务隔离</p>
<p>举例子,比如说转账, 从A账户转移到B账户, A减去金额,则同时B需要加上金额</p>
<p>在类似的场景下,涉及到两个表相关联的更新,要加上事务</p>
<p>但是千万注意!!!不要在耗时长的操作里面加事务,事务粒度也要适中</p>
<h2 id="transactionTemplate"><a href="#transactionTemplate" class="headerlink" title="@transactionTemplate"></a><strong>@transactionTemplate</strong></h2><p>spring提供了@transactionTemplate 方法级别的事务注解,使用方便,但是 方法级别的事务,粒度不够细。</p>
<p>比如说如下场景,</p>
<p><img src="/posts/e55b8c2b/image-20230421144023243.png" alt="image-20230421144023243"></p>
<p>方法里面有三个数据库操作,一个查询,两个更新</p>
<p>如果用方法级别的@transactionTemplate 注解 ,则把该方法里面所有涉及到的操作都置于事务范围内。</p>
<h2 id="spring的TransactionTemplate"><a href="#spring的TransactionTemplate" class="headerlink" title="spring的TransactionTemplate"></a><strong>spring的TransactionTemplate</strong></h2><p> 因此 可以使用spring提供的TransactionTemplate 工具类来控制细粒度事务</p>
<p>使用spring的TransactionTemplate </p>
<p>先注入</p>
<p><img src="/posts/e55b8c2b/image-20230421144040504.png" alt="image-20230421144040504"></p>
<p> <img src="/posts/e55b8c2b/image-20230421144049750.png" alt="image-20230421144049750"></p>
<p>查看TransactionTemplate 源码里面,核心方法是execute</p>
<p><img src="/posts/e55b8c2b/image-20230421144101099.png" alt="image-20230421144101099"></p>
<p>execute方法里面的核心又是action.doInTransaction(status);</p>
<p><img src="/posts/e55b8c2b/image-20230421144116559.png" alt="image-20230421144116559"></p>
<p>这个就是我们的业务操作,然后最下面this.transactionManager.commit(status); 提交事务</p>
<img src="/posts/e55b8c2b/image-20230421144129590.png">
<p>因此 我们需要把action.doInTransaction(status); 这个操作传入到TransactionTemplate里面去</p>
<p>具体使用如下,实现了一个 TransactionCallback的匿名对象 重写它的 doInTransaction方法 把我们的操作放进去即可</p>
<p>transactionTemplate.execute(new TransactionCallback(){@Overridepublic Boolean doInTransaction(TransactionStatus status) {capitalImportDOMapper.updateByExample(capitalImport,modifyEx);capitalDetailDOMapper.updateByExample(capitalDetailDO,capitalDetailDOExample);return Boolean.TRUE;}}); </p>
<p>也可以通过lamada表达式来简化 ,因为这个TransactionCallback接口是个函数式接口</p>
<p><img src="/posts/e55b8c2b/image-20230421144148372.png" alt="image-20230421144148372"></p>
]]></content>
<categories>
<category>代码</category>
</categories>
<tags>
<tag>java</tag>
<tag>事务</tag>
<tag>mysql</tag>
</tags>
</entry>
<entry>
<title>java如何根据IP获取当前区域天气信息详解</title>
<url>/posts/7deee04a/</url>
<content><![CDATA[<p>大致思路是客户端发起请求,我们首先根据请求获取到外网IP,然后再根据外网IP获取到用户所在城市,最后根据城市获取到天气信息</p>
<h5 id="获取外网IP"><a href="#获取外网IP" class="headerlink" title="获取外网IP"></a>获取外网IP</h5><p>万网获取外网IP地址:<a href="http://www.net.cn/static/cust%E2%80%A6">www.net.cn/static/cust…</a></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>:获取客户端外网ip 此方法要接入互联网才行,内网不行</span></span><br><span class="line"><span class="comment"> **/</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> String <span class="title function_">getPublicIp</span><span class="params">()</span> {</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="type">String</span> <span class="variable">path</span> <span class="operator">=</span> <span class="string">"http://www.net.cn/static/customercare/yourip.asp"</span>;<span class="comment">// 要获得html页面内容的地址(万网)</span></span><br><span class="line"> </span><br><span class="line"> <span class="type">URL</span> <span class="variable">url</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">URL</span>(path);<span class="comment">// 创建url对象</span></span><br><span class="line"> </span><br><span class="line"> <span class="type">HttpURLConnection</span> <span class="variable">conn</span> <span class="operator">=</span> (HttpURLConnection) url.openConnection();<span class="comment">// 打开连接</span></span><br><span class="line"> </span><br><span class="line"> conn.setRequestProperty(<span class="string">"contentType"</span>, <span class="string">"GBK"</span>); <span class="comment">// 设置url中文参数编码</span></span><br><span class="line"> </span><br><span class="line"> conn.setConnectTimeout(<span class="number">5</span> * <span class="number">1000</span>);<span class="comment">// 请求的时间</span></span><br><span class="line"> </span><br><span class="line"> conn.setRequestMethod(<span class="string">"GET"</span>);<span class="comment">// 请求方式</span></span><br><span class="line"> </span><br><span class="line"> <span class="type">InputStream</span> <span class="variable">inStream</span> <span class="operator">=</span> conn.getInputStream();</span><br><span class="line"> <span class="comment">// readLesoSysXML(inStream);</span></span><br><span class="line"> </span><br><span class="line"> <span class="type">BufferedReader</span> <span class="variable">in</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">BufferedReader</span>(<span class="keyword">new</span> <span class="title class_">InputStreamReader</span>(</span><br><span class="line"> inStream, <span class="string">"GBK"</span>));</span><br><span class="line"> <span class="type">StringBuilder</span> <span class="variable">buffer</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StringBuilder</span>();</span><br><span class="line"> String line;</span><br><span class="line"> <span class="comment">// 读取获取到内容的最后一行,写入</span></span><br><span class="line"> <span class="keyword">while</span> ((line = in.readLine()) != <span class="literal">null</span>) {</span><br><span class="line"> buffer.append(line);</span><br><span class="line"> }</span><br><span class="line"> List<String> ips = <span class="keyword">new</span> <span class="title class_">ArrayList</span><>();</span><br><span class="line"> </span><br><span class="line"> <span class="comment">//用正则表达式提取String字符串中的IP地址</span></span><br><span class="line"> String regEx=<span class="string">"((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)"</span>;</span><br><span class="line"> <span class="type">String</span> <span class="variable">str</span> <span class="operator">=</span> buffer.toString();</span><br><span class="line"> <span class="type">Pattern</span> <span class="variable">p</span> <span class="operator">=</span> Pattern.compile(regEx);</span><br><span class="line"> <span class="type">Matcher</span> <span class="variable">m</span> <span class="operator">=</span> p.matcher(str);</span><br><span class="line"> <span class="keyword">while</span> (m.find()) {</span><br><span class="line"> <span class="type">String</span> <span class="variable">result</span> <span class="operator">=</span> m.group();</span><br><span class="line"> ips.add(result);</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="comment">// 返回公网IP值</span></span><br><span class="line"> <span class="keyword">return</span> ips.get(<span class="number">0</span>);</span><br><span class="line"> </span><br><span class="line"> } <span class="keyword">catch</span> (Exception e) {</span><br><span class="line"> System.out.println(<span class="string">"获取公网IP连接超时"</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="string">""</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h5 id="根据外网IP获取用户所在城市"><a href="#根据外网IP获取用户所在城市" class="headerlink" title="根据外网IP获取用户所在城市"></a>根据外网IP获取用户所在城市</h5><p>首先你待需要一个ip2region.db文件,大家可以百度一下</p>
<p>ip2region准确率99.9%的ip地址定位库,0.0x毫秒级查询,数据库文件大小只有1.5M,提供了java,php,c,python,nodejs,golang查询绑定和Binary,B树,内存三种查询算法</p>
<p>引入ip2region.db<br>maven</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="comment"><!--ip2region--></span></span><br><span class="line"><span class="tag"><<span class="name">dependency</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">groupId</span>></span>org.lionsoul<span class="tag"></<span class="name">groupId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">artifactId</span>></span>ip2region<span class="tag"></<span class="name">artifactId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">version</span>></span>1.7.2<span class="tag"></<span class="name">version</span>></span></span><br><span class="line"><span class="tag"></<span class="name">dependency</span>></span></span><br></pre></td></tr></table></figure>
<p>创建IPUtils工具类</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Log4j2</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">IPUtils</span> {</span><br><span class="line"> </span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 根据IP获取地址</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span> 国家|区域|省份|城市|ISP</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">static</span> String <span class="title function_">getAddress</span><span class="params">(String ip)</span> {</span><br><span class="line"> <span class="keyword">return</span> getAddress(ip, DbSearcher.BTREE_ALGORITHM);</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 根据IP获取地址</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> ip</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> algorithm 查询算法</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span> 国家|区域|省份|城市|ISP</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@see</span> DbSearcher</span></span><br><span class="line"><span class="comment"> * DbSearcher.BTREE_ALGORITHM; //B-tree</span></span><br><span class="line"><span class="comment"> * DbSearcher.BINARY_ALGORITHM //Binary</span></span><br><span class="line"><span class="comment"> * DbSearcher.MEMORY_ALGORITYM //Memory</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="meta">@SneakyThrows</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">static</span> String <span class="title function_">getAddress</span><span class="params">(String ip, <span class="type">int</span> algorithm)</span> {</span><br><span class="line"> <span class="keyword">if</span> (!Util.isIpAddress(ip)) {</span><br><span class="line"> log.error(<span class="string">"错误格式的ip地址: {}"</span>, ip);</span><br><span class="line"> <span class="keyword">return</span> <span class="string">""</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="type">String</span> <span class="variable">dbPath</span> <span class="operator">=</span> IPUtils.class.getResource(<span class="string">"/db/ip2region.db"</span>).getPath();</span><br><span class="line"> <span class="type">File</span> <span class="variable">file</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(dbPath);</span><br><span class="line"> <span class="keyword">if</span> (!file.exists()) {</span><br><span class="line"> log.error(<span class="string">"地址库文件不存在"</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="string">""</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="type">DbSearcher</span> <span class="variable">searcher</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">DbSearcher</span>(<span class="keyword">new</span> <span class="title class_">DbConfig</span>(), dbPath);</span><br><span class="line"> DataBlock dataBlock;</span><br><span class="line"> <span class="keyword">switch</span> (algorithm) {</span><br><span class="line"> <span class="keyword">case</span> DbSearcher.BTREE_ALGORITHM:</span><br><span class="line"> dataBlock = searcher.btreeSearch(ip);</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> DbSearcher.BINARY_ALGORITHM:</span><br><span class="line"> dataBlock = searcher.binarySearch(ip);</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> DbSearcher.MEMORY_ALGORITYM:</span><br><span class="line"> dataBlock = searcher.memorySearch(ip);</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">default</span>:</span><br><span class="line"> log.error(<span class="string">"未传入正确的查询算法"</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="string">""</span>;</span><br><span class="line"> }</span><br><span class="line"> searcher.close();</span><br><span class="line"> <span class="keyword">return</span> dataBlock.getRegion();</span><br><span class="line"> }</span><br></pre></td></tr></table></figure>
<h5 id="根据城市获取天气信息"><a href="#根据城市获取天气信息" class="headerlink" title="根据城市获取天气信息"></a>根据城市获取天气信息</h5><p>第三方天气接口:portalweather.comsys.net.cn/weather03/a…</p>
<p>调用第三方天气接口获取天气信息,本文使用java自带工具类HttpUtils</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@GetMapping("/weather")</span></span><br><span class="line"><span class="meta">@DecryptBody(encode = true)</span> <span class="comment">//响应加密</span></span><br><span class="line"><span class="keyword">public</span> Result <span class="title function_">getWeather</span><span class="params">()</span>{</span><br><span class="line"> <span class="type">String</span> <span class="variable">publicIp</span> <span class="operator">=</span> GetIPUtils.getPublicIp();<span class="comment">//获取外网IP</span></span><br><span class="line"> <span class="keyword">if</span> (StringUtils.isBlank(publicIp)) <span class="keyword">return</span> ResultUtils.error(<span class="string">"获取失败"</span>);</span><br><span class="line"> <span class="type">String</span> <span class="variable">cityInfo</span> <span class="operator">=</span> IPUtils.getAddress(publicIp);<span class="comment">//国家|区域|省份|城市|ISP</span></span><br><span class="line"> <span class="keyword">if</span> (StringUtils.isBlank(cityInfo)) <span class="keyword">return</span> ResultUtils.error(<span class="string">"获取失败"</span>);</span><br><span class="line"> String[] split = cityInfo.split(<span class="string">"\|"</span>);</span><br><span class="line"> <span class="type">String</span> <span class="variable">city</span> <span class="operator">=</span> <span class="string">""</span>;</span><br><span class="line"> <span class="keyword">for</span> (String aSplit : split) <span class="keyword">if</span> (aSplit.contains(<span class="string">"市"</span>)) city = aSplit;<span class="comment">//拿取市级名称</span></span><br><span class="line"> <span class="keyword">if</span> (StringUtils.isBlank(city)) <span class="keyword">return</span> ResultUtils.error(<span class="string">"获取失败"</span>);</span><br><span class="line"> <span class="type">String</span> <span class="variable">weatherInformation</span> <span class="operator">=</span> HttpUtil.get(<span class="string">"http://portalweather.comsys.net.cn/weather03/api/weatherService/getDailyWeather?cityName="</span> + city);<span class="comment">//调用天气接口</span></span><br><span class="line"> <span class="keyword">if</span> (StringUtils.isBlank(weatherInformation)) <span class="keyword">return</span> ResultUtils.error(<span class="string">"获取失败"</span>);</span><br><span class="line"> <span class="type">Object</span> <span class="variable">o</span> <span class="operator">=</span> ObjectMapperUtils.strToObj(weatherInformation,Object.class);</span><br><span class="line"> <span class="keyword">return</span> ResultUtils.success(<span class="string">"获取成功"</span>,o);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category>代码</category>
</categories>
<tags>
<tag>java</tag>
<tag>工具类</tag>
<tag>天气</tag>
</tags>
</entry>
<entry>
<title>java计算判断时间是否大于15分钟</title>
<url>/posts/3904c7be/</url>
<content><![CDATA[<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">@Test</span><br><span class="line"> public void ss(){//---主播进入直播------转换成毫秒值---------点击开始直播判断据开始时间是否大于15min <=15返地址,>15返回null无法进入直播</span><br><span class="line"> String date="2021-08-06 09:44";</span><br><span class="line"> SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm");</span><br><span class="line"> try {</span><br><span class="line"> long start = sdf.parse(date).getTime();</span><br><span class="line"> //获取当前时间毫秒值</span><br><span class="line"> long current = System.currentTimeMillis();// 返回一个毫秒数</span><br><span class="line"> if((current - start)/ 1000 / 60 > 15){</span><br><span class="line"> System.out.println("大于15min---------------");</span><br><span class="line"> }else{</span><br><span class="line"> System.out.println("小于15min----------------");</span><br><span class="line"> }</span><br><span class="line"> System.out.println(start);</span><br><span class="line"> } catch (ParseException e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line"> }</span><br><span class="line"> }</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category>代码</category>
</categories>
<tags>
<tag>java</tag>
<tag>时间</tag>
</tags>
</entry>
<entry>
<title>linux部署jar包</title>
<url>/posts/a6669b86/</url>
<content><![CDATA[<p>启动jar包</p>
<p><code>nohup java -jar -Xms256m -Xmx1024m xxxx.jar > map.log 2>&1 &</code></p>
<p>查看日志<br><code>tail -f map.log</code></p>
<p>查看端口命令;<br><code>sudo lsof -i:9090</code><br>关闭jar命令;<br><code>kill -9 xxx</code></p>
]]></content>
<categories>
<category>linux</category>
</categories>
<tags>
<tag>java</tag>
<tag>jar</tag>
</tags>
</entry>
<entry>
<title>java最便捷的word导出方法(POI-TL)</title>
<url>/posts/4e2a03f/</url>
<content><![CDATA[<p>场景如下:按照客户提供的word模板导出系统数据</p>
<h3 id="第一步,添加poi-tl的依赖"><a href="#第一步,添加poi-tl的依赖" class="headerlink" title="第一步,添加poi-tl的依赖"></a>第一步,添加poi-tl的依赖</h3><figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag"><<span class="name">dependency</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">groupId</span>></span>com.deepoove<span class="tag"></<span class="name">groupId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">artifactId</span>></span>poi-tl<span class="tag"></<span class="name">artifactId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">version</span>></span>1.10.0<span class="tag"></<span class="name">version</span>></span></span><br><span class="line"><span class="tag"></<span class="name">dependency</span>></span></span><br></pre></td></tr></table></figure>
<blockquote>
<p>注意选择合适的jar包版本,避免和现有项目jar包冲突,此处为1.10.0版本。</p>
</blockquote>
<h3 id="第二步,准备word模板文件"><a href="#第二步,准备word模板文件" class="headerlink" title="第二步,准备word模板文件"></a>第二步,准备word模板文件</h3><p>模板中文本信息可以用 标签指定</p>
<p>例如在word文档中写入: //会将word文档中的对位置的标签替换为map中的数据</p>
<p>模板文件为word文档,格式为docx</p>
<p>模板图:</p>
<p><img src="data:image/webp;base64,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" alt="image"></p>
<h3 id="第三步,写java代码"><a href="#第三步,写java代码" class="headerlink" title="第三步,写java代码"></a>第三步,写java代码</h3><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Test</span> {</span><br><span class="line"></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> IOException {</span><br><span class="line"> Map<String, Object> data = <span class="keyword">new</span> <span class="title class_">HashMap</span><>();</span><br><span class="line"> data.put(<span class="string">"applyReason"</span>,<span class="string">"test导出"</span>);</span><br><span class="line"> <span class="comment">//(2)动态的表格列表数据,要创建List集合,数据类型为map类型,map中的key为word中要遍历的列,值为要替换的内容</span></span><br><span class="line"> List<Map<String,Object>> list=<span class="keyword">new</span> <span class="title class_">ArrayList</span><Map<String,Object>>();</span><br><span class="line"> <span class="comment">//创建map的List集合</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i < <span class="number">6</span>; i++) {</span><br><span class="line"> <span class="comment">//用循环添加每行的数据,添加6行数据</span></span><br><span class="line"> Map<String,Object> detailMap = <span class="keyword">new</span> <span class="title class_">HashMap</span><String, Object>();</span><br><span class="line"> <span class="comment">//将word中标签名的例和对应数据保存到map</span></span><br><span class="line"> detailMap.put(<span class="string">"index"</span>, i+<span class="number">1</span>);</span><br><span class="line"> detailMap.put(<span class="string">"title"</span>, <span class="string">"商品"</span>+i);</span><br><span class="line"> detailMap.put(<span class="string">"product_description"</span>, <span class="string">"套"</span>);</span><br><span class="line"> detailMap.put(<span class="string">"buy_num"</span>, <span class="number">3</span>+i);</span><br><span class="line"> detailMap.put(<span class="string">"saleprice"</span>, <span class="number">100</span>+i);</span><br><span class="line"> list.add(detailMap);</span><br><span class="line"> }</span><br><span class="line"> <span class="type">HackLoopTableRenderPolicy</span> <span class="variable">policy</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">HackLoopTableRenderPolicy</span>();</span><br><span class="line"> <span class="comment">//创建一个列表的规则</span></span><br><span class="line"> <span class="type">Configure</span> <span class="variable">config</span> <span class="operator">=</span> Configure.newBuilder().bind(<span class="string">"list"</span>, policy).build();</span><br><span class="line"> <span class="comment">//设置列表配置,如果有多个列表时需加.bind("list1", policy) 新列表配置即可</span></span><br><span class="line"> data.put(<span class="string">"list"</span>, list);</span><br><span class="line"> data.put(<span class="string">"local"</span>,<span class="keyword">new</span> <span class="title class_">PictureRenderData</span>(<span class="number">80</span>,<span class="number">100</span>,<span class="string">"E:/name.png"</span>));</span><br><span class="line"> <span class="type">XWPFTemplate</span> <span class="variable">template</span> <span class="operator">=</span> XWPFTemplate.compile(<span class="string">"E:/template.docx"</span>,config).render(data);</span><br><span class="line"> FileOutputStream out;</span><br><span class="line"> out = <span class="keyword">new</span> <span class="title class_">FileOutputStream</span>(<span class="string">"E:/out.docx"</span>);</span><br><span class="line"> template.write(out);</span><br><span class="line"> out.flush();</span><br><span class="line"> out.close();</span><br><span class="line"> template.close();</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h3 id="导出结果"><a href="#导出结果" class="headerlink" title="导出结果"></a>导出结果</h3><p><img src="data:image/webp;base64,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" alt="image"></p>
]]></content>
<categories>
<category>代码</category>
</categories>
<tags>
<tag>java</tag>
<tag>导出</tag>
<tag>POI</tag>
<tag>WORD</tag>
</tags>
</entry>
<entry>
<title>markdown引入图片、音频、视频</title>
<url>/posts/1eedc1b4/</url>
<content><![CDATA[<h3 id="markdown引入图片、音频、视频"><a href="#markdown引入图片、音频、视频" class="headerlink" title="markdown引入图片、音频、视频"></a>markdown引入图片、音频、视频</h3><h4 id="markdown-简介"><a href="#markdown-简介" class="headerlink" title="markdown 简介"></a>markdown 简介</h4><ul>
<li>Markdown 是一种轻量级标记语言,它允许人们使用易读易写的纯文本格式编写文档。</li>
<li>Markdown 编写的文档后缀为 .md, .markdown</li>
<li>简单易学容易上手,十分钟左右即可上手</li>
<li>有助于作者专心写作(各种在线博客编辑坑太多,文档丢失、广告太多,可移植性差)</li>
</ul>
<h4 id="插入图片"><a href="#插入图片" class="headerlink" title="插入图片"></a>插入图片</h4><p>我们在写博客的时候总免不了要插入各种图片,下面就是markdown插入图片的语法</p>
<figure class="highlight text"><table><tr><td class="code"><pre><span class="line">![img](图片链接地址)</span><br></pre></td></tr></table></figure>
<h4 id="插入音频"><a href="#插入音频" class="headerlink" title="插入音频"></a>插入音频</h4><h5 id="使用audio-标签"><a href="#使用audio-标签" class="headerlink" title="使用audio 标签"></a>使用audio 标签</h5><p>语法如下:</p>
<figure class="highlight text"><table><tr><td class="code"><pre><span class="line"><audio id="audio" controls="" preload="none"></span><br><span class="line"> <source id="mp3" src="音频地址"></span><br><span class="line"></audio></span><br></pre></td></tr></table></figure>
<p>插入音频后效果如下:</p>
<audio id="audio" controls preload="none">
<source id="mp3" src="音频地址">
</audio>
<h5 id="使用iframe标签"><a href="#使用iframe标签" class="headerlink" title="使用iframe标签"></a>使用iframe标签</h5><p>以网易云音乐为例</p>
<ol>
<li>首先在网易云音乐播放界面,点击生成外链播放器</li>
</ol>
<p><img src="/posts/1eedc1b4/image-20230421103934711.png" alt="image-20230421103934711"></p>
<p><img src="/posts/1eedc1b4/image-20230426102741178.png" alt="image-20230426102741178"></p>
<p>插入音频后效果如下:</p>
<iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width="330" height="86" src="//music.163.com/outchain/player?type=2&id=28280555&auto=1&height=66"></iframe>
]]></content>
<categories>
<category>markdown</category>
</categories>
</entry>
<entry>
<title>mybatis判空提高效率</title>
<url>/posts/dd843aa7/</url>
<content><![CDATA[<h3 id="select-1-和select"><a href="#select-1-和select" class="headerlink" title="select 1 和select *"></a>select 1 和select *</h3><p><code>select 1 from 表名</code>与<code>select * from 表名</code> 作用上来说是没有差别的,都是查看是否有记录。select 1 from 中的1是一常量,查到的所有行的值都是它,但从效率上来说,1>*,因为不用查字典表。</p>
<h3 id="Select-Count-和Select-Count-1"><a href="#Select-Count-和Select-Count-1" class="headerlink" title="Select Count (*)和Select Count(1)"></a>Select Count (*)和Select Count(1)</h3><p>一般情况下,<code>Select Count (*)</code>和<code>Select Count(1)</code>两者返回结果是一样的</p>
<p>如果表中没有主键 ,使用count(1)比count(*)快;</p>
<p>如果有主键,那么count(主键)最快</p>
<p>count(*)和count(1)的结果一样,都包括对NULL的统计,而count(字段) 不包括NULL的统计;</p>
<p>实操中,选择使用 count(1)的情况比较多;</p>
]]></content>
<categories>
<category>代码</category>
</categories>
<tags>
<tag>MyBatis</tag>
<tag>优化</tag>
<tag>mysql</tag>
</tags>
</entry>
<entry>
<title>springboot项目启动时执行代码</title>
<url>/posts/ea6a3de/</url>
<content><![CDATA[<h3 id="ApplicationRunner和CommandLineRunner"><a href="#ApplicationRunner和CommandLineRunner" class="headerlink" title="ApplicationRunner和CommandLineRunner"></a>ApplicationRunner和CommandLineRunner</h3><ul>
<li>SpringBoot提供了两个接口来实现Spring容器启动完成后执行的功能,两个接口分别为CommandLineRunner和ApplicationRunner。这两个接口需要实现一个run方法,将代码在run中实现即可。这两个接口功能基本一致,其区别在于run方法的入参。ApplicationRunner的run方法入参为ApplicationArguments,为CommandLineRunner的run方法入参为String数组。<br>当有多个类实现了CommandLineRunner和ApplicationRunner接口时,可以通过在类上添加@Order注解来设定运行顺序。</li>
</ul>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">package</span> com.rj.springboot_mybatispuls.config;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> lombok.extern.slf4j.Slf4j;</span><br><span class="line"><span class="keyword">import</span> org.springframework.boot.CommandLineRunner;</span><br><span class="line"><span class="keyword">import</span> org.springframework.stereotype.Component;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 项目启动时执行</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span> ZHAI</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@date</span> 2021/12/9 10:10</span></span><br><span class="line"><span class="comment"> **/</span></span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="meta">@Slf4j</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MyCommandLineRunner</span> <span class="keyword">implements</span> <span class="title class_">CommandLineRunner</span> {</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">run</span><span class="params">(String... args)</span> {</span><br><span class="line"> <span class="comment">//需要执行的代码</span></span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category>代码</category>
</categories>
<tags>
<tag>SpringBoot</tag>
</tags>
</entry>
<entry>
<title>vscode插件好用的插件</title>
<url>/posts/30e6d251/</url>
<content><![CDATA[<p>主题:Brackets Light Pro<br>文件图标主题:VSCode Great Icons<br>中文:Chinese (Simplified) (简体中文) Language Pack for Visual Studio Code<br>绘图:Draw.io Integration<br>Markdown笔记:Markdown Preview Enhanced<br>Markdown语法规范:markdownlint<br>粘贴图片:Paste Image</p>
]]></content>
<categories>
<category>工具</category>
</categories>
<tags>
<tag>java</tag>
<tag>mysql</tag>
<tag>vscode</tag>
</tags>
</entry>
<entry>
<title>使用IDEA根据wsdl生成WebServices客户端代码</title>
<url>/posts/24409baf/</url>
<content><![CDATA[<p>转:</p>
<blockquote>
<p><a href="https://blog.csdn.net/wohaqiyi/article/details/85330808/">https://blog.csdn.net/wohaqiyi/article/details/85330808/</a></p>
</blockquote>
]]></content>
<categories>
<category>代码</category>
</categories>
<tags>
<tag>java</tag>
<tag>IDEA</tag>
<tag>wsdl</tag>
</tags>
</entry>
<entry>
<title>判断字符串是否中英文类</title>
<url>/posts/e5c137a2/</url>
<content><![CDATA[<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> java.util.regex.Matcher;</span><br><span class="line"><span class="keyword">import</span> java.util.regex.Pattern;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span> ZHAI</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@date</span> 2021/12/23 14:52</span></span><br><span class="line"><span class="comment"> **/</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ChineseAndEnglishUtil</span> {</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Title</span>: isChinese</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>: 是否是中文</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> c</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span>: boolean</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@throws</span></span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">static</span> <span class="type">boolean</span> <span class="title function_">isChinese</span><span class="params">(<span class="type">char</span> c)</span> {</span><br><span class="line"> Character.<span class="type">UnicodeBlock</span> <span class="variable">ub</span> <span class="operator">=</span> Character.UnicodeBlock.of(c);</span><br><span class="line"> <span class="keyword">if</span> (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS</span><br><span class="line"> || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS</span><br><span class="line"> || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A</span><br><span class="line"> || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION</span><br><span class="line"> || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION</span><br><span class="line"> || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Title</span>: isEnglish</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>: 是否是英文</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> charaString</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span>: boolean</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@throws</span></span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">static</span> <span class="type">boolean</span> <span class="title function_">isEnglish</span><span class="params">(String charaString)</span> {</span><br><span class="line"> <span class="keyword">return</span> charaString.matches(<span class="string">"^[a-zA-Z]*"</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Title</span>: isChinese</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>: 是否是中文</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> str</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span>: boolean</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@throws</span></span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">static</span> <span class="type">boolean</span> <span class="title function_">isChinese</span><span class="params">(String str)</span> {</span><br><span class="line"> <span class="type">String</span> <span class="variable">regEx</span> <span class="operator">=</span> <span class="string">"[\\u4e00-\\u9fa5]+"</span>;</span><br><span class="line"> <span class="type">Pattern</span> <span class="variable">p</span> <span class="operator">=</span> Pattern.compile(regEx);</span><br><span class="line"> <span class="type">Matcher</span> <span class="variable">m</span> <span class="operator">=</span> p.matcher(str);</span><br><span class="line"> <span class="keyword">if</span> (m.find())</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category>代码</category>
</categories>
<tags>
<tag>工具类</tag>
</tags>
</entry>
<entry>
<title>关于思维、强势文化、马克思主义、唯心主义、唯物主义的思考及对话</title>
<url>/posts/50749798/</url>
<content><![CDATA[<div class="hbe hbe-container" id="hexo-blog-encrypt" data-wpm="抱歉, 这个密码看着不太对, 请再试试." data-whm="抱歉, 这个文章不能被校验, 不过您还是能看看解密后的内容.">
<script id="hbeData" type="hbeData" data-hmacdigest="d03e089571e364dc4fdc9523f2e3bcfdbfb78f5b5857d4aa1188e0a26b545770">601b7ad76f4fbd60ff466c34909923e9c8f637ce8db723aeeebafec606bc5c120d6a9bbdd3ca80170e9fdbef80df91363cd65301c0ba562d350925529231b0846121229b9f4365edb3a30adeac15651d9ec745638300d5418d712a190b024d95f2ada39f5b5c1e31c1149120f2899f1a342364415a8385a1954783c80552404d3f388bc4e2c99eae818d840e052f9334d5ab66f356d9ce45a9ac2ca7e0a717d488082799eb2893721d5d47c16c8cc20c9e674c4ec16f8fff52a01fbbdcc44eaa7608c91b03f4a79dd9316c863f60a4e486b2517b9a6fdd0772776459830585aa03123c3125240b74ad05a827c8fbaf9d0c22e54a95e66a12be1c37c798282a14c5507eb535ecec0e83530269aa92802fe012776f1277d7e1590da2ede9cdf6a1766a7280b8522851b381e48da350ed9596d507d0a950907a9290643caaf6252c6061312d45200c0de41e4fc0367a72bbd0095095f10c5492dc8790310a8b29a14d3cfb0718ed196254b77f8f01570d2ff2d45f65ccb20c4bb8c8be1698fabdc5dafb4e0ba667f2843b6035268adf6535788b596aeb682ff937a743b13fab9077262f6ba78d2569e06aec9e3ca3ccc1b73070c51b22c9a0053f23ee8cde41a829e6b2dcd122e134c0e35935bb72f486ecc68d8e653965445c90fa4375ea444a4a3ff9821b08007316f1e9802409b82b60a1859c273140fb30da0541648c00c5830a77e642b59e3ff2f43d0df07717a433db24c4f2708ab4397aa616501ca90400e7ae89274d7d9c68ab3fe8c34c59c8118a3510302724146ee0359e2ca61125a2a603c794c92d89f1e0152dc44de9a51b19b7d4597317345e658281d1f7a9e78a7720f108aed21d8f66560f0b44f5a122d5ec2371d0ac1e16b48befef1c771d5e75090fd085d5caa109d82c79d8b67edb464a82c5312972c805dbd501e72294e06ad6283e2eb085e293d7b8542ce5cf6213a681bb3d9731b0e25572d24776d99dcf2c0dcfc6d4de9fa35072c6c70132ee1584167e0235222d86b17bbbaf1f147d745f14f318e1eb568fcb40640f3d5e42da892a9ef4f3e2cf8cec085e3ca1c04981ef58fe8fc4b6ca1e2efb3b108bd9d2ee5705850e3638e47c5e1a44eccaaf254a9151cdfb874a13fea3c577de5bded473d56387f48a54037ba4a273ece5c6f06929fad588c6a40fb1b0eb5f8465dadea079619707f9d4a8c346113397dd7ed0b7a8e72707d667193578cc7112df1585bdd6961db74625885275341790c515a2e1ff6708075fff418243079bba332f2a7df873e8d4e3a109e86b4e6fd5bf7da05d95ab78ad3f46f1538ab4715f21b4249583dd163eeee691fc1353c4fac310526861a01d7de0ba388771fa4076c2d27143f241aeb35b21ad4f53492be01603ec38b25407c0be6a20f4fcb05a733017bdfe1264444a79d8b363530cd60d0d0f1b20d24d5636caa488400a248e915331ef75f9c99f4865f04ae2d4901a18970b27e52f0a4e472cc8939fa94d4dba51c08c4d7cb547a362e2c9532217f50aa972e50ba839d82a5f10e065707144ecaf7b370144dc63fcf3c70e87ea4bd8b0281d4cd4e1c3c5235d1d36c55d2df7db8754695115d140a64d895e11ba947cad8707cd4dda33a63360b8b2a0a429751c8535fa5a2031f22c2cd003aacb23099a615c93053bf49d8d8c6548442972bdf4b66e238414769ca33af82277a28feb1b320d071564cc38df121360479c34ffa072edced4eaed912d0fb4f968cecd8d19c88509f30853a59777c078922dd2ede0eb74ee360e2e70ef572e6b4b91a7c0da2c5d01d1307bfa2aece76cc363cf8eeb0d7d37aa4c05bf85192ab943b0d7775d8a278566440f5e4b95719f14cd7d0d916517734fe26b3094b95f0133c7f526392aef4003a128bdd973cca38b0a827c00349f26f426d22fb7ff2f932a03f680b3f08e0ed089572ea6545f651f1185ad29b80853008250297315c7580c4d8bc493cd54a86f3607656daf00628b918413e489fdaade7f646268d8e7c5b4340ae77ca695ca99bf224aa21047600b5251643136e9292e25a51ed6e6a40f48b50531d42ab359227dc985f178ea48cd96c6a0ca0110718c85809dff5c5501cb8dc6101eee9a141a7188b53fcea2b0f4fd591a0ca748686174fe0d53c68195730b0a99d608eff3252e51ce5be306b71ac48f924919c6e6d5aee21cb6eb4fa6b05a065e6f8b792437136d488cc4d8145ff40d486a22f5d208f4fe75fe8ed4e23f0fac673cfff092f0dbe638d9a740aeff3d88020ed8e8a667cb8813a6823e737101ce0ca3c0741276002a8ecd2d8c0e661033a308449bccf8d9ec82fe440a74351be3dcf340e90749d51df2cdd3d483d7b8e7c3d15020ab80c1c339405fa44ecb59d88d40ff21d375c089ee1a0988674ccadcb55c45ded9d5b8cbf6dd158fed000d5e90d04ea9a8442735ccc2e0f0bc90d7d469578db94e93a231cf06223c195d7c62ed1e8edd4d20a05b70a4cfe01e051dad95a509dedf8c1fd7e6953c7432becf4e23bf9dbee447d1d3b4f1c1a87f8e6c7733fc2d33b07ec58431be94910c6950bb9d229623307835cd1c674859799c74a312b5681e6a12847cac0ab1a9bc709a11670ccee29ca45a96a98bce07ddbbcb5bd6ddaee301b0daa83662915c57057be818cefe63d93cc6d55147a967d2b92ac9374be779179eb480aa53ea82894d01cd1dbefcb6e0036d885355f6ddb3bc1fd60e869b2620edafc743e38f749343d50ab88a2fdb82a4a1b316eaf24c6509b0302d5bb039a3ec2f8e56e1fe060913399f06f771f27f6e48b250c9577ddab2dfae1ae9a920aeb351a380799b2b38ba96d2b948b2f2f945098e1731c84725fa90605b80f111cacdae82b6a04e7294a5959f77f5a5ec49d773bd9545ab9919b785cd4e259ca8fe43e34ecd3c1ce604a8241524bd0f688d5dcf01648f6348338875bd08913fe569cad2199337e714640478cbe1524b5ec9ffff29efa23ee2a2bab44ba492b28f9252727d3df07a151831ec5abd51aca8ab3db60fadcbc00afd781d4bb72304e96fcbbd376618d7d2d707cae3d20943c1b6adc47a8a31c6eed34a30c5f1d086a9a95e336edbe2d6008390b963d5abdbb742c9aed4ec7af2a3abf7d5d1988c81e779a2aa3f4df98258b6546342061fc45686d72ad79340af69f37e6523eb066a619535cfa9b9016744c4a81b701c33144e1418a9a4bb63b3e84a2a55cd6e81ea2e4c7f429201d56585d77a9627742d2bde25244ba74f7853836426b049a7817586bf34511352c615e5005dae66e4994bf0fb1baa394542bc86c69f37d15d0a84fdf1c86a641dae614e764d956f50bfc2d2af3dd1d9948398b282db5c273fb838a03b708d5372ef7d10e16ddb2a9ee1b478676b8c2ff014f9203469f8abcc2ecbcbf139fbc146f834d0d9fd19bef25b220cc5d24786a9601a1b6ad5dbc34c87481efb80930c3c2844c942d33c5d6ca703503433c97583ad5e85356d41cef75bd04f84e8fd87a5fba3b4c6ce9995c4912956db5e6b6317db10c49e2b67654586b1fc351c7b08bef8f2779f38f55f610cdd0afdf448e71c96653ba00d534f6c59406c6aefa6995ab95ad4649108939cc2c026fbffd4317a907d53fbf1850acccb83bc769191b7d72b38e9b3a67c58617b9047fa663b2489142ca9febe761a3fb64fde4fc5767bd46a4ffde92acc48cc060b36f5d6d6702ea1d5a152994feaf86fde354dfd2e06486d1a8025b99ede282e2672e11ac0b263dcbb58caa3030f7399bd3f55c07ab35d11a2227035bc881d3668a98d11b67bf85083db98e42c589621ebcba61812bcd871f9b732ff762a93d6ec5ac9ebb715792ddaea36fed2dd6e892f6fc577fa645cc0e779c1a194ae164618357b6e7eaf5bd0a462492568e5eb469e5c78316e6bd576b193d3cb9d06d98fd901f527317ced50ac231c97c79f8a39e8a3ba6c086a3a0887e1f97f9a235720b94fc340f795e10062d8f3ff0bc5d1e48e0c2185a3c791aa0baaf77fb977ddacc5fe8a091ec94f8e8dcb40d1265a8904729f9cf5462da087741f45e1d24a238f841910afb30cac0f4121af06b2cc83e4f4478519f58cbb12a91c8b03ef3a8d744d0b98d659e9043a86a94e77f631fe7c2129ccfc9ea0db2fadec0bf3f9319db92ce46dcc74ef8b3cc439cc32438fd5d7a9c580ae62106970c79e6761f7bf22b205aed5c5dfe57d6cfe9e7635ed59c559adc3493b2d37dbb1743bca285eea054b63c4504c6b105dccee3dce8ba596f0b14998b9cc2ce2ad78e9329a1702ff4971f5798f42f328c0006505eb46c537592f65f197c6a93bd9d2f319a5fbf37182cec0683a7e211b8df5c9cd0cd29bdf6d506949ace7987684ce235f6bb6b1854825a1fd6ef0bf8712896ab232396292f03fb130db8c9d61124f26d4bc9547a2fb9ce921fe585b9d0bcfe6d70ef12ca637a01e69693c753301a23dc4a5095169556022f94a3cd1038a343541cfba2a4e3f4b0bac1fa3169c1e8d7ab67f54d32964f6903ad3565b23fc223b1ce72edd862d14726300cbd6950bbd7bb8aeae3fa8278d16f494483d7340b9369d0c8117b597bf6ef373ce746f00fd64a5e49f4f52316b396f0ad4ce3dc7564a39d5eaf626bca7e8f930ba47d1af91a0692a364cc8c582dc23f229511e04fa4eda7d9d9aeae22cebe5fcb4e18f69113139311809987967a638211acccfff847b510ed252a0145ac60033a48249b1039e63dffac5e6c1140ef0c052ce11996d4e68b0aae82fdcc453791f85862e0f280fdcb78331954a27d1972cbf548dbf28915f3017d481c477a008a7d72c09db0377dc4c4affe40c9022bdeeb7b8bde3cbc33d345c55ad97d62bd69aaceae06a4651751f29ae278dd99e50beca518906c9ccfcc986329509b771473c546e9cf684902ce513908d50ef738edae8e09e0723d5d4e88afdf5fabd6f534197735ee62b77abded7f3c9a4bb02f6a3d1b7c833eea1bdc0427f57f5ed662d28bbac1fdcc5ac645e4b83ed8d96fc5341ba22cc1f49a6f044d51ed49a2da4ce84798c575e6e60843f778f8d19e29935f0186f9df095fdfeeb3dfbabc3290bed3b9ef5f4b3f59373b10fe999c8afb81789176c2a033947ef93563fe2487fb6d4b179ee900256fb8ae71c14ffa14fb52ab09d8161e26d7616aed117211af1556b2a9dcb9c6704e1ddc6edea90e5a46066d592595c5be69a3f8b42226c51a63908824c0be8494f749256215846c7906957df195404f87a9098f5b5a2b00edf6604b188d7456363d1a385b1c1b059a67c3a93d2c981f4c8b1717208c78d1b28c3998568cd858c0c794f438bda388ae83b6bc467d0ad8b267b8713d3db8fcc990bbb7ea3cfd5991c874b3f28582a7935c2e7bc6a119132844ef779f8e8b80c6562ed8989f9af34ba9ca6c0fb1ec917e90c4a0c127f18fec9887c26257452bd5ab452d84c08c09ecda0061e20dc4ae99234d0cee133103eda38f2bf8570a3ae69e3c1b207480afda5b829e9d1a6d123ec13c01848511d6634b74b0149c270087891e7a9e406e870521d951462d61b4c1a81812aae6a294a65049bfedd4744618c6aa85a92412948e8800141704fa2212f228b026fb90e8ade6fb4055988c615f09dd2fec83f4bbe1f98d449fe6a010d2e2db7f95770bea298cc7c65edb6e513d573eff27b7c527f7225b3f456467da2837c0a1605eaf319b80ac5687e7f42ceacd6891fe409bd44dc9b0611fe28a8bed4c4d8188d7341dab25f213a27d1b3bc2d98af20f61f9478b183ed9995bf14290efe8066ddb96f94366d74abb347c3b837f011a81a4f3f4ae5d7be594f15125c515c6359b9c240754bc803da61f883dc0c46c09eea3edc98b5b10fa04fcb9c7848d7408d557894974b5131aae9c12a38542de5e8315eafc1ef5819d7ee271b06bab525ffb049a760148c2cffaf18cacfa565b0cb2d5f877a75f193ae14e068d3adc7f59a5ad3d820f3d42ae64c8b36897bea62f899a3fbfb0032851089709aaecb85edc5a3d8857aea04c376013150603d0e0cae02bf5e51e774a5401c0dddafb94c9885fc6dd83b31fa4ccf7f924b460b0ceb2bc5e6fe2f5c7f10a583de762a3bed8e012677b5f66eb9e97c41695d9c75c9b877fa950e7747731d7f808ffb27bf0226948f4a1d17ae314676ef3bd9fec6bd332c4f8eac7ac9f5bee7f88b5764a6c82e34f8a976c92b3d37d561fcefd1c1aa61737e1911d8febacdbff84af9356556e9124b56dfb25d2732bcaa49ba0a73bf2f7a6d702f1ccd6f85f5ed62e63648bead9e1ffa3b4f6cb3561480dfebf1e3b5c1ee4f6284b42a84d8236a324f05897cdec2d76ee9571462b782d93dc1261913b0d1e7443178b996639590513837e6dfd745fd58576e6956f9ebc5a063c8469d354a2b3a302e71d93400acb8cdbb47e7605dc4b395e1a5f78d0045ad3f3ab05b0759588bc2f8193139ae6df1310091864e1f0b854ae6f5dd397627814cd0fd181abe764b028481216a8744a7648225ccd32bbf03557b9dc348448fc8fc71f8352cbb8181408218b0e7b3d6f0188c418f271c642a29ecaf73d67bef12aa21dfe40f2badc03901661ad0f86ce8c542ab22746da27741493ccae683c250fc92386536fb66235fba3b52777f24d00d2b475d1c3246546a93dafa4c2df4388f65d37d8102f7f88cc752faee07e8e3393dde1ede647b2ca35a4fb7c76756daf61ae392890cb0bd39e3e41dbfc39c7f088d3ed4f824d9d0fde78cd277e6bb45fe06442e09025c77a54a4cb0a22754cde92a1c80094e6c91e33a437d14a5f00c7c2216853f644403273575f763a3bde46213d5221019c5f86bb83143c79fcfd5368adb46d25483d7815f0ac55dd8524ffc793c2b9ff2d01a7d5465475ff2b2aad271f79cf3857e4fc4b2dd8c814715096ca7af04f4640226344a9c72228193ff49ff1356c79c7cb1542cc0f7f5b7767e8cf9cad0ca9d0faf7782fe4fb14995c50e9b8a0b2477b78625e2331c8ca5fed07c14f3e270b18552f1a3d9cf61d2383eb310b5db921f1cf3b422fea25c70ed386c9b233313c8a9e50f1b053cd3d98e6f6ed4a113aab451aeaf3f4a9f5821d99372b9a2f2d11d7357ac7235d5956ab6d85f039a83e9a7ab5e8fb978ac4acfb8d04d1224b207775b35ba5f36edeae5c1a144a389c29aea2a224f133d79952b2b91999e223140f82cd2b59e1dee1b50a1b6b3b873ffd2dec8b1997cf5a4ee6806fdef477836bb7bf1376a3abf8337b2f75910a31cc46315456defa74e57982a0d4dab68a1ee5b9a12a2e1d29772198186f1a2ce05f57829d53937ea2e62e5f5840ea2d653fd5e5b9f2db8337d4ee064231b50317ce63958676dd5337c3ecf15466e6c00ef1935c27c49c18dc18c189a6682f5507a2ff738a6285d8634312820c42250d8bbba4e1e695d3950b2595ccd514e930dcfd27dbdc4717c5e37a370bb13825fa7d26bf531812672e560bbf717ca48bd4af765053793a0e440932462aa499abb06755cc67acc9cde92a872a510f530eea6c20bd2fa2abb40091fff92b4e9852bdeccfb2cd6b6622fc1d8c3803843a9f993203d4f23fc2da9489e10a4d55d2f9b1e8f45508d01db1c063c2329dbdecf60125776b268780fe025d2872fe81f5f86a00a46cfbb0cd939dfbb51a3954b2ff4f7ff9b215d6d3a31426c27f3f2366929d6d12c306f3603923a053745ed74d23d7b9f7ab2eb8ef5d6fcad20e41a79062644a18a2412e088f1106511de43ecbdc625d129645b2d15ea1c46edaabf38ead645eb11e25e90e92057697347e3b4cea0968779179ceeb5d1a4611be55914e9a1f77fcb06e6727b37988adf6b5d9f863ff3fa199c4591bbba3f37cfbb4ca7de28d898ed78f6994cbbf050728463139d9a1cb736294de22bccdf15ebe09ab781d37a5f3ead2521494ef5ecaadb1a27c7af72ec42c749504172f22b43d8f8634830c200fa9266827a6564d5223dfed73d55c38d1c292fd85fa181531f7cfa75b6abdc059b9860e71c3629dea8db5343da1e0e90a70cd9e1c30adfac072dadad25470e7d8168417f7af7f8b811ef5e7b53781db79ae9fd97099b23ae3147f86324c9b8b988863302f200d1c62caff3a7d5ae21267dc47b5e90bb4d582c40592111ef6cac9293fb28dbfd69895ff65d8a063d97a82204002d09fd57023596967a322e9498bfe8133f2b9cc360edb009ca3debecd85d824c3f83314533f1d7ed0e2e8e17e6a009bcff9a8714aca763f1b9b9e38e6142fc32b36680756bbf5c85436e0d83b252a54f8eb2a6cded7eaca6ec3d8fed12d78e0b7b7aab2e701a3c709928beef86e74ea4ca55289ce45eb678e18264b9cc03767601b51ceab441c5a85d4ad2085da9bedef5f96601fa0a188c65d45ab11e4cff679e43f2889c0fce6ad9c11ca08706a7caad97d7b47df63de1ef46adcfb23661c292fe7f7452bc041b4fcb1dbb970a058d0c0090c3ab8a4498f562801180a08f12ef78c21ccb6f88ec99c75457fffdb9dc18e6f34af26627c4be9a52af59cad90034fc4124f292429ed18752839c5c5e06329a3bbefb1782b3fd115baae9b3fb4ed120c00a3673a9668e21e065926c8a3af4877750ef01ccac036af969b83ab8bd6d70bfe153e92c88a78dc505b4bd199aa6c482d2ed9cb12d7a194993f966141b24d3b7d71e107ffb59bc23f71075609f6479a934e4e3a94c2c1b72bbb6216ea7a3471b8cc0be7cbcd025f47b7a846380cf72261c191a38aba6307ffa18d4c3a48c576ff5ac767f82f28dea23e8d40dd766dc5afee5cb06d311e2d6e71162ba60ca0fa3077c194448e53f9ba8f72b7c09abd245034c87285d6b0d24a3e67e5f900a4bd0f22ac57a9c36239d9fab02bc22909bb54eb622f6e30b71a596e6323e05e902d25c9579a450e09cb31f291b4cf589af88cf1fe22505ebf5f73026e732695a3a66069859f98ab10a4966f7ee22d98a48f9e71fdccc6ebc9dd72250cff0987ea1983fcec0adb91d0f091be51a2dfc5501e5e2d135e64788416bebe3347cb25c1b6a643c7900da5cc3fe80ea1b2f66afc77ca206b4c1626524640381c95737dd692309e59472a340306bf98a2a523b123a98ce021313d02672d46dfeafa7a1c8fb1ad6e15d4ba5db641db0b240edb7b48b37872621010661b968d1f17f19b042143ce296a0633d4946f4cf232a5aad20ee9d9314ca0c4fec0a9a260966e11ecd74cc8db7a7aa0ee4e8b1170e221879cf969a7faee435f61dd608efab554f471499f2fa02d1b57139323dc11427fdd1becdb7e740eadb86d9d8cdb8eb311bd371cd43adfe6787810b137cbbf0f9f1e4b5fc9855ca195cd0879fcf716ce06b04a1c302ea92a037011bdba7dfb18f19c800f9d35cccb45d5a0e4b26573ae8033494ce28b3adb8071e3f1b24fa82a01f923dd87ceeb1324c777a976464b9ac497b130b2b0bf4741b7289255d99ad86ec2c94a970795737d73bd7c58747fbacbe1fcdd4babdeb100f3241bd8eabe0be929fa0c6c7a1694db0ba43266ef398e13cdf755eacb1232e541ec3c8e2da6c28cce7411ad7c5df4f10bafdaf88cb7eefc8ccff21b085773141eba3d66ad34607da2e4c1760a5829bf913c797d8f93f01c112fad7f4134b6625050563343173f89739552b41cf9dc7608f508a29a7cc703e8cae9fed6e110f84c0ad366005f25c8c598f8f168c35cfdc0a855688a27eb80be7a8d6abd0113334ef0b778b57c1264c677535868c5be9183997fd20fa3a277439348bfaac7206ad6e00fb1840c4f567932b7af6faabe589503bb353e4c588dd94bb5ffa2c24af5a65f05cdc55be1c3d4e2892d3df995e8bcb528e6f794b8dbb6042cc1803b2245b30f7ba338abb51ca16a213548572c9ea1aaf39cae143308f199e07e82755e3420eafc46f2bcc1db81d671ec4ccd5451fa7d6f5cf0e35a72061f0524ad5f94898cdfe79bc796ec605025f86c15c30797af678741558463494e20896b304dae2f6e1087aab718f20ba40cc081032f52ea03046c32e36fd9a1b5ff311190494e391f5720b73bb848e8f8109474d73c4466f9fab9e8a06f63b396c1b12a8002cd9d546fe00686fb691e28a95670168bb2273c86bb65a9fa674885da63b63cbd934fe4f5f93362f2d644891c36a445c40120602e5f74b174ebcf45e45d86975272f736d86c002b8a0212c31604d3980ce962cb97d22baf1fbd9dea44761228b99accc0059ce30317271463ced2797cd0cf36d136aa2d572f9826a9140d5367b8a01736323de776084a82d802b7c7f08a9f520624382b039368ebecdd32ae5d308323b5d92d96b4028cbc97ba4849956303012f9ec9f872589392f7d8790a0d529f4b97c758cb6b9f93b2a475ba4aef19b7ece71ff7ff98402bc8e97e470c8a985a92b5270fdf0b56c64b5c4ea7ad8fcf700146ad7a0e6c31c42f4e56a0020d12f5aef6a21a7e5a81fda6b747f680ead148f47f5d8b1b8a4fbb96c8d48745030158c9ac3444a8e3d045e37aa43a158d05e19dfd4765bec0327da5d6e08cabbc977354610f1a2532862e4267d3c3c950383890be690750faebb6e0dc529984303d4bf301c268a6f10e4e174912b1d9357a336b850cbeb6292b08bf457b83591088d1df1d3a0bf62cdcf26dfb058c6b8ff2d9761df0599834c89f39dfbc17d3719e7bff5c6767ea632f4b812d7e242d8e4b9ce265e7a81a334de484437eefb8140590bfe8bcc04c6a23944b47a6259347b1e1662a1ecafa5ff8ffae08c419e5f9a5d7d5f4d962e39dc015702f0bac22ecb896c29413ffc093cc738c1f9545fddeeda0171984c61c2dea6329a2809b279a17b6a41a07b099b0a92e964c991012f87432e2c00b0e0168931f196846974619e1840977a4bdf4834ddde4a8e1ae234a83d3cff1ca99db3837bea0701d23d9eb085b7fc5de2ec2e1cc5c7256d2408be6d85fe07219f2855703f5a5d1f6e110214dc52f64749e6085d85fd3681da8038349236d99d5aa81aa5782d5ea6ea618ab8d60365aa585c9c988873ddbc95360b4684d7afcd77832212aa610f71f916b0ab2f0a30590695eb01cd8bf6afb91ca8d6dbd01a576b7b5f991e070dcb2b930abb36a581ea1f7c1f66f9c2277467f0a885886da85952075a7497bf35c70d960f69f2831aebf050ac6a00e9bc58fb2cf26e10dbb9b95b4a142efbc97364afa5a48071c730ee9db01673aea6ccfa20d2d85d09d3a6d1d2b44f69c4d640d91863895930d781afbbe383435b17782adca20e57917c900a9bb5e208e3f42c1ae243e1ab47f6c2532b7860be94c5e9788fe13f18a98afd6b6f739f2a999515c4d46893e7573df5c7da2ad00422bfb569a10d85775594ef333c39256a37017cd4c37700112011901a7a2b50c593748cc1afa08ead32e34b928abdf6a44385fa1ef19984dd9505ecfae4f09a4860b1fc5c720f7d46310690f3e474a82cd52bbf4fcb9f6678e0ced67f9cec2dea14954ca41ed09ce1ccf184f77f1506070c8a60b9384fc8398aacfe07bdee0bef46aa4d7ee4fadfd70bcb97fd8ae5ae3595b49688d9d10a93c3c44180aa2277ff41e2a8c9e639fb8f5be0fb2544d1026bb256deab0a797e05101504762f3d605092522ea170fe9e77b11307bc1e9230adf2ea0d9b4af8ba86c48e55c4e1e71929d9ffcdfd731f1958f4672d782e925367ff3ab030fc55b72e80c08644c84e0a82c160de96187aa4e2e2bd078713aec0a08839c79b251f492342432122b4f405a5c4e29e0284f2b8b99fd87d0f70d4f5a4301a62a15df0222f708e2053e3213d78aa0db5f307076fde940a3517b6776473256bf48ad6fa99d9897d7f011a736a12cdf55d4d74eed157e5147e85792574b2fb27327e48866392a411a3f8714d80d021afd091ec8a75131049be9c8a8f6637a97fb31e3c3af467a612cf5dc1a3a088e7354f7d2169a69176804666552a2401bb55d322d1a25837a4e1bc84f01ba5a0cd0b43a83d8fd9ed2cb848daedf70b0efba1910e6f816895b7baff71954582feeb05f7c368a028ae3b5198a93f7cb9e5ba7c6ba2366f16d359c417648ded89e917b747985317236c5a9f60daebb6ff2de68dbf4c8d979180ee4ef8094292f3a6b274b5f42381a8a69576701c08919af5ba5ed5c49d691c01f02c48baa179ef9eeacdf5930c79b2c2e8af8ee41fd713e9ed94150fc2b661bd848776c3a017a3718fe11f0b8e9b0e8938fcc329a4cb7b3de213c353a2752a968bb29d7329cbb5507ed2f87f07984501cb45110e33c021728fd93084f7afc927d877173c6fcba4bb601772b667db0db8fc333edd48faf18604f06cef7bcc43e4a7fb3e7cefb9564213ce042041dd76153d7f1d30e90f54b99f3c05184e08e4bc37e60ecd4dead0f7a71e3adbacaaefa9ce178e4e221d75e27496cf8f51d44ff4530cd0c5b6c6b7cc8deab12eb08653d670db1bf560ad6517b34ff4e7ae51f35cedb4238c885d0ce054aba63339901815d21460d57779e907ca297e4f22b163b8740590ef49ab1182f35c2c827a1f60b2a51a4857f1ddec4d0e13b18aa9379f340f6b43dfe45fd5c59ca76050fc93e2bfcf1655a97c71fa2185c31dc1a3aba9f6173b8b1a50f7f19cb9a719cec97b8f33f8721f868d47c3b06ee1294ca2b3ab43e6b8979ad42ff14452721cbd8cc44fd024a4415f74552526597a5a21023fd80be26a2e208e68101dfbf6710b1b3760601d3efb86546b81329460fe04ca3ec447e8ed63eb8775931b7cf2a45142b8350293c13e5d807f2c2ccaec2d2e6213d559752600adb77e4d84cfd93dc62eacc17ec16e31dd65dcea4bf2dafa4bf4448c7139dac6624e932738df4c88b69b926825d19a6ea8179eb3ab610f286a92dfcfd468f954345be824a2d4c3a9d351dc1f73d85aead114ea025ca4ca3d6172f0117c2837de583f86e820ed3ce2b1ab254563c430821699720fdc07a3428c66b8a58b6a2abcd7206d52bf8296a2b9e81bc0cf01ba510a4d5f840fc553941c0840c9f82506b5d8f050a4faef83e4fd96ee46157f7383a7cceee63adb11f82f88941d3319585a1bd8848b151bb8f0400e044b490a6329f9e07e5683997a7e31ea624a496862da71d6d33a06c0b7c4bbf0e142878f6012aaac5510403a47a158392ad2db5e1a78974acbc40b8551ff836c9a32a26b69100c46496abd4c4e9dde1e7161c3786e717cc1d2e04d9d5cecbfe2615586a45afc6fd4f3c6ef1ad217ae9f6016e76e6e729df25902462d4ba5eb94c88c2db146de8f7f394ebbe92d7e815306be14b47ef9e3bffb45c004341e00f9c3b5cd05cdb808b25eef7c686df1d7c887db12cbca529fcf5899017469e9ac89423f0b9d6383b6a77fab460f9816a49708438d481dfa0843be2f0ba1e009dab687fdcf44b651b94e2f3a665b8e597514f360e4adabbdb36119d1ff938ff7eadb959ac6960b65dda0135f0e97effb23690990a3683129b3ab7c9a6443559157be9bd1e55a133eb28157f7e10403fcbe7a72d60b37f373503e739ddb47c41b7dab5db03f70ed633b9cae02302caf6f3db171cc5de82a4bc72367a54973bd44ea310704605833a382782077c2ce8faea5db50debbaa950295e70b260fd242bc22d1ec625562c6383e5ebc61baba4c5d3a405526a00aa09e415aabea368f0eb2656cba760e20ea2fd46572f34d8bcbb3a8e58eacb9ca3efc295fb64009523d8f77ee3729b93d4f858173da503f53a856eebb01da1b7de4d8136d9198017ffbf0cdf8d44cea56515d2b63e5f4ab3ae1d939cbb98d6394cd111ff7365bf9a012e9549211775c80902e01327f9b6109f243bc96c9c32e1307de86de89b887b17c1b30a7724b4e080488741722f5c9a5f591ffd8a4af4950aff3a229425e8930d61c38c579d538b72b249ab225efa13cd264dd68c59dac87b464e1bc4f8544f267a907934a9b01b644423233ff72903011ccf3fb9637631ecad0a07f51a3696d249e63b2765117031d9c033b6f91ba27ee4b8e08ba4b4c2b36bcef8244455b1f740d6ace3acf2a5443cbcc0611da895c29df11d0d8e153e6d87606847868c862300911e48a2d6dc7a4b846cd7b8283ce572dd5a8e7f31e4147cf4585f30960c2aed18b2e85d09d0f9bc0ea01926195ab5a76cc6ccdf7fd30815fc200ad298ccfae658b3e4c491fc929c15c09453c39c7c16c143fea8cc42867d7fdb4008cf052427f05d6e3849e251bf40c6184e1c6398340793875f544dd9c2d2adf2d05a0cb4fbe0395a107dd8edecb7a0291122c3a2ffe0d9f036a3ab0ee0819c665e182b5e65b45ac832fd648e7af1e09da472992c915a1f55cb0976de19abe27463da07dcbe420ba1d7fc9bba0418ed3ba5685f49d51ae093665d21fd734192591b92554bf9cdf04c492bedaf98ac819fd4d52bb6d049e86f40fbc8593729d98068d37cb5fba3425a22506123ed4fb440c875acc6e175d6e9564dd096ef0530eda4d3e16f282a17245d84d0b271768587271514a3a729e7007b6c97568a1218cf74804aef3c80db94ace99de68e9f6bbea2b019c0d3d79b9a3c52327ba32a1f7e4d16eac7759f751efa44cfc94debd4f2c3b4836c88eeb5b8ec4b7233c5269e13cc751767131d8794b74f0e64b2aa9eb511eab168d592e7b402c1457b8e807d7f1d641227345e0dce4624c30ceabb3d69ddc7f94f87bd15a1b6d15b4f9cd44519a3d6e7122232226e7f39336ef8b8c48c3f5ad0ba91179787c9edee8e8e71c02bab2127c9a20bdc8ac56a123c716c9bb6bc292a533f164bb7c93ce1dc081badc5c31f5c3f32515180db98b9cf20cf78bca159b897da8b932de5b36d7b1512ccc996325676c1cc175ffe5d36c76b8a7721addfa76bd973ef50eef68f1716d6a80d2095a1354f8d66f7a7e173e8050649dff3a72425c2b4735d059e8d6ca4c53ed22aa1a66abf240e326c9cad253ae2d2e83d51015ee8c142d1e3f2dd8afac9a575025a2e56e478094f06d45e9dad79d1cd7c215aa715c01af8f85dceb028a6a627454bb040956811e2689701775696adf939721f5e1de21095054a163f8d31ff3630071c233b9b9478518a5fd4c700de6a8e2e8e9baf9ae6efbdca88a7a7caf9907d6572d6e1cf62b7883617fe071cdcb4963596b93ed9031e3fde3419855e50cdad5e6e5ed348468146126e6db4a3e1915851a8891ec9d2b67d40fb4c2d1c302d16b142a92bcde3bc1a4da623701678a6bbf616abddae8919865af37585f4ff37b58dc59116053426c2627e94f7432fb943e0887b44a3ff00df3d8db67172d9a179eba21a771fb87421092fa72aa0a1dad62cd9f8968163034937217e0d2319857c388cd98343c697001cc4216925a9ca1d2a6751b77ccf6e303282d013fd6e37fb36d42f42ca7ce65831505ce51d0b4c0e076ce7f6807174b4f2365bb1ecb5b96a8d4c2638ce3fdd393d95d001beba7afc9bccdb5b69fb3096c902154c68887a28b11d41746d8e2e17bec920666ce7011ace36e161fee8c93ef7fd607aaacfd99b2eb4d6654c1370ce1d2422ee8ea61607caa2574f3ca803d629ac1c23434a46284da3b06cd7da52734c1ed13f1078f8bac90b9bb3f73280270a4271e01cd3e2a8f3fb333594c7e336c9b6672a7627f51dae84a79aa863e1e2e0be9bb289c30ad3a3b842feca2efd2cd4040b9030ed9288f1c082c7526f3a2be72f1d7048bea22faf645eada9f4766c24d206c20501a983fbd3ad26407b7f16fc62980380ba7a7a2a4d08010b5d73153d373635f306288d1989e279585fd5e0b1be7baa5375eda5d43c6bf0b2b362cb111a300b8313237332ac604a356f04bb367472f846d0960da26efdbe49805e38c6f70cc7f7753374f469aaf4b35ea81ae829272a271daeea83a2c239966d7f2fa25233eec67010c72f3653bd068395c57a59464d45a997b0985b643fb07516194dbdacecd28a4e893b8607f30fd5b029613bff8fe3bc5123548848a4d15477137ca4d97e3df4e1106480e103e7fb5a18085d91f28cc6f6ce08afb25ce71f0a559e47f1979d297d93a28da56caa7c9e2ede1ea6b340a4afe79f7063a09dd52a046fca6d3ff5a3f9fd4d73ce131291597298cc40396e66cc6407c07c0acf4683be90e00a6f31c72014a9507b3656e7891d5a8599febd80dd6fdf3b195137e696cd99f098793c68bee98149b15d628e3069436b8cdce3bd316771b61937dbcd0cd98391e6df6d4c31f7e206a4a40181d43e1ab9a310f8120f2f3a1c425f951036796ecf32b832b3c3a36736178830231f624fcfab6584354a9e52693dc30e7a17fd7f7f0a4ff7929f7b0aad22c6d452bde764dfb93faf98a4bc461288f17ffe36f9e674eeed9949513cd773714fbe5a19c4ac945646cd09632f2dc151e72dedc7ea01524a018a70c6e26c39b28948bfbf9fd70702159cb7fa5bf111e01e5386af35d46032c51ba1db4e3160ce4e8d89e078d24274f453a534f222914b89cdd7823c6a945aec599c3099df9ef1e8647c4fab430a26d7035e8c9b94cbcafb75eca1e064ebbe33d68f045c58ae72d3fba2f9db958ed1c5b30f97924a1ce18fdc89c4993488dc14aeadc4f3a2598d8887c2da3e9090d3b01779e3df06281957603182228a0cbdd8ebf7b87eec97ed054392850b7b8bfd7c3e2e4e6d8ac6af8de3812204c7105f705d1d5811bf269950eb05aa194161c5f2c02695a30b6e699a13dd0fa93c18f1f212a9b42b3aaadf3fb4e7a0cf1ec8b26c31fe792b918e8e14935e684c886f2d0b31f3dcab52bf29ed08eae213e6b3271cf19cdedad96d5ac0be664dd92c58f003648b928d5ef02e6ee48d1e4f55b63ce86e012a7d0fa3afedef2396b968bc4c8124ed97314c1866894bf3340667855394b39baba546881217b1abc4f065e40d5d5383641e4d49ca011a751f380fd5bf59fdfd470be6d2de061ea4eadeb96836006dbbaf1b3f2c03fa97778487b36e13b40d8bd41df56a4d062103a0da992d9d5eb524274b0c7239f1a8a361d41476945b5da90ed3b2012c8cd633f646f5ef35bfa77bb5219ad1ef463f45a9a523bcc57459efe6177a771f548dd1d49f6895f3aec0ef9ecdeb2d4fb10ff92d2e3c957bdf19a52668fb0d04d9a4053af455d2e25d0e0ecf39f1496a22647d45a88396a3d641d3050fc0438320c2c032b167521a858ff4306da3fd17c835fe2db567991badeb0585f07d562a3fc2eec67c6d531b42d89939b17b6a72df842525c394f4794906b78fc175769f6b8f6c8d20a3c491a9ea3c353447a233ce57de52189677fd8313147e128a17d8afcb928127356d6255d11577efafb7647901676aabfcf71f0cb7e3deb7038d72295c18a423e292c0d02a22e551abd835affc773cf1c6389444008f843e85e93b77f705b3e939c5201359d91f3d7e8aa11eb83489f742b5bbb48b0542ab361cf01f005f5302ad61d8201e2b1551f9bc3190bb62faff3a5b462bed4e98c3d9a827742e963b0e09bcf2c97899b48e30081c61fb8befdbe2b5e9d205fcef2bd037825e975ae63c9e8aecfd7f58d5e665d47f10b0f99a4689c40a2c58d1d6ef1f15b82452428b31e11944bef74b0adfedb26b447bec84db38bb1f5884a5a943597c55c869df74d1422c541c5849a05a6cfdf255d890a73f97d747b96f750393918854d5fd19c851b8eafb0336386e4d943ee7557ed8d8acfcac5bb04d0ac55c1ed50304ae6a1aeb2e80b16ce2e4686ca3039e58a782375868a78ba0456215bbe6f4fafd728d0d09dc961e11011353c74bb0f0e9822a7a52125f7eb9cda3a44f3b4edefc468d713f9597b622b64eeb7bef6fc35ed55575f09bfccd8b0fe18c02a2fd09e06f7577d8ffe7e85f6c2c38e4035536d0481e39d4e23033fa33a0e4e1b810b05178d632d96ab13653c1df2b518b46f54dc06d3632e69d7d31a9a33444f16268dd78bac54b980b15c2aae2b5c113076f07d0a26a3c59af8b635130d4bf9ba8c70c7ec9e497504ac5e28d902c3d9455907aba59d47e215442141e5fcc815795ad4a1ba6996723ba1e9ef0a41c280c11eaf32c6cb0b943d21a2171d0a5e243f1c07b159dd2199c483b46b76fcc58cadc022ffaf219dd87305ade19b35d42f048fa20b89ad81c56d84d6b0c2e45508e12dc3ed3d7f7a053762aa11711b59fe145909bebcd54246c126273a9ad5a9b1ff35c8a511e3ad7c958d868d3e62cc07326de4d90e46e13f5bd5fc56b2305686924b5988362931f9ad05ecf7faa1776a21b4f7b2d77393e4689545c694ce7219f6ad5c6df2fe325cf0c9746d8fbba87eb3af3d67c29ff5759eaf4ff3e0cce9c50c8fb143324dbec95c3568534e44191121a780ca55d0fadbd73c0c987aeb63a4e205d32b3e10ef6bb3cd47768f9abefe83d2896633c1d5650b3f5d6a536a612a9dec7cc0468b06eac603505cb8b744593092048510ac72979eb18a1327179e4a7bf85fc76d24eb5302a768e7fe803c88bc0be6eb464eb097dbf6bb6655e6cfd25400542602975c0697f1f99231ee13fdc156edddd40434573680a111c311278ae7a35d82a954bb67b98a23b32434946d05424cbb953d0d146b962a47becc385c6fbe17dbc8dcd45c0db43e659fa6921721e18fc3d6f21a948a0b7e87545547e87ce7b9ba7e5dddd5a5003687b2827f7514e452259f3deb23e2ceb25049009a49d9fb585e6c6af01b197301a6d40ddd9c68dc6ad02380b98cc8eff6d5ec817efb62b10984f91e54f592267ec585998e3707fc71bf610eb46637dacaab61b2a8ec647e9fbcddc182a2985c34f4588f8d21137372df5b9d83ec8df0b2bc75a20a437d2b1298446e108647b99ebe25e23639a3fff5087e4c09b36b7217feda7f05664cf3f59b946f14b4fe1fed284dcf8d3cb85dc2945aea5a942b48312d4526d4eb77c07ca9b464e663f190a8aadef584c0de0d80183814c358fe6b1932d1ce7d7bb8d79d59e2351e0b279ad7b660218d3514b93df56428dc2ce478ce1ed6c01550357c3787d83ec6f0c8fb7df63505d6be34026fca95df81165659ba330077d9a95335a9d966684e0b6ec0861d4f6255903de18aea170568396eeeb1cf09241a2f74324bd82ee661b867a1a3780912ef55e121d117e41546843c817b3a31b184479204e5dba121e4cd5b91c929a319937236a3a8a6871a20326740b23e36e1a18c704053231ea399ff2fc98015e289efa7308b28922232b6a60535474ed64eff9f90a102f7623d65521dbe324afc8b95fc9d562f5e2b8dcfede110910c2cf04742fb836ced594884821b139fc7c39c073a7bbcd03e18b3ca5974d841f5dbf2d049f2a5ebc9b4adb8d864118180f3ded14890256d44a9f78522e73d8bb1f473757fc41d4ba6a10fdc6180a107f15fac6f882e8ee3133a39e54e3428bde5ba0c4f67dcd121d7534cc541267b2db2518abfc72becdaf8796750f67a7551fa113cc79d77c97d34b8efdb4228a588ba8aef855bb11c318453369e5690a2917ec44e8b0bb4b0ccddc8bd1442df9a0a6d8c5230021f1415db46369e4e9c0180a081845cca5e61392690462013557be871f79f68e561e94757f5267821eaa545a4864f30fb2599e62132ba0b55c886417774df1dfbf33285f9cec8bd739b1f7e7ca05b9935343288c006382a4cba862fde8f11ae137f294d310479e577c16252ed4180312c669fb4a29438bb79011bcde0e66688f36cdce9ff01f1ebf20298f949c83058068d2b1479a9dbb0b94b6c4f71a1b22655158e08b34a35822c3deafe2a30a6955692e8ae7cf35c875892a5ca2823091f3fb0b39def9600e9c6cd61fa90b096be516db3e527a673a5f757ba43aa000a90d61193f32deaf24766cc62c9f8467082bbd33004b1124a7ac630b0ae2c45bb2b0ba9537e277e253c258ab35ad0732d3ae5935dbb24123784d0912aab3aaf9f212c8ce31fdf21284a2b954b2c914bc55cddf71a93c3b53ea6c3a6b5f5ffa7f633d2593b0507532aedcda3f0b5595e1e9f718fcf1080a7608af6d94387deb5325fd67d5ac2620626d67bce6f87b10bf1c7fe81db00b0df1e52adf67527a07352cb783f44b34ec99e0f866a2d8485b14125fcc427bb6c887192c70fb64978d5e8cf75498a7f9d230272dfa6f0acb192953a8be684e381e0583914488df735de7f92df02ea15c058a0c98b334a304a6e97652579652fd8833897073e346b10e2d3e5cb84f7c4788ef72ed17de6b95954b30deb5455774a7ec6694d009952c0ef7bdcac44ca8a2a2c4ac76c225c70c3e40b4593fe613a67619c7eeeb4fdde4304db8b6b7713406999422c4b9a4c22bd8cea3f66a9e5616fc98ee628c7bf6a2910bbe364abaa56029d88cb5f3aa0e51b9d6dd78eaff161d77fbb06e40308a61fe32250d974638ff8fdf6e376e835a89393ad2a1456dc5101825d7c6ca51fe77779a21c628559af8c188a8965036660e2b86e57d9b2ab05cdb2c680499a631448d9aeaf0166b9b117029bfc8002e100d896ed0d963a4596c4818ab3ec2be6c8221b2386a355ff7aad764a9f5b2c7f5d3d0083829a881005a89b20d767bf65fa681d8e41bd21511295eeb7e5e0e2c1a0a698b58b6d503f280b381538183e105a741074c11e7c9150a2fc423ba281d28d0c5106895225561db8ca458c749823dc06c6824c964fae0141b0017ebfff062105cf8bfdaa582035e0ecc6d16ec94922c946ac52b8341bbe9cfe76bba2e06555afe6be69693845cde18618a3a5010233709abbc37a90eab664596cc3ea44a65063012f3495062896c5da7d6dfea06b4d636141698ad7193f896e070b0a21cc6a225f13b57bd10c91c9edf9f22c665117fb69a4ed5787abac9e8a9f18f8301a6a6165e061b98079a62a4b5f19e40089f62f4039d1461da7c6351c72336cae4e798bdc07a63308f88df9aa126afc8c69c27f4c1fcacc68d927790ce8951e60ac8a5b975263d4aebd1f74547b5796199548243407c2cb4c10d3b248ff4eef3175be77b0299ce64880e32717973477198abd9f7d6c38a7de5de566cf46f5e2c26fb7776d35d26b73a58b76fc5b2d34cd36f66b9cb2a99b02b31d9a436bc3f5e24066d1095d194504174ddebb631bed786e78ba2e7cb5d1bbdc884db98a71ad7cbe956f2632deac8de71e099571f111f1ffd31f09e19075d22a1e5ab611906f1aaaf6d19936725a0c4d21549ce736ee3851ab312e6681f2c88650d35a1c1c051fdd130b51af4efc4bf870fba0bb2fa9f5a5b6efe7866c91ab26b7cdfa4efd2bcd59d6bdb9e31688af5d5e504b649bef1bf17877233774cb318905ab99519b1654350f6d91c11330e86044a00bf2112f15f7e4a0aaddeb9d66da1aa7c5636a4c80fa25d0fd7c96d03336f25e071c0db55260977ba9a2bc61cf841f44df45695871d8669149e87523198963484917901041cb57c9395d6e40ade56100f4a073dff84ea49b35a3a1b8f08dda15583710ea1c1f855ef667e49942d580eb8935f32c05390fcee4af911a0d3b70865ca0bf2d8534b85812cb1f4b7041393480a44b12a5407aa711187992d6a0a3d88316cedba240d4b0ef64fea1cc3a831fb396dbb3493ea5624ca7352ce22679cd0e53053c2d83bb8e3b54ba112c9170c6cfb79bf13ffa6bb32768574c56d1e4008dffd4711b1901c518cddd753d50a750d46ced8d8b7d696b46ac113539f2c32670c3763a8c7dd9fa85dc2b734a643c0c28525ffdea74d1341b685813d2f8f14e0d3f1e03be7d53c852068678bde38631e38de2ad6eec3efb68c5a4b106288eee1ed089f88c4c8b14540618af2c43ef363a35614927d3dc8a164b927fcd29f9afa6e621535c40d539d4c18b9fc05616031e47a536e5d696b7d9449b3d7a7fd039234a6aa930acef9b3fa7155708f4ffc361388d8403e7598ea92b113fc89a81cddf28f954fb33eafc984d7b2468e9b1c741718d5678a1240ac8b26c787334a32c829efe7ff669ef666559e6165a063bb55518ccded5b7eb0191e3d5217b83e28f70fbbb04c6106b3d4e41fdf008a2c342cb22ee4c95d6cddff43f10781c4aa47c99ab6a89219aa2732943167a7ce1353182caa541f092be5d93f33520472f53cfe2ec90dfe9c8457344db5726aa0ab070cb371997cb8d5236c820896866f444391a07855607840a8874231b29c88d5f3f42ebce3017f3ec4fab450004ce5552c199be28db3d842ad6001934919b65110df49a501c55c62477506655208367c7d66b032d5b7b9a550dad63913221f3c3b8f0c7d544e6bebc79307f5763caa92f8d94c4c56e52da8594ddcdf7ff8bf6157973498543fecd53a6b3a3d165077bf6da3bc90499985f09293e2fbfe3312a0da12d5a871abcb3ee13f23f87ee18ecf274cbcdb8065cf0adbdca30326d61977e7a9bfe8a2d8a257fc8355187ea4b7060434329a5c1b499c738708e77133198a3cafd1f277179bd5ea750a02e8c2ce4e546bf195d28bb2de08b131148619f65c976dbe436dcb85e53ce977c2df31fe611050046b45ffd32e8c79ac9877b42c1848251677ec2beaf4654db65223e69c3bd74bb08305a67d072747b6471bae8e1d1798c7e8f7589d1b923c3c985eb8aeb9bd11ca5cebb87e02021749e90718fe11f5b164f99f7890eb17f4db5fbefbe790a6eab63e1fc38e93f442bfddbebca5eb8edbd58a2e6ee20f1bfd03c8eec6fbc1e7838c8efc886a9869f09144ef3e0a6bea355d823441e93a6bb322f8b567a2803a677d5dcc12b858ee2d676ff24785c8079987ce4f0a2b0994035ff076cd152e0a173d3b15ed6b4b0c5e6d38c36e0b0d3dde4cc93fa76025e18f3950f16ab37555b2bdd0b889f1656275d0f70af5b47cd43c52f94bfc836fdba31dcbe283899954bac1268255193429ba5f82d1f5ac23d85c18ae7f3c3865bcf88ce8c342a19961e9710af477ddf718586164c6dbad104cb93f5844afbdbfb965e7693dd5a63c94d986d26dbf888109c9de9ecf985a70279248ae171b93f786915ac605073bf43ad1e3cc21c82ea0d5ef6a140ba791a98bd194a63f126fe998c3b608491e27297197c4bb8c89bd305d7283e0d536d6190f35533691951d411fcf92acc06c702473354a20ded425317f57dfb536fe6cd6ddaf0a28360d8539c6d944e8d81ee87adc7a36d2caa1392b21f01d9a13fcc6e7277c28dd1d3c4ebc07a149768f41c4b94656a4aa4abc6f5c59e3c5167a325215279e6198d5c4454f7eb00c85c35d2751fdb8909e327dd0872ad8ede6e35aa22a028596b8fac201e1eea850605576e852b34f6e8b141b1b605605decc42dcb5bea3711d651c221a2cc28073a16cefebb2f93c26201de75c38e2db3f7027daaf0f1ecfc5ca5013826112ac96f2a28dc720f9ab08ac418f8e0a26daaddf836bf9cfad5760d232e03c34ab4dc6fa8c9dea2ee28be62a6788a8e734df78cfa99c8b05d895b969cccba1eca64b35cd3b8abe83c6711ec1db439524cdab7ae485494ebea73f92b1671d6f7a0ec141cc9565a60f90a70dad132a9988d762b42cf1fe7ac7c8343ecd766bdedc6500b080e6e29ed5f504f39c6c4a581b1e5b1c1cda833d17a9aee21be4fc9ae0267585090c159a5ce1beca8fc5ef51193cd764f2f1105f3fa92c7fdde472b7f92f88c119afbada591dcc40c9cae3e3a4f1021e4a39a6d6451e409ea446908712aaa4a1463608008b735ffb0dffccd389660cbecfd1e3dc787acaddb4275d5cf9dc51657eebdc63994e33c406e8701246bf11f814c9a61e28a6839139bda6d02fe7c41b70ab90044bfc5f21d1894908d3eb502a53f6dad5a407e2f7b6c2ff326374b0cd5aaafa957da1bf2f5f56eb1b2ad092e3b639153fed31c4131e847fc3276357620b49126c37d5451f145e9af3dd57e44c79d18569b74b1c39c73db160b9c0844496c828c52c35642b715237aaae8a00c367bcb34a948ba4888a8079945f9e8ca19918c4e014b218c57ddaca851467fe1ca569ac358af8a1bc200af6edad846b2a7e7d1447b5c6130948f7895c141d8c7f3da34ebd5f066766da8ad550e81c8be43cc0bbae7b3e9cfa977ee8c898ea54c0b4464f8d7ab28506560b0ed0c2ed092f59e0495a2639a4fd632c36f355e5e85cd11b1f1ed7227da10e12d361a080895f75486dc34e26e5e2db8ed55b9c048e3d9e2b0619d7b5e5d8ca343b31d657ed56036efc4f6831937bf564de9359eaab634970d0921256adfa0943e6c070012be07fdcd794cf972a8857fb49f15dbdc4ca7c0f49b95c6e8127904473dd11e424edd003d347d91b078eaefa15c55e51db5554589f0ba4e6ebee3bb15920d1c3394335b48fc1e89d5893c15d11465780522ef010a32d7ee55ae3db03e9736aa183ac88f43911647162cc87043d5e5b25d7a916a1355b879900a9af17b236d68748d7ed57e6d3fc778e2a45303edb2e04fa1017173d81a596463fe515c7e03a35074065a19a8e1faa636cd86767a140eb59183a2bee21ad1e243a45dbe8ac8ec9d341211423c0474c07a176f96c82a3abd9f825843d34aca68875ef16e0c07e1f890241d333e3bd9d18b25ccabb3fc8787c7fe8ce09344bea017d2fef4aa773343db14be33a89439abeac08109d173fcb05d0fe1f8da0677346316834a99458dfdf91341e4c913ef8c75ea115d38672a1a5e5a4c7fed4358dcf45f25012459458f213f2d6e6db3f058a349a46d28e3f687bb214c8c54d943dc390c01fe850c1418c8b995c71d7f36d07d124a3e48fa28034ba58f87c65b92c6341aad8418a9ccfb4d209839f1fe3a976bb733a5881f8d6cd496818892d3de9394cdb9285b20eabd8820c710bca69b30d7ab66388bc1078fab873723606d8a4c8fd685d2bf36d3c871838ac957e74dfb3235b00519def7534fd263a7d82789f3553f953307b3a02c7ca41fc2e9d4008d607a0d49d901a4c9360e3db03e6a9b9f0c079e52152fc2a8e90416e580b1f010bed1f5b429f6281a4b8fb0635658167136a8ef4ddc3caf6424a74bca88eaf7ee3c48b8efc4e41630221b2a0bcd3471de80870b4ad0efc800b44b079cc0a71943dbf27ebb04a4e4f9ede1b53ea7b653ef9801ae2815c1b618a95574d9a66c2be9c4958f3ea0c6acf29e04575dfc1077130f37141a39e08abb7cd35fb933656ad3b24d7bbde25e5ee39755b92cb1bdc13a923767554350027d81a83f92f22f48685702f7492431ecb2c010910b641bffa1e9b616a87eae83553c03af30ad973788373764572ad93eb8c4865ebac8c5164a7d01b3ff5ac44404d840e5d582dc9e075790a23c4f4a4d5c42cab7b9dbdb06131ab5f51354827297d1f2c6ea2c6f76e5d9d91ee4ea96c3fdd056c6d1dcd10058320fe2f2a9fcf14b0704cdaf567e2c8fe7f304c6ba95f1f1834c04b8279000c8c835787c3d99d10a4513376b2b319c736f31e0bacc90cf74bddb52d07cc06da703749e6ff760d086e3f16aabe2f9cfe5f1c586a3a598a270f9ae14a72f2b2d025f8a25e66fd6d57cc3da38368875a0f5cf219c18ed93db5ab156c6b72dde843807027342ac3339ab116686e77b56b271883fdba752c2fa275b04d8e3cc421852bb3e4f253f5793e56de96b79cd8dcfc237f8a0b0643024968e182446c6bc8b7fd255c7366ae88d956c5af2208d4267024b3d4fcd67335701d39fa7c2e66c6a909921325c890240ec560c11dd685211d320d9163dbfdeca656c32a29160e0477db6699d75b021465cd585b0e03f4995776411baed8a455b967ec516125ab754d21a290f5dfd9a582465c03559faaa0ffef8e455833d1b0c2b3bda22c6ddd3317940730ff2e6e408b1bed183db44d9fc39ed2b8670a66063666e7030766d5b1959ad55f9e79c95e601c483b6ccbfb83b559c2aec9953ce73530b52af7ffb4fb8fbc47d58483cb2f852de360c8142e59bf1d37c8fd0fdb5c2990ace454db220306713b5a741dfb7733c23ff5f2c64657a7342f644a94a1d096fb3ae3525b91f6b445fa2809ba1862c862c0871af5e626a240ab844fd13b973eec45286ac8b9209ce355af1235f9bcf1716176bda3061d293f870be44b2570303f1377d6832e224b633579bf98f44b7fc2814e4cc5aa6e8de6c508b964328a92787ca4018a3ed0d5ee67da3bfe841f3e3e8a37bb4b2771b6ed4122eb9905d5243434adff103fd60408334d1b9167ffcbabfcda6a8c514bf178917385af3e7712f95f02bdd3e34271f0e18e5f835ceec23c8e5bb09051bda8dce274aef18e3103e51e928b17979918bf3521d09bd2a87e7c421eb64a924e80f246eae753d5f28b84ef6bdf7ae716a2ccc45fc93d75c1bec85f8af6b15ba43f6b708778351ba5afbfa6178a3532336fd4ee64ee1bad1e7d9d4af3a59c8cf32ab110bedd6f97bea50d988c73d3296419d20016ab63478a35a30257aa121c27c076338af67028f3564afcdc3e54d0b7024b4b5161d3362349626bf55f8aac30b995f26a8500c8eea2ec184112700bc5d9190ea1ab1ff87e8e77011cdde522b658fe2149e5647b76068a77737ad61a62131ae33d9ff97c230b98a41ebda963ffb39cffe06c8f56d9f1e101e47949a3ced387e7e93355afdbb4f29c05102f1cbe3ee6f55d039920db7bfaeda7590a7cfadbe30bcfbe69ef63b95683d8db5b0b612fc4da43c343c6222cbb64f01473e9f4fa2daa35a45221eafddb8c11be89639fa84edd0467cc8d7401de87198a56ad64f0486b0105619c6dd1e0a30498cba4326144332ad9fe29561556a420fe46be02c33f598835bab993bca61ea7da10722053250bd3acfcb18ac89beacf6697c5c32d2b61e84a825aaa6bcad3ddbd10d009b0bd8edf0e31d8900a26f249b51cddf1d1a67e4498581c40afa9aa5516fc46c422c015d84ca3039db3dcbb6dc298c81c23b8f885af8649ca8d79b0de8ee62c952549e5ff3f9ad594561603ca4942b97f157f7f675cd905917e83fcc638f3ab84c2346d9bab7d6dd30d7103f8c1955c6e21734a4a7fab9cde7cbaca5fe6fd0208327875b634555b993eee87b9afd41712db0b7402abd8aff6e016b1c1a245a184f1cac596bdbc7ab2bd757b77b30169deba8a82354afa37fefda9749a21cc85c458500d142fec497e15fe002ea79f7f5f9aaa11b32a0bcce5950306ebf2024b4ee9281e7fbeb3bf464e7aca96b5bca8c621df78a8f57e4205f2fb8167b0992ed03ce32949aceab8d82937279061cad7e64ee827f50bb14ed8cb1dba38bb481898636e53082aaee1284f4c4bbeadfb253e2345579750bfe16a9751233e5108afcfbe6486fbe0c6780a37da28506fa4618d228c5548c9af554e9b3e3249cd4470a9863a6b25ece8f1cc3721a423790f651428460d7aedefb289c350b30973dcf070b6dac5a8cfe52e19b0edbb3c141204d715c80a71a536c3d5ccb3293242fb30939d76a844586f9fa2a0d87dc6493d651d87c7eb85af72d990658be1a3f7eb4b048213a5f0c859f77d73c482bde6f6b830861577374d7cadad0708ce278fcccaebd82732333231c3dc2e952fadc580a7be92c9fddac74805e1eacb0915ce756ae072833034cac264b21094a8cca8238516f5ec7d0ff9d9c13cefee68f7801c8b9967849815df6f763b10b7a7c77c013919b3d3a1384cc7ca5e5e8229461a5461ba0a5ebdcf07280602f02accf854e49d2bbd73e6c4d0faf064bed04d1980ecf719df61bcd5e3202d560d13eada456886d7a6afd540b4a8b632999b6dd86860fc8bb2c1eb984c785c46f79dbd09aa636e52aab757cc728441b832dc3c0ad7a6d5c11dfeefbe057cc7d31a67aecbf11bd72b8bff0caab2e634d533fe239cb9bc4930b3bc8e3fd02e032173b51e195ecdea1277f690e1d3429f8826dd89a044335d36ae22cfa368e27ab60d9a7085bcf847baebaea858ca32313245135548bd8c1f0059b3e2ddf72479be9d3f428d1097a693d887b8c78dceac5c571a8655d994c4470c7a643338fb8d12cfc77275665a5a373974d94901602d08a2ec892cf377dd4350094e409379e91853ad17a7b836adca1b4242adf8a9e6efacbed2da1f07a34ac3e333f4c64291c0830297939264008a91ddf653d67c72919d1108da5bba74dea55c1524b0f838eef81b2c2c17e2525d03002f757bae342a663775446f96649a9ce1015ceed2f2f8a388f41322295e92f11f5ecc2b0df93c73e84fc18fa4588efe670e2b120582ffee9790e14295bb4811eece11e1be9431536212e5cbc34e2323935be9198e159a376ea3fd85a32296b2c46bd324e8ede32b9a92a24e20d64e9c4eb169bcdfa5cb036bc6f71770eaa26e00f4b222e974e363045ff1007fafb115465187b72bdcc26d8ed89ada4fc3974d60966a4320dfc81388d0a08aab64b47d532b5bcae882e7b414e38ebbe55c84858d33de9429c4edb041bba1b13f0cf6b0663b5ff75693494c3b701ee5207026f6be879e36d13dc53468a017e67c02b88493ec103a8426728c575cc1ea446b80f231787619ed49a747234c2b0eafe6b0647678ce5257c530494a5bd900d26af3b8e578ed71c0f20f98bf5febb216ad3123285370ab753fbbb3d5d434e721b27b7d5ea1801587321170295b1c0fd6eb4d8759459c1c00db7d073789c2008dc316c56b4ba61eb60d338ef69c8fc2a825d7cc3c21e050770eabdfee9df63dca977470a60407e9ac5890ef74223289ff1194985670a592a7aeb4981123f5cf131121b19eb8b883a81544e21dde96b213fc8b959afa603c0152f36ba581f3be5cd36de72d036757cef36f5555735ee3755a0f41df16e9ecda64df8372273aaa10d7ac877dc89bfda102a84a673e6ef6f05f2cd8a9088eceb6c291e33c5907772a81d94bad2c166cb16587d8ef88506d929f465d1cc88960e6aba425d4df57e049de02a64480bf13f555707806f84fd3a2648b5955733655eadd74aea62f3fe4a8abf6394ba4cace10617b9e9b13d806d617807e6f4ee7cd6ccdb32641f45e9d3396fa560535390e211d5c1abb4e6e11bcbd7a327fac9f8072f31685cc96f4b2e96457301bf9922ceb0907e48f9c155e425f67f819bdaf21d229bc01b91be411775fafab09454e8bf91ff84f0128ac547ade3d200ecabfbbe8b1c279e52622b4d8010b33535dec3f7d89affe487a110e60068680847e66154e3416603ca894992970219fd5c9dc16399684c33b5847dcf3e212ee3c8f563538f8d14d3a28f7ab399197c021ae2c76588234ba6d19936199804095782b141bef25a35fea21650e73886388274c4c7c958a6b9cc54356704fc1c3aed8259ec5fe8d8713bc6f30d1c7def865020eb8f85842e024d830029d6deb140b33dd97cee0d1eb1ba9e18876e52e6c818489df6bab9fed8fe66cbb4a3b8f7c897588839c51008c80e0a419f679bdef10cb284c0bb17484be3fa0a9f9e606f1833f80011acf177cda27f9b82e89995af91931bdfa0c32103e7d70262ca94e05682095f9a92cc5a51d8fc82a21df249677de80fb61f6fb3ed630aac946fbf473a0a62bcbcbeeb7cb856116b5e483fe749327adf815035a3eaf542109c63165c9c2f86fa7f0c4ded8520138f54db62af3c24c29d0b3f1424abef61c0f52c3a5a0c566656b18b91aab2c59e1a5a1e18339f293dce62aee1be665019b542240603ab1bc599cd508564c8a62c2a22b4fefbed8e3780bcc7d6b49da7db8104aed8b60e8ba9bbb327b75d58fd9187300d78359d25c8c4acc98ac307f1e7ffacac0257eb910a1015baedf6bdb43b3b410eface9ef95fd0dff7d7e903f8a243027a8ec14d430c36114e820e2654c185c81a6f821c7d5c6323797476f22d2b77836c69479bf7942c51e48ea3279778ec512d9006e9fea12b0f05dfff480dd5929f93cdbb85f8846f234e12754a5b6d6227e0319d5549c2eeb0db508b013ed8dfe04880f18637a822d8fd4b2c78adb3ebfbd82f7d22d4593a4ba21432a2e86a1c4792db96fbdf05c23ac7ba8b2d18b3e513285eac395386b04caa6b96ad3f3f67406fbf1bf6e9d72cf973cee777911e9769e9fb2f13761ef43dc55209c145ad7c686e44f4b4d3fcc42af56247d8dbcb269638882c035f1eeca1be91bc7dbd222a8d848c976fd6378ebe1351ea51a0ce1e24a8cfa8e4b15f368e1a62042378268b6d82e3a2dea2c1192d2df4e7c54f66fc1471b79f2a4b2db6c077d1dc2f28b106d9ec38e1a3582357574fd6629da9a8b9aac96f26b2fae714a7115a5d9a02ab033d2032ebff8a37979524edaa8dabde89e09e45fca2ce261a9e5b147ad4758fc8e2b51246766f2a1a587ee548d12a6b5b9b64bb4f6ba50015da95886d80219092900eade56a3155f5b2f355ff8a3bc5c207becb43a18817527e3f86c80d303cc03a3dce8bc599cb20d261324dbddd98c50e38774f17ffea162bfe1c6c277574a38c708a40f9840fe30e11b85aa13b02d9c072d5ab4aecb4330207cf02fa90f47ad89d50ddbb34d1aefba076536f2129750a25e1014e20132251c429ce17bb253929c7b8e3d72d5a589ad8b5bcb3c53f59a4f84d34d7dc7fec66bf47eb44cbecd7caece57de01f2f8014f8ba396f19dda9c7f744a4fb75ee06712a69c94628ca725fde3881f3d3aa736626b0d38bc3555233e1a61dea7ddd582b62370dacb81a320d2bb850403564031a6e763f76bbd17ec8748cc76bf0d44947c0b63a7ef3407eced5ceb51dcf4b49c9c7f36c502569b2b78511dd51ccf3b0f7e39a6a261685d8c075cad4f2412d0c16f34524915d70ae1caaabd72b1eceee28988f99e6a0ddf8d516d3ceee0660b1805230ef39e833599a52c285dce21fa1462a740a623abc0139101b442f3fb4ddcc4db734811e010624180b2b2c89e4e6c796662c022232d854dd81e8918f18716f3b09858962fd1d58816890bb6fc7b4eac70757d8b8670be7f5bc25eb7b4d435d2666aed9a56a6906c33855795526eff35af29a8ed2de1a4d9d41d2681c9b3b73d94e4cc77193c3972913924cb921cb96a20be925eb4e1b1c7093beb2f2550feef79fed4094301a03badba833e72a2ebf67f54dec2f99f8464b2e44f797f345aecb80f5ea41dbd259e2bb692200be1649306d282cd057bd317e825a68d70e432ede71be4a9eed916523799627fc979bfb6e0ad7be067541f9c8558a01e209ab6634364c05719c0657d99998a81488c2eddaf693a90997ab7722f254eb245eda86c530d7d3b0a7838a30fc9958b5e1cf46bff36c8cf57a724282bdce29d69db34ce00cb57e79f30113da68d8e418372f8c18b3a00fe7d72b05fd2602ac32782d090eccf300bbe1c44322b1b386e556ca8045842f63014e709c4d78ba244e8a56d561dd4c0f8f6c12fe2ad8dd4a62fb756439d3b5daedcc63fb80b6d391a24213b0082abee69b07299b8159d8f5299228891130180a6bebca90d79321bfe6bb9b5ed4d26222814a6403ac95fc42127cb8fd1b939d38697200f12d0514c206942f292d213f772747c291a95945aa06f0f35226f8cba05e818e336328715667b227f92c18428505c7e5356314d58ebfef94d13cc81d478ecc12d0f12b43e189b8eb017ecffd0a2de0fbc70deee18269ad2c7d7e893e5f8e85f7abbbe64dadc0321fe19605c5eb6c83a42293418cf9a20e814d8ce57ca0808e465c5fa0cfa2725e7ded861617194e3979e0e4d8a0389ca7b12873b1fd41eccb6022614606555ab8dee7367734d5746cff0adaf6231ca9b428309c97a2970185e8fa4a64747ecfb181b9310d5b6060382a9fd9ec4f287e9dc06560e02808f840190bb8ab51aa4ec4510778ee64f04ad4fd944332436c4ce88525642b323399f636af1671b10fe2126fa2078aea1f766dbcb60e4666608b717be8ea25d85643953776e229fdf00b9a2476a25dfef0c4a840dc920e888545df33f6ddd7f50a49cb4e44003b55c0a39c5d7ad9ff0656cafd430ebb44740d69edef7ca8482ae58af8e9a30fd09a435c03b02e0524760731d6244010760f179c27f737db5a00af4d0ac20be73e9aad8be8628a0a104e39e4de552b948d3b3f013dc825693ae82468f00213e0c706f7f5810f6c81fa1134b484ed260ce956b11828cb7ecd9b5bb83aec1488b0e989b27ec793513e57632ff0a332d244250d4b1b48ab789bc33598248f899dfd089549d0240f0203cc990e7ee491edcab91c8bcf97974c61b5808fe4ab2773d127f1e78a007d94e896a882d3cf7ee67c9612f03d3b62750864ea6611c92501375c749d05252cb189bc4ee3126e5bf23695ea1f235db74e02320068ece2cc0c36867d3a5b9a29d11ec66fe82fcd70c41152af9b1e29ccaa65a1a4bd61c84738d1f0a063dfed882874fc2b0f271b338b48cb00f0246279173f15506d1a4d3d184a7bd1f84da0a89512e83aefdd0b44f5576be0cd4b3d7992028ebf3ee172af91d1b40557aaeb3cbcf04cd3729b2c9d92e36890e51a6460e06b88b0647c1743b6f1f73e27548322c128d85f44c67697669c0b4dc0de585e6dddfff0500080c2fe0c85668c3580220619a0f4bedfce990ea687c33ffb8ddc9e89ab7e12adb1a5892372a0622dc45715b7e04683c47d0ef610a2eb2839dc672f6e5d95466d8ae928b9057a9bb73e43ec009127dbe69b55f30ee6b7de4f59edef0980b38afd8dca9dd6bbbb392db8936f842ea67ff094dde59961839ec0dc46a0050b203447936eef9e44dd81553f6f64089d3a4b4e3174a6551e2d16eeff6f9b705bcb34e0d34f12da0788eed6fc5d465a7533f771fc027f635aa6476a978591889772b76becb238c06ef94b871f70bb7d6dd664e2284f96186df52b752e5617cb9b7c12d681cdf2dd0742ee1398e2e1d07330f76b2f725e9f75d5fec61523e476bd1a5298c3628fe018f0af6027d225c22b73d430f56ee5c8e6555533de11d9b38e8ab48f0b09768dbb4de3f39d6e4b58278b1069309dc99d1a1c5888b22215d2359848bbc5215a89f79293085bdd2f9f5011bdfaddbeb5d2398d0729b2f2f580a57d5d2dde91f3904c13d0baa8a0a30701ce79a0de9b1ce6f3202106a68bd15f06bb915004945c96c519799de563cb854bfa2c974def5bfdb9a9e60880ca1158972f9843a64897d1485fd116466ccfb4898218a971265a21006c6367a7253121e752cea7d248a975041ab0376df6a3492df93e277812d07743ae50754e88e56ab30d6da63931702107099b2ed7ae9609db99999a7f56aeaafcae844524ba3d68437bdc06d0f7ed178736da1a80d05cbacce67a9144e2c9fe5b542323fe9e5d277e313e55f35e94a80072d4af16648d0254697bcc3518a30c958cc67189b9878c79fca706ac7a9cb2c9a418aaeb50e71286a3b4954ec5c34d3bc0c27bf051c5a39917b8308bd14d6ffcf48590672884ecc733797a0f391447ea2409f011ad71470860968ee34afa97ee8cd4f08f4b466621dde8be01b7afd97a87298c7e004266101d6b569ad20230592924bbbe2d3043a63dd1d5ac0ff25a422cf87a1c1527b9b8b07c6ae9d92eef352a181fc67d1f130177f049d185825ff6e5d2fe03093990bcf09eecb1acd416bddd11a6094412a40b65a88c2d5d8972beaee10511ea2fa4fe633e8e7ae4915729d3b04e7520d0e795a474289dbf717309dfbcb1bf493aa43815069bff8cd3aa379d2d5e5e4dedddb3d14c046b2a273f4e8e2805ee86df1f5a474eef6e6e1c0b9ca3923140a478a66d3986bc8677efd86b37e35dd79e7e907871dcc471409b87d416560d8a8703d5612defdc419358acdfffe520715053397a637db40b98eb67493318638905b4e2f69ecb175ac216cc708e2ddf000717f29190b2a667fd4cda03a268495da8b0bce9c6b3c46c6541b2ed87340824b64921b3ec4ab798fe32bb2b3a23f56c9a2a44591e1c775e16b38a2fd4c561f32473b2f6a76b2058df35e772d8b84c86cc2b20d3423db2e1f98f7030223812f31a992626f4521cf4dca3063bb68a7337655da7ecca8f9f04e74bb2b56e9f6afd8e5543c02f4a5d1939c23b4242ba00cbb052192ba76134dfab2215592ee5fe47b3dfe0a6df94387d4f5f7554480b05bbc77c4ad3ba794700a98cf6d892ac870ca2c81f2c4ae5233a2662ec9b1de422cb4ad9d03d331a9d6059d33563256a36711b901059b46cdd85798a3ddd9e4730dc93edef2b3653b8cb238d0e07ed5576ad89ff8744fc69cb004e41743c9bcbe07080a9effa77f90f5abbd58efcaa4b5148fc53e4d8c653a6a50d68eca318bb7721cc570e9a32b27cb3dc0a2e03e774b6304bcd10f5f8c656082b1d42531a984f7e67116fb59b3c1137f1d3d0bd27c340cdfb651be80230234d54d640b6b6c0e600d0628463e2fb59a9253e590a727e35624b1be8156e0779c1f000f99c56a6073c1aa7f2a7adbbec311390736bb9f67636d2652ecf9fa0fcd8ac8b5c6029419ae517231322c8f0dadc1ab6402953184c0a4a2aff0f38aff542e31e43dcf3f449e482610fa9c580f8c78c7ba40a5fa73d62261dba6798c3578e97706cb6ddcc5dd6785ecc466f0565e81d17d2b3f0ba4a8be0d8dde4fffd9ca9e553a3120e95e2eabd223e90a1b624ede498aa35908ada0970c0eabf286805ebf0812d4c3f4f1ae0408df0cbcf8f5e8967afca970db5b2368b1fbaa9ab6931b9e544c228505b15c8ef3ac8bd5777868ff086dd7c1f4e9f0654e500b426527d3204e40eba026addb7bfd2e88860831bc7c10c4e626d34cf657ed1834e400f9bcd81f69b1611c2caf62550b86dcb8745a9e5a5b696f5a477011032e07baa39768f560d36da2dc698fe214b60551b9b3c7fecebf16217b686a99019b3b420d2430ad0127292970c674fd838dd91b47e6b4df69de64926a9286955f7416ca5e94a76c14c3cf9731be453bbd0adcf5280b28c809b2d0013f3a2f75fd6665aca01f7437754e9e7fd375acba32a525e3aacde6babf07b429cea76fb004216c40d0aa9682b06c7f21842600e3494ec5a328a56cbb56e7a9ecf8356d6840a74a2d4cc1753ef77b42cac882cfe69e0a581a5036a6a6e089c743287dbc69381f4cfed8dd4d59c602133b7ef94afcebeb6f126c6298e119d4b943b064e45559971291a7925ff48845ce17319c6f0c78b92bc401658933508ffece3841673a3889d7a2683561af28936df65bf356c0a3725095a468119a7f359866843bbfb35ad8e581bc49ec7642f10e920f47c74b18e55741f52fbd3afd35f1606f4531e14e49eb6a634c400d917de81e6049446aca59a675f5ca7d6a55d40b0d8cc540b3a018998f7d0afc7de5346b57bf3112c5ba31af671998bab24fd09fa4109463e2720777c53ef2d5f60626592ae00c0927ac6cc7788128f23faa0e3addb3c227f7ef20c5b4d988b2bb257b844e1328ed7aeba21abcf5bf4001ebdee1f8563bc98d638cb406d60c36d7f1671d558a6c4098effe76ab042be4020d8659228b2de9e08e8ba4fa92236182b70cc036cec75faa23aae96962222ad6c7906e032ca17c24010940b69ba71127b3898122b71b0a1cf0d61ef7f5f6f7780980b055b0b56366992d716827137c1d9c4acce3defd2339d0d8d0df600b1feb146cc00914ed58f54a1cc01b4a8e768b643e687a7c9854b47672cc99c69e91457707b96a2acd213f573b4036180b28f2fd2e7534bffb34b818d73ac1d2c0dea9ca2da5af1a5f27b62642e2918ca1ade26e40b3dc75b50f0fa9c64cae103e985ac08f223533705268f253273aa546fe48a4567f0122d3e2cce23da929016d9cabd49d8b1507748e22b76181a3253cfaf54c3c1be39082bf484e20814427722d67c9494c887d40382b43034fa3fcd9b4b7acc27308e9bc7fb020b1f41dd5fd6e7228285d096a1554c3a67e65bd061572437bf2df1c1dc4f4fff427c977f5c82c212673a386db4bd358abfd11dcbf83c16f1f8e5b494bb8326ffc7025eb1df10af53bd69d740e15bcc307da32ebf4be4c876e793af03907c0272784f03066a5f0ef399be73c96de901c99ed7d08627c47e32ae764d2a1d5d078a4e7871a9fea8cc177f1a32702e4d1300a2dc99650dd95f20470c947ae7596dc9c594a31dda28f63649f8b8924f35a27c1d063b1a502d606b3aa6f4956954d831a80a34243f7cb4b8224876b8651ec91022077f4c04fd87eddcfddc08aaf7e4adec2130fb76c878877e150b9de601f2744933177820bcaa1859985733087d36b85e24677ca9bbf731f13f29451bfe70ffcb417a79ad77fe83287645d62892a3b78c22d2fb3b8099a3f50c093304b192c8b09a6000dca23da5fbc669dc5c58c919b33ebda2ce603500178de80816160bffaa0912b722af35eea00236b8b21a4cdf63c6450785344ea8019684706231872b2f3c88ffb1f8077e055385219ee4286a67e0b061e988f3671ad7eb767672459c97f7779cf7782905c957521c2a04dfd7a06d21c21fd64cc2600dd44d358c59dd057b00062374a4a517d04da944abaac0c2d5b6b5d94dc70f9f34f5cbc8ff9acfab6335a065021cf91e9bb41e8139c3e6c889cc63db17a17c7dfff566d8e717dd7aaaf647939b0c7327bea28844b831e551df3a4af133fff6f45a9fb1f2450cce1e9c38252a7a156eac0b44622f8cc6ef27cfb248152d6c5f870ecca06694ae45272f5d019ccf20ad03a8d97d491fe1df4aebe84cd04f302ccd09c78d045ae0d210f21df0d79115f32e8d6c8ab99ce6cc27d70da9ced015a6febe1a19a58064df1f39588218ec4c2821571dde535cf8e91e2c1e89f23e825da2efa854239494f8751d99987ed251bc9aa70a3c49ffce2e3ff140c65152a94484b2253ab7e4dcb7bb14852e3c7f89df761f4954feffda15bbd79d4b04e641147fd687c67191ac673c358a6af07b5591adb0a8588b0fc5774c8ce1fa26f16bb1b697f79fea91a505c5a78f3fcc307b3cd39145287bbd3b568fdceb841e0d1e6bb20204813344b060a9602ca14a890b580f2e1fc7f831550a9db6d9d4bd09c1380eda4ca4a6cadb0dc4d9bcb92c972a2c4a4838ae70a217b801ce9e824ed54372e8b0a57ef9bbb22e602f535107d76d2dacea26f824261e8e787747f99478d5f800f146b9d9f68b69b0c1e34b3bc26354dec25058db48c874a537b53ec145392f6a9fffbda11a671d0c7184591a291be2f7554aef3f5dfe368b4b50453d3e01361a7ea0e9d324aa309797ee1d2f477d2b5fd6930953406457abba0d803d829fade174e62bd3ebb77a857be211977a072abd06dbc88b9581574153d57e79a07c59d7423e037d391744380de733cf48190fdae639009b059439add6a82d6eb18b5e9738769f64d71f6e07798b641a751a20398d9e8323449910f30e94d150a7e7eb4c29049f87bb010bdeb58c9c40079dc75cccc6cc1b9269ef965839f7d91af862a5656e8e5f7231bcfa249099f6bca4ee1371d0a7f28f65fbb9ba42b3161ea81317916d41c659602e46e95d1b3278e34c40f1e2ed57e8fae530c89ca0658b873d99d1655c87e04a4935e954195de7b8fc49a27caca9f68279b9ed95bf48e4674a08f4477c029eece01a390fa17c7b17bbadde5028aa785383464b48d47aa47c423eede4f2cfc6d8bef1626ae1952b2a0d842d3ab5992524cb81f03bb265b616243e4938e7ba9d214d7255fcb460a209f573a3fffd6e7e76fd9e580afd7174f2e44e4e0d5831193fa35b3f6cc7ffe0c71f8e235ed902b61cac1fe5a3d66f92c975e5f7d6c7e1a047d9cab22f9852a90522626ce87e84311b4139cc3865a9ec7147bad0fe43798d37a82dc897651cbb70f2ce41646c7f3acd08c52fbcb6bd755f506f552ee410281a83728413189b7abc1b8840535b11c7b214926efb1ab5b71571415b75c436f9e4f1f4d1250f948dd358631cc0766236910778ad5f73b34a0ddf70a82ef5f8f3382ed976888ade1a462aff974beb0fac7612316531864c59991c6f0b1079083b82b350837a4c94f8f2f097b62241fda9154f94499dbb263fc60f1795b3fbfb858a965805e0250b0dca1157e822222d76d62df0b8f62ed4be53aed12c5c6f603a42007b0a7bddf58a8b62625da2dd1a197f3a80cbf46aac59cc3b548deba6e894c92ec10f465eb3b841b5f471fbff01334df21dd28d9c85fe57471baf6dfaa255894a300dcccc6b00678916bac408fff6664e9ef8b63924bc03ad9bebd68a2855c9d3686ae79bddf69630f53601aeea9c9adac565f6183ced19e5ca9d172bf5c57858eb865a8b6b769b9cc846b8879ba5a593789fc3e81f0185dbbc614bdb1ce19ed4fba97e974f6ef26164a5239fd58cb56e1521fd35a309f4595abef6ccd4dc450660f25089d5e70cb504ed4cb00143c224bcb6cd7ae8933a56b4f693501969c85b90ea4e5de0e4e7dbd327f4a63b30a1ed8451ffde9e464112bf643d5a1145b3c5d1d6f62529bc9cf70b0eea08dc4fd53ac0017f4d411b46101ed58023360871b3592d3981c39fd80f974c518becf6729bd226408631bca6614c104dec436e063370a6ef546782891fc22faba34518a07fe789085fa3197d1d2a2d6740660c7e5befa19d1f0b819edf160a1948fb044747a42a86a00f159cb55be4cc46c2f0718e7fe5843aee0618150e051a11dab7a9734b2b46bb3bb808a7a02e50a6d98bf3ac3b8af638d275904fb8a8bae710291ae8762cd82595c18ec83fdddf4954974c3c1a9b6522abf915b3c52486050365eebb1eedd9ad6fec60f4183045eb557e48e295f22db608834de1fe43ce63ce74ac538cc8bbddddd337b27f8d733d9c0eefa3355ad5c2da5d3cc8877dceafe6324ddd72840237b75e447dd2611ee8d82fa508ed045ee9ccc2baef213a97edda12a1615ff25fb41f7ca517e52b67ff8899be98b25b67713045a0d3a2529c3de4c5006b835eb7520c1fd5c52c49c9d4f04e7dd2d781e627027a3d7c4dc91fdf181c8c14db79b2ab04afb7cf809fee0d50cb642a0c3763871b78d1feb64e5017a092f301726cb3ad8455cf5942bac8506728d4c76077278afd80267153e0d6c0c2ac86603509aede01f674a819bdfc9a4e0425eb5e3b2b4bdffb5a0ed6a216f7508cd03df9aaa99919d613da8e403711d4eb28e4ef982e1b6789b9f5c3e57070d229c6119f1167e7225f548fab321b6fde3d687d4f8c06a7ef68cc7b44c988d9a598ebb4ff2ae56bb47dfc8f8272f61b48fa5fbea21532e642f150f2cd7140c49d92f28da1f1e24b39c530b6ecd4bb7a3c92a29fb1a0dcc169acd21c815a1bfa654795e933a514af6e0b267805dd44fde46be1a8c0d95c00afe7da877cadf8c0ca77a2e418f985fcc13d8c519b1e7c394a34642da24d1ff562a12097a5c98c8e4ba65dbe4187ca5c5284b725a68106b2104ff25ca5b367016e442239398b81a7facb0863d5829e2c89341bbc1c7adf5b9779d3cd538f54705ecc6fd7bd4f16679a79b6717e2c1b0b7650eb52716599cc271d44ed800ae1b0f4ba031e9c8d9a38eac3cf02bcbb31a3a78ddda8dcb036af9768a67265b9aa925bdf0555f943931ab50a093c5a846a7d8a8301ef8b3ba3c0ae7b6f1102780043fc0f95449c3c0a4cf869c242db0962c677d72cff978eb30a9885b3988ea0ced1117054a5302badb74618e8391e0d85e7a78ea606bd61859932d6ed56dea554419f326306e9d9ca9b86878635c32192eb204bd571891778d310ab2f719f4d2c4434d1c932ced00d0211b7b230133051cd4c600655fd71b234cc5bca83839cc548dbf63046f041090952e5cecd4feeb634fdf464002a0fc46e153f896f54558b0b68745598d2e2be821da09eead13e2038972044af0c46dbca0d5cec84ae58c4b57e0f4f09e0044c0fb3ba8ac79df3d24d909b5eafd30250f39de82b74390040165e873111a44983eb3bb97f21769622e5811177b96c05b6d07d851dd26f475e03c77488131fc975d7552dada03f91d328f0af6cc0f72bf1c36963667a24a577f6ebc906554f5a658c2a084772ad198de84588854c72fed05845e0420d40a47a34757d28eece7d8738be9a12e682950329bd50dd30bd20ac1332bc9bd0e30ef334015ca5489e5a5dcd975bc54c8afc1907635e62c226ae899fff8a192997bb830fcef7c1d223d807554911f1e136337fc2b0398b76f1e78512f69c56ede37819b1392ce37c1340b5bd9b47c6d950d46640709a47423bde44604497345c30373ebc89af8483afec4046cf57d6d0ee439895c2a74914a3f393a343a763577ba3778e91ccfe0d04c71944e423ced5526da8a0ad08e9320308f5eeb91ebadb991d109d0ea2995314a74835d0ac020001b45aad0e614c2f2bb8cbbf4b95faeae6a6027f81560234c5dcb94821acd31455469376f5cf55c5b70e4442af04af6003e92b4261396972973a0710ecf95a65241278f1da1f205ce58e9bae247b7cc7880c50df5d0927c15379b16cb9f91dcd2fa19022095d1fac6b63dba29e93a512195e29e667bcdd02b9b6a3000f556596d2ce8950f5609068c2b1891578cffbb301e8e5bd95004ab402e2110cb07a3d3225f0f2922a051ca803beb2f722e35650e71c637b83d19410d94bfdb2a856b799dd015bfc1ba41faec8eaf233ef3a46bbeb69a0311c37f117d621bfac10664dadfc778b2f78a1f72a17c85cb2d31f5cc793ed745f060c1fa53bf6233db1f51e2d9f651c42b6ca20d395e60b1e07536ee6c9f0a27f7f2d4a5b0d5fc8281b3f43a7f4e3df2845a1be1efaad680b50b34256399313fa3ff3d4ddc167c0239e10cac56622307ed2c2a4cf7e6baa24ca04601df0aa7fa749c41b599cc8088661d98069e1be7421c67bd2b4ae71ce3330f035bd5aea99f125880324549b3ae0d39246f1e684112f948ae04ee90f800961f2b4c05851e5b6b934bc6110dc0724bd09e1588bd6a918f725fb51bbfb4b45d0980f3ba6be8d34696fe12d4db865b8a646c51794115b00dec049e894a7ea6c04f59ba786ce1d9d685289de24813e923d91dc24e0d90b2ed7d6fcd27fe2f542e487b9e5f3d3c467bb404acbc86f126163cbd804ac5f4e12a60ac9b3a304032295eaad198cb51f6a249ec56e186e98394fb96cec4372df473a9543a1892562c7d174bee5264759966c62367019854c7deca0e1af6519eb575a90f57c32696a6b4468ae90fabe163c3741b740be099671630a37b301f0170f95b7fbb8f712851369fcb87a1191cf1324262543a963c9928da9b6b18f2c75eaaf5aa2dba9da7d816c2666d5164637341406493bcb7b45712c9967e5db5efb1e40be3a473791b0709e67d52ae365e1edef0a126af847f84c7ec8fa1ee30cd626d13b503dfae13c98ed6441dbbcfb669cb2cb94d79e91064984105f9170a74fdd0a169a659ddd54a7827303ec12221ed56eae59dd6dbbc89b618c598e6c8403d579c17f81ac8123d7d27358ee8f3ece88948b48bc11e75b9705d1a6ccd8fcbac33ea24f6cbadd2285de64c77da9683c12897a23e013bab9bc119460aa2543b442a352dc6f11e73f317324925673360e203561f7101e2b9c1df70b13d9a589fb7976443ef48551eb964da171d93272e16adfef50c23a840f317b62c758bfc1a9d7ec3e907d8f392a0d1abf628e749e5e08287cf1f486ac199d4f2b0598a26102a7e1f3c5772e9ecae67cd3eeef0bf965dc512f6eb5305308bf65f6faaf718ffac1bf3fbfd48a03fcdf099e5a0dc550a5d5d477102a95a3758545677527baa8f86bf5395c4b54dc2026496695ebd5d7562312dd027c6814f7de95e91d303ab540ee9e443f13184ca7493d2a3d9718c60e09d9216487f52c740d53591553c1e5391aaa7a07f30b0bd1a70bbde27283805ceea3369f811faa8738a153e1484fbe26384ce668f22e64f90b02fca36245c1631dc22a9ca22eb5df71d3f8551da8137d7092c146ff2601a9caf54c4962e3a1c7db6107af552f2127275b625846ba70caaeca156f9bc19d96a0932978a4ba8f3383dc843827793fb632b4ae33dde4c05ba42aaafbd02dbc6df34fa7c43e1b0604027b5b38a6196a3bfbdf350b1e0b3a4563987e86a8961c54d66ac5989d4741b69b493e0d2f34dd97834792e6732e00a6faf383d945537298a76e42bc94c2104a2c350c38ce25ce5757a2061afe511c65895eea326825334f106413694a030d3f8540d4396596169d1ea287fb2ca6e551ee1488c05befb12576e1975db9acd3247795d2ffc152841ec428603eb89eca7a12efd6bee63c0134e681c4c458c7792f8534d37499e072f81f28fce3295364722cd44212f43b0939b7630cc1c383bedc52586d7226a4b932f48980db5757b269eda3dfb402cbd53fcd2f36a2ad6bf6a198381cb90099a03e7087776e464adbb9d9be69497b5be701ca2a897c1b06079a5f4770280ac40b6de8e6dc3e390e6ff1b7684b4f7ceed751be36891a36740e16a147ceee13333b0774bb858905f31003e0aec7ce73161f3d23b4cad56d430b3d691441d3335257805e32e5ff12229ecf309bc2868041e9d740558bf90bd3ee54130913e439bb72c300bff5c020af1e7233684281a19d66c88fd53f93f4fbf0c0c57ef59a3c5575053cfb44303d9a7f84b9368620959ee5dfb1670f13ef8da647e5e84bb5f9823554fb53858d26fa5f6b1fe537b7b3b14606c0696acbdb1ebc775ba60ef97699d7638cc0b7cbf192489dc7b97b258e2a6dfb1c3657f27970a47d6dc9839b64e268016fac0beefd1a870a919b0c3e076135e4a33f121a061ce8b645f9aed29cf47b71c36501c786b02d62ccb55bd5b0cc0c75134837f981e11d8e9917f0f762b8783fbcb008f4b86dbe6e9aa7d6447cad87ec4f0b23fb98731224036130abde11505ebeb098caf527d677454cf03eaece40300853eec265f7c12ca6b52b2fd129546fc4541df86ab5d1e132ae71ccd7e674dde30ee70ad8375de81e369e7c4fddc0c7d700966a3bb040732e6f0dfa9e5134d8284c5d743b3406715de69bb04295647e10b105826d7093ae98d4bd5b9ffe7cfdc75eecbb918fab1aa7d2c4efaeff089dafd148229c1608e8f8d7459aa41e8bbf8e59d7e4792ed0a4aff370904004ef56be614b09c5118142f808ba60cf6166c9cbaab37854810ecd96597e520b2379a83c2a82af0b5b04ff0a02fa83980a920b89c95f1fbe0a6e2af451c843c2eb14a24edb5ddc2f7360a1b22c0ac2ede95aa542cdeee245d87a50ccaeede4109448f713494c27152dc5edd7e17d5cd8c0d5a0aeafe74fd7d542fe38eba6971311f89e0cdbebaca59af5129efccc679630040d51111575d772b78f1518384ee62d55112b97997724de8db4be4240c774e2bf0244b0c97ace5475afe16fdd268376036e5661b113c331e7d0b89970d7d60632029bb7151139fde18697777c6117a14a137a5c390ba03348ef8a8f591f69543cf25d7e126477e266be0b4a66b06a9e3002a2a92ca5a1bb88dfd5ac149d5671d1c1eaba9af5c9360f210d1f9cbb8f37c3737b8ecc5bbaf00e8e2f00ce00814f10cba5a6e8925a4f56b52f1ca3c5961220504ebb2d59c1be5fe9db233714fe54c5e98b0420c491f073e96a728d3d828a6ed354a94b225556eb919566faf62eae1c8fdc1a6599c9fffc7296efaccbfdbedfc0de3168dfaff8b99d02c3334811f6f800a0ed3739faa022fcb5c34ca844b0953672a7f677041efc23da31ed576b4f892df12f05c0ee941670e72c18e5d6452b03dabe5b9fde441143b7f67e6d399179a55cd9fe6af771e7590ece952c355f9f5618c6e2ed6bce3dd988ac392b67dc3b4af2f2634c9a5c3702261864cbd9cc33b8ed4a4ba0b407662460aaa8a266bf3a5cf274b973891d9966209935e8483ec56c7386843f5d1b6f2dcb44e3db88e92f00e0a3145a0c04d5cda218e7f5e9ee2cbe118a5014b13e5ef12fcbb8b45ac60e536d3672807a5e8907b29407ce5aef934b1f567d0ac0df08fc361fa54a2015c002fb82c1ae679e926a60246f559fb0cc84bd4d28adeae8335f859330171fa4332b82a726d617155c94073b627f9a79229ce56f0444c82ea55ecd5da304112dd2685aca666143c28e5bba70d90ee9e41d133a84dc852dd6b956596638fe0610328f8f08e8098c6c35bbed523f9a92ce84855a26a501e02bae86aca69c3d1b8c93b28f52af72c89e2280dfa5a61e1b0c08dcaa237f9efb770e99af50e3a9e6e44d681d9a860ff0e4374f5fa77428dea0f74ab9177bff09d71a410044f3c790a40ef64946235873ea9f616b66d2f28f990bf2ea4b633bf8a944bec92879fab5b2bbb56ced4d5240ee2661119a28767259c17d3b4962aa5a1341ac8b0dd90667d8b652c7e7c207417cb8e6b9b21ae38d2c9599eb1d5613e3051fddd6b24a9192a17f84fa1c42c98976d97e0fc971561ce67313ff3dc446f98cabdc8a365c009d15d0550e863d9c0f9692a3646d5954efcc993062279d0840ea75861fe6873c2bb7be38e630de28f42e3e12779203951c82cb44c69ac450d3770911dd8639728e836751bcc8ff508e2f03eed07e83f92f4f9adac7828b3e7204c10bd30f36a939f23d4930d9c1769738425b02726b380a2a7bca6897db0fbbc8c06dd30eade7c1c7f38d867a833156016bf245999a41e4dde5cbc80733d4bb13ca893fddc4b82b9b955eb44bd4459861b8fe85c76ebc634f01895411fe14c9637170237e2e881acc133d3d1baa1718225501a8ba9b5586e1a15d6430e1e3b36221520d787dd4c5f56b90c073ec1e4b55ab597ce8b11db6d159cceb162bd7cb123fc12ef44f5dda31412b1016c0c0c0dd9c9760d1842d1c63226db50e08aae0c65451014e575865e48e750c86a9d50110c5ad5420025400bd00ef7dc85cf6e2b588589e0cf34ac9d28b0dbfdffc3887736d29a98701a8e5c935be780ab1a0c2a4fb9956b08deaafa42d8d3fdee1674b388c945cf2eebfb65e814a1e14ff721091f0ab81e1312a3a68c0894fd1c54b8f771450b739ebe79327bcf054809a7cffe2d33f8039e0583cc0b555015b31900b7cb02be280e7dfee685b08df2218cf452b7220aceeb5b30f0702016efdb65f13057cd9d28446ad036eeba37cacbd73f5d5e4875a9ec34867a5572f08f3931d1b681de460f11e332e03f98f33df917444dbe5abf6010aba2266fc1ea39b0174fa2d2929449e2b8bbe157dba03229307749b6efcc9c2cdb9a558fcd700ad84166f0cc1b490741f92b9d7eb68f8f92d4cf16f8f31c189bdef2d465ec3c09d1a522ceb8dbfd0819cf756fc6d98cc8e810424196cc8dd0b97a1d6eacd7fbcc52a76cdfc7884c6cdec0ca79702915fa327f515b8c4c2aa00aedb98b4d140bf3aa348cb1f052860c8a406a829b2230e409eb882a6274ac747690f717a9e335fd26ebb63f68560a8d8e99cbfeba3cfecd2770273eb13b01f0fce126a6c224050e922f79420cb4a3fd3d69c77cc34b0e484f0389a120ec6c169230035752bb6fd61800c19ca7ca65f0689d8f2890c69ae45f85ea57e1555233548d790bd50087f6433540021e3b3b44d6ef3f96965d88d2701e4c5535e1806387650efdca67ee410d42e0e9ac4a0e8300d151d0ac796088927f481631e0878d39b24bbaf2e362ddb24a73a656e19570c05192ececc36b59cf1a6af51cc893869fc42c2bd31445c2032d45dbff8de66c0f7e0095d8e5c48705ee97dfe29d2880445d41d033feb839a61e165c31ff746628f2c5a41ba0b85b0db16f3eea0332b7d55a193779d8e86b9a92e6b742d6695ba6d54d475fbba53aea1f98a179e52f3502a703a01931defee103a733a252054c55d18b7679eb955cb30ca501ebd0f312f1955fc9578c7e0e2d6c0789244ed873b3ee8b69f2c18648bab355db2b1f2594eeefedce8843e02fcf0b6ee7fa9d3520c34311ebd2e23f920964c225aa7e0f93aae56fabf11d5d64a38ad936db93ba5014806dbc08c4971c540200d15ab31a6d8406ad395bc99800e7ea810918b34467c7f45c3376678019914ca53d09ad011b8f33e879bc25e2bb273559d992e3b30d9827bca213f8a11f77669ef8e5120b6c8121951fb1ea140540453a20097ecfd8c6572b8fa10be9a5adc5a054df3c06452aa4f9554fe378d25eeee55f73ddd7165d08c5fdee89940f7e1fa4e6210bd7e84ec8af9efd331c22a2e19b9c7c55c3738de8ea637a43ff8474c9fd5f724a74b4f4d72866cbbc1dd12336aa15e6a171313502db3b9346521305833436c631ec9806fcf9466011039c30c6bf2960bff1a7c1b3ae6e6e18247f0afdca422216992123e47b815366f1aa59f24eb3db7da54900541ab9d13b6b3c56be0ca2a7ac71c8845fdd46aef24e4b87dd4a5bf404b255cced8b5b4795ba43347e2c939a8acd9e574acb34cf86b10e87e4b1e251587a00c56105448fe27ff9deff7fc4a1fb697e77f4f47058251e9055fbe146d44fac13c429f9ceb44bb8cd6a44fab3878fbdc8a24ccfb27cafe321d12c92632438c400d88cb1244e062054a755fabf3ecd0159395c6ba8e00820884174d482870bd823cc48b3e75c0521ffb4ad06325f28e74978bc4a6398029b9c802322d6ae8e6a583f73a04309ce06ebba478554d1be41dc935c1d2ad20f96165cbc1dbf9f9449ed6904fe7b35be4f8119fdb592aada9bf2584b7385ed6d9808a791db837109d38f792d1586536c6708c168d0f3930f35738bfc0de36b2a1c320f04f8bcbc5a6986e8a924ab1534466e4bd49ef65b8a6365914aed8b544fb52f814a967ad03fcc656065a73e0c5a4081f01cc905fae3588401636f7e3870b3bdb3c90e1df6bf8e25c0b09cacd351abc279ef779efabc7845f4a439d9c89f2148f415efb853b27db1646c8e0d167ef4ff2a60360c5234ba8cc52293b80eb719f3a8a0160d8895a188127a61702c4ca07686aabe1412ff32aa8a0c73e104822d0f01375a98b6a72e122365abab7386a3515bc262dfbf6f31c3e90412223acf75a93782a37b10bdac91126b3de2d4f8cb01142ffe4bf2ce72b8800b0a1dd46f1e1bc998895944be78287998231dc870212212bc1f2986e8806a52fe8bfcb23feeeba4af6dd5c8616dd913d72dc49a160320e03fc7e367d082d5536f94a4236ee148dbce0ea6aaef7ff4ff785fc0255190668fb17c14180ed75bee0689f9e1fc84ba42dcbbb4d9043abc92ac6160786fa6ecb4b080c7bcc8060550ed1028418cfc260c07858e9abdd27241601c6a2e2110e53534be68048dc82f2b732fa570675ee80536e7a740442a382688b67d18368ceeee210a344b404c23c0e98409483a76f78f7bc0b3e0022e3da068de8b87d93badf1f34223703c622742ad15975e8f8dd910c49e717968d98fdee45747566dc5153240144e94216fb27d5ccf33db0c66e911dd1c0f36be1331699d1f5eca820c0f69ef00ab9bea810fba971c785fb8f878dd3ad</script>
<div class="hbe hbe-content">
<div class="hbe hbe-input hbe-input-xray">
<input class="hbe hbe-input-field hbe-input-field-xray" type="password" id="hbePass">
<label class="hbe hbe-input-label hbe-input-label-xray" for="hbePass">
<span class="hbe hbe-input-label-content hbe-input-label-content-xray">您好, 这里需要密码.</span>
</label>
<svg class="hbe hbe-graphic hbe-graphic-xray" width="300%" height="100%" viewBox="0 0 1200 60" preserveAspectRatio="none">
<path d="M0,56.5c0,0,298.666,0,399.333,0C448.336,56.5,513.994,46,597,46c77.327,0,135,10.5,200.999,10.5c95.996,0,402.001,0,402.001,0"></path>
<path d="M0,2.5c0,0,298.666,0,399.333,0C448.336,2.5,513.994,13,597,13c77.327,0,135-10.5,200.999-10.5c95.996,0,402.001,0,402.001,0"></path>
</svg>
</div>
</div>
</div>
<script data-pjax src="/lib/hbe.js"></script><link href="/css/hbe.style.css" rel="stylesheet" type="text/css">]]></content>
<categories>
<category>哲学</category>
</categories>
<tags>
<tag>思维系统</tag>
<tag>马克思主义</tag>
<tag>强势文化</tag>
<tag>唯心主义</tag>
<tag>唯物主义</tag>
</tags>
</entry>
<entry>
<title>分库分表Sharding-JDBC</title>
<url>/posts/342f571b/</url>
<content><![CDATA[<h3 id="一-初识Sharding-JDBC"><a href="#一-初识Sharding-JDBC" class="headerlink" title="一. 初识Sharding-JDBC"></a>一. 初识Sharding-JDBC</h3><p><strong>1. Sharding-JDBC是什么?</strong></p>
<p>Sharding-JDBC提供标准化的数据分片、分布式事务和数据库治理功能,定位为轻量级Java框架,在Java的JDBC层提供的额外服务。 它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架。<br>适用于任何基于Java的ORM框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template或直接使用JDBC。<br>基于任何第三方的数据库连接池,如:DBCP, C3P0, BoneCP, Druid, HikariCP等。<br>支持任意实现JDBC规范的数据库。目前支持MySQL,Oracle,SQLServer和PostgreSQL。</p>
<p><strong>2. 为什么要分片?</strong></p>
<p>传统的将数据集中存储至单一数据节点的解决方案,在性能、可用性和运维成本这三方面已经难于满足互联网的海量数据场景。<br>从性能方面来说,由于关系型数据库大多采用B+树类型的索引,在数据量超过阈值的情况下,索引深度的增加也将使得磁盘访问的IO次数增加,进而导致查询性能的下降;同时,高并发访问请求也使得集中式数据库成为系统的最大瓶颈。<br>从可用性的方面来讲,服务化的无状态型,能够达到较小成本的随意扩容,这必然导致系统的最终压力都落在数据库之上。而单一的数据节点,或者简单的主从架构,已经越来越难以承担。数据库的可用性,已成为整个系统的关键。<br>从运维成本方面考虑,当一个数据库实例中的数据达到阈值以上,对于DBA的运维压力就会增大。数据备份和恢复的时间成本都将随着数据量的大小而愈发不可控。一般来讲,单一数据库实例的数据的阈值在1TB之内,是比较合理的范围。<br>在传统的关系型数据库无法满足互联网场景需要的情况下,将数据存储至原生支持分布式的NoSQL的尝试越来越多。 但NoSQL对SQL的不兼容性以及生态圈的不完善,使得它们在与关系型数据库的博弈中始终无法完成致命一击,而关系型数据库的地位却依然不可撼动。<br>数据分片指按照某个维度将存放在单一数据库中的数据分散地存放至多个数据库或表中以达到提升性能瓶颈以及可用性的效果。 数据分片的有效手段是对关系型数据库进行分库和分表。分库和分表均可以有效的避免由数据量超过可承受阈值而产生的查询瓶颈。 除此之外,分库还能够用于有效的分散对数据库单点的访问量;分表虽然无法缓解数据库压力,但却能够提供尽量将分布式事务转化为本地事务的可能,一旦涉及到跨库的更新操作,分布式事务往往会使问题变得复杂。 使用多主多从的分片方式,可以有效的避免数据单点,从而提升数据架构的可用性。<br>通过分库和分表进行数据的拆分来使得各个表的数据量保持在阈值以下,以及对流量进行疏导应对高访问量,是应对高并发和海量数据系统的有效手段。<br><strong>3. 分片的方式</strong></p>
<p>数据分片的拆分方式又分为垂直分片和水平分片。</p>
<p><strong>垂直拆分</strong>是把不同的表拆到不同的数据库中,而<strong>水平拆分</strong>是把同一个表拆到不同的数据库中(或者是把一张表数据拆分成n多个小表)。相对于垂直拆分,水平拆分不是将表的数据做分类,而是按照某个字段的某种规则来分散到多个库中,每个表中包含一部分数据。简单来说,我们可以将数据的水平切分理解为是按照数据行的切分,就是将表中的某些行切分到一个数据库,而另外某些行又切分到其他的数据库中,主要有分表,分库两种模式 该方式提高了系统的稳定性跟负载能力,但是跨库join性能较差。</p>
<p><strong>4. Sharding-JDBC的核心/工原理</strong></p>
<p>Sharding-JDBC数据分片主要流程是由SQL解析 <strong>→</strong>执行器优化 **→ **SQL路由 <strong>→</strong>SQL改写 <strong>→</strong>SQL执行 <strong>→</strong>结果归并的流程组成。</p>
<p><strong>SQL解析</strong><br>分为词法解析和语法解析。 先通过词法解析器将SQL拆分为一个个不可再分的单词。再使用语法解析器对SQL进行理解,并最终提炼出解析上下文。 解析上下文包括表、选择项、排序项、分组项、聚合函数、分页信息、查询条件以及可能需要修改的占位符的标记。</p>
<p>SQL解析分为两步, 第一步为 词法解析, 词法解析的意思是就是将SQL进行拆分。<br>例:<br>select * from t_user where id = 1<br>词法解析:<br>[select] [*] [from] [t_user] [where] [id=1]<br>第二步语法解析,语法解析器将SQL转换为抽象语法树。</p>
<p><img src="/posts/342f571b/webp-1685959324557-531.webp" alt="img">](<a href="https://zhai_zhihui.gitee.io/posts/342f571b/webp-1685959324557-531.webp">https://zhai_zhihui.gitee.io/posts/342f571b/webp-1685959324557-531.webp</a>)</p>
<p><strong>执行器优化</strong><br>合并和优化分片条件,如OR等。</p>
<p><strong>SQL路由</strong><br>根据解析上下文匹配用户配置的分片策略,并生成路由路径。目前支持分片路由和广播路由。</p>
<p>举例说明,如果按照order_id的奇数和偶数进行数据分片,一个单表查询的SQL如下:<br>SELECT * FROM t_order WHERE order_id IN (1, 2);<br>那么路由的结果应为:<br>SELECT * FROM t_order_0 WHERE order_id IN (1, 2);<br>SELECT * FROM t_order_1 WHERE order_id IN (1, 2);</p>
<p><strong>SQL改写</strong><br>将SQL改写为在真实数据库中可以正确执行的语句,SQL改写分为正确性改写和优化改写。</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">从一个最简单的例子开始,若逻辑SQL为:</span><br><span class="line">SELECT order_id FROM t_order WHERE order_id=1;</span><br><span class="line">假设该SQL配置分片键order_id,并且order_id=1的情况,将路由至分片表1。那么改写之后的SQL应该为:</span><br><span class="line">SELECT order_id FROM t_order_1 WHERE order_id=1;</span><br></pre></td></tr></table></figure>
<p><strong>SQL执行</strong><br>通过多线程执行器异步执行。<br>结果归并<br>将多个执行结果集归并以便于通过统一的JDBC接口输出。结果归并包括流式归并、内存归并和使用装饰者模式的追加归并这几种方式。</p>
<h3 id="二-SpringBoot整合Sharding-JDBC"><a href="#二-SpringBoot整合Sharding-JDBC" class="headerlink" title="二. SpringBoot整合Sharding-JDBC"></a><strong>二. SpringBoot整合Sharding-JDBC</strong></h3><ol>
<li>创建两个数据库order1,order2,分别创建t_address表如下:</li>
</ol>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">DROP TABLE IF EXISTS `t_address`;</span><br><span class="line">CREATE TABLE `t_address` (</span><br><span class="line"> `id` bigint(20) NOT NULL,</span><br><span class="line"> `code` varchar(64) DEFAULT NULL COMMENT '编码',</span><br><span class="line"> `name` varchar(64) DEFAULT NULL COMMENT '名称',</span><br><span class="line"> `pid` varchar(64) NOT NULL DEFAULT '0' COMMENT '父id',</span><br><span class="line"> `type` int(11) DEFAULT NULL COMMENT '1国家2省3市4县区',</span><br><span class="line"> `lit` int(11) DEFAULT NULL,</span><br><span class="line"> PRIMARY KEY (`id`)</span><br><span class="line">) ENGINE=InnoDB DEFAULT CHARSET=utf8;</span><br></pre></td></tr></table></figure>
<ol>
<li>开始整合SpringBoot,这种方式比较简单只要加入sharding-jdbc-spring-boot-starter依赖,在application.yml中配置数据源,分片策略即可使用,这种方式简单,方便。</li>
</ol>
<p>pom.xml</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line"><dependency></span><br><span class="line"> <groupId>io.shardingsphere</groupId></span><br><span class="line"> <artifactId>sharding-jdbc-spring-boot-starter</artifactId></span><br><span class="line"> <version>3.0.0</version></span><br><span class="line"></dependency></span><br><span class="line"><dependency></span><br><span class="line"> <groupId>io.shardingsphere</groupId></span><br><span class="line"> <artifactId>sharding-jdbc-spring-namespace</artifactId></span><br><span class="line"> <version>3.0.0</version></span><br><span class="line"></dependency></span><br></pre></td></tr></table></figure>
<p>** application.yml**</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">mybatis:</span><br><span class="line"> configuration:</span><br><span class="line"> mapUnderscoreToCamelCase: true</span><br><span class="line">sharding:</span><br><span class="line"> jdbc:</span><br><span class="line"> datasource:</span><br><span class="line"> names: ds0,ds1</span><br><span class="line"> ds0:</span><br><span class="line"> type: com.alibaba.druid.pool.DruidDataSource</span><br><span class="line"> driver-class-name: com.mysql.jdbc.Driver</span><br><span class="line"> url: jdbc:mysql://localhost:3306/order1</span><br><span class="line"> username: root</span><br><span class="line"> password: 123456</span><br><span class="line"> ds1:</span><br><span class="line"> type: com.alibaba.druid.pool.DruidDataSource</span><br><span class="line"> driver-class-name: com.mysql.jdbc.Driver</span><br><span class="line"> url: jdbc:mysql://localhost:3306/order2</span><br><span class="line"> username: root</span><br><span class="line"> password: 123456</span><br><span class="line"> config:</span><br><span class="line"> sharding:</span><br><span class="line"> props:</span><br><span class="line"> sql.show: true</span><br><span class="line"> tables:</span><br><span class="line"> t_user: #t_user表【即分库,又分表】</span><br><span class="line"> key-generator-column-name: id # 主键</span><br><span class="line"> actual-data-nodes: ds${0..1}.t_user${0..1} #数据节点</span><br><span class="line"> database-strategy: #分库策略</span><br><span class="line"> inline:</span><br><span class="line"> sharding-column: city_id</span><br><span class="line"> algorithm-expression: ds${city_id % 2}</span><br><span class="line"> table-strategy: #分表策略</span><br><span class="line"> inline:</span><br><span class="line"> shardingColumn: sex</span><br><span class="line"> algorithm-expression: t_user${sex % 2}</span><br><span class="line"> t_address: #t_address表【只分库】</span><br><span class="line"> key-generator-column-name: id</span><br><span class="line"> actual-data-nodes: ds${0..1}.t_address</span><br><span class="line"> database-strategy:</span><br><span class="line"> inline:</span><br><span class="line"> shardingColumn: lit</span><br><span class="line"> algorithm-expression: ds${lit % 2}</span><br></pre></td></tr></table></figure>
<p><strong>编写Dao</strong></p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">@Mapper</span><br><span class="line">public interface IndexDao {</span><br><span class="line"></span><br><span class="line"> @InsertProvider(type= AddressProvider.class,method="insertAddress")</span><br><span class="line"> @Options(useGeneratedKeys=true)</span><br><span class="line"> int insertAddress(AddressDo addressDo);</span><br><span class="line"></span><br><span class="line"> @Select("select * from t_address order by lit")</span><br><span class="line"> List<AddressDo> listAddress();</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><strong>编写controller</strong></p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">@RestController</span><br><span class="line">public class IndexController {</span><br><span class="line"></span><br><span class="line"> @Autowired</span><br><span class="line"> private IndexDao indexDao;</span><br><span class="line"></span><br><span class="line"> @PostMapping("/addAddress")</span><br><span class="line"> public ResultBO addAddress(AddressDo addressDo){</span><br><span class="line"> int row = indexDao.insertAddress(addressDo);</span><br><span class="line"> return ResultTool.success(row);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> @GetMapping("/listAddress")</span><br><span class="line"> public ResultBO listAddress(@RequestParam(required=false,defaultValue="1")Integer pageNum,</span><br><span class="line"> @RequestParam(required=false,defaultValue="5")Integer pageSize){</span><br><span class="line"> PageHelper.startPage(pageNum,pageSize);</span><br><span class="line"> List<AddressDo> list = indexDao.listAddress();</span><br><span class="line"> if(list.isEmpty()){</span><br><span class="line"> ResultTool.success("查询内容为空");</span><br><span class="line"> }</span><br><span class="line"> PageInfo<AddressDo> info = new PageInfo<>(list);</span><br><span class="line"> return ResultTool.success(info);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>此时,启动项目,用postman访问插入接口:</p>
<p><img src="/posts/342f571b/webp-1685959402920-536.webp" alt="img"></p>
<p><img src="/posts/342f571b/webp-1685959418837-539.webp" alt="img"></p>
<p><img src="/posts/342f571b/webp-1685959428860-542.webp" alt="img"></p>
<p><img src="/posts/342f571b/webp-1685959439756-545.webp" alt="img"></p>
<p><img src="/posts/342f571b/webp-1685959447590-548.webp" alt="img"></p>
<p>插入四条数据,可以看到两个库,两个表中的数据如下:</p>
<p><img src="/posts/342f571b/webp-1685959453888-551.webp" alt="img"></p>
<p><img src="/posts/342f571b/webp-1685959460322-554.webp" alt="img"></p>
<p>可以看到,根据lit字段进行分片(取模算法),因为我们指定的为2:**algorithm-expression: ds${lit % 2}**,所以奇数和偶数会存到不同的库不同的表中;并且需要注意的是,由于我们指定了**key-generator-column-name: id**,即自动生成主键,采用雪花算法Twitter-Snowflake。【不同的库】</p>
<p>下面我们用postman请求查询接口,访问:localhost:8080/listAddress,查询结果为:</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">{</span><br><span class="line"> "code": 0,</span><br><span class="line"> "msg": "成功",</span><br><span class="line"> "data": {</span><br><span class="line"> "pageNum": 1,</span><br><span class="line"> "pageSize": 2,</span><br><span class="line"> "size": 2,</span><br><span class="line"> "startRow": 1,</span><br><span class="line"> "endRow": 2,</span><br><span class="line"> "total": 4,</span><br><span class="line"> "pages": 2,</span><br><span class="line"> "list": [</span><br><span class="line"> {</span><br><span class="line"> "id": 363696781952811008,</span><br><span class="line"> "code": "1001",</span><br><span class="line"> "name": "济南",</span><br><span class="line"> "pid": "0",</span><br><span class="line"> "type": 3,</span><br><span class="line"> "lit": 1</span><br><span class="line"> },</span><br><span class="line"> {</span><br><span class="line"> "id": 363696816295772160,</span><br><span class="line"> "code": "1002",</span><br><span class="line"> "name": "青岛",</span><br><span class="line"> "pid": "0",</span><br><span class="line"> "type": 3,</span><br><span class="line"> "lit": 2</span><br><span class="line"> }</span><br><span class="line"> ],</span><br><span class="line"> "prePage": 0,</span><br><span class="line"> "nextPage": 2,</span><br><span class="line"> "isFirstPage": true,</span><br><span class="line"> "isLastPage": false,</span><br><span class="line"> "hasPreviousPage": false,</span><br><span class="line"> "hasNextPage": true,</span><br><span class="line"> "navigatePages": 8,</span><br><span class="line"> "navigatepageNums": [</span><br><span class="line"> 1,</span><br><span class="line"> 2</span><br><span class="line"> ],</span><br><span class="line"> "navigateFirstPage": 1,</span><br><span class="line"> "navigateLastPage": 2,</span><br><span class="line"> "firstPage": 1,</span><br><span class="line"> "lastPage": 2</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>可以看到我们的order by 生效了,并且分页也生效了。</p>
<p><strong>【测试没有配过分片策略的表】</strong></p>
<p><img src="/posts/342f571b/webp-1685959468493-557.webp" alt="img"></p>
<p>如上图,只有order2数据库里有订单表address_order_table,此时我们想查询的话直接执行如下SQL语句即可:</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">@Select("select * from order2.address_order_table")</span><br><span class="line">List<OrderDo> listOrder();</span><br></pre></td></tr></table></figure>
<p><strong>【测试关联查询】</strong></p>
<p>此时我们想关联查询order2库的address_order_table表和order1,order2库的t_address表,下图是address_order_table数据结构</p>
<p><img src="/posts/342f571b/webp-1685959481164-560.webp" alt="img"></p>
<p>如果想关联两个表,直接执行如下SQL语句即可:</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">@Select("select a.id,a.address_number,a.order_remark from order2.address_order_table a inner join t_address b " +</span><br><span class="line"> "on a.address_number = b.id where b.id=#{id}")</span><br><span class="line">OrderDo getOrder(@Param("id")Long id);</span><br></pre></td></tr></table></figure>
<p><img src="/posts/342f571b/webp-1685959493053-563.webp" alt="img"></p>
<p><strong>【同一个库进行分表】</strong></p>
<p>上面是在不同的库进行分表,如果要想实现在同一个库下进行分表,则application.yml可以这样配置:</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">mybatis:</span><br><span class="line"> configuration:</span><br><span class="line"> mapUnderscoreToCamelCase: true</span><br><span class="line">sharding:</span><br><span class="line"> jdbc:</span><br><span class="line"> datasource:</span><br><span class="line"> ####ds1</span><br><span class="line"> names: shardingjdbc</span><br><span class="line"> shardingjdbc:</span><br><span class="line"> type: com.alibaba.druid.pool.DruidDataSource</span><br><span class="line"> driver-class-name: com.mysql.jdbc.Driver</span><br><span class="line"> url: jdbc:mysql://127.0.0.1:3306/shardingjdbc</span><br><span class="line"> username: root</span><br><span class="line"> password: 123456</span><br><span class="line">#### 分片配置(这些表都是需要提前在数据库创建好)【一般都是在单个库进行分表】</span><br><span class="line"> config:</span><br><span class="line"> sharding:</span><br><span class="line"> tables:</span><br><span class="line"> # t_order表分片策略</span><br><span class="line"> t_order:</span><br><span class="line"> table-strategy:</span><br><span class="line"> inline:</span><br><span class="line"> # 根据userid 进行分片</span><br><span class="line"> sharding-column: user_id</span><br><span class="line"> # ds_1.t_order_0 ds_1.t_order_1</span><br><span class="line"> algorithm-expression: shardingjdbc.t_order_$->{user_id % 2}</span><br><span class="line"> ###分表的总数 0到1 t_order_0 t_order_1</span><br><span class="line"> actual-data-nodes: shardingjdbc.t_order_$->{0..1}</span><br><span class="line"># t_member:</span><br><span class="line"># ...</span><br><span class="line"> props:</span><br><span class="line"> sql: </span><br><span class="line"> ### 开启分片日志</span><br><span class="line"> show: true</span><br></pre></td></tr></table></figure>
<p>解读:在数据库建立两张表:t_order_0和t_order_1,会根据user_id进行分片,取模2,即生成订单的时候,会根据userId进行判断,如果是用户id是计数,则存到t_order_1表,如果用户id是偶数,则存到t_order_0表中。</p>
]]></content>
<categories>
<category>代码</category>
</categories>
</entry>
<entry>
<title>判断集合是否有重复元素</title>
<url>/posts/918792c0/</url>
<content><![CDATA[<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//校验数据是否重复(id和sim卡号不能重复)</span></span><br><span class="line">List<String> stringList = list.stream().map(SimCardInfo::getSimcardNumber).collect(Collectors.toList());</span><br><span class="line"><span class="type">long</span> <span class="variable">count</span> <span class="operator">=</span> stringList.stream().distinct().count();</span><br><span class="line"><span class="keyword">if</span> (stringList.size() == count) {</span><br><span class="line"> System.out.println(<span class="string">"没有重复元素"</span>);</span><br><span class="line">} <span class="keyword">else</span> {</span><br><span class="line"> System.out.println(<span class="string">"有重复元素"</span>);</span><br><span class="line"> errorMessage.append(languageDao.getErrorMessageValue(language, SimErrorMessage.SIM_ID_REPEAT_START)).append(j + MagicNumbers.INT_TWO).append(languageDao.getErrorMessageValue(language, SimErrorMessage.SIM_ID_REPEAT_END));</span><br><span class="line"> flag = <span class="literal">false</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category>代码</category>
</categories>
<tags>
<tag>java</tag>
<tag>工具类</tag>
<tag>集合</tag>
</tags>
</entry>
<entry>
<title>刻意练习</title>
<url>/posts/2e543a56/</url>
<content><![CDATA[<div class="hbe hbe-container" id="hexo-blog-encrypt" data-wpm="抱歉, 这个密码看着不太对, 请再试试." data-whm="抱歉, 这个文章不能被校验, 不过您还是能看看解密后的内容.">
<script id="hbeData" type="hbeData" data-hmacdigest="5ff4f12ebe81e5205a9b4b6d6fa2e0c0ca6e151c663ca536000efc1f2e20f26b">601b7ad76f4fbd60ff466c34909923e97ed128e58d6c203d7511ad498e001a1d6567b357b90becb535dadbaa4930268cd0ba6cbc33826ef8f7606700655e2d3cf7136459abf8ea3f7a9804e9372480f127b685e4497481f46d90cb9d4f5623182cb27027d47695bab4f75523ddf90143a7063ec3afe8629d6bd1e34f632aeb216e87e460fffd6911eb2e43c9656503552a0097ed7571613d0e64e4e59670bc1e023362e728005e25534957bb54a9a6b4f36b14c37ee1bd4455af1890f84aa323a61109db00ac69dc518301cc1f8843458a69a615627e8c826fe6ef2534e373d5ca6a5c4caf9ad4ebd32d219b5a696cc4d9dd1ff0672c4f0fc5fe087b90724521ec118d2fbcbb12c2e587ee2fdb4657699b4057985cd30bc9316c2a751246c1e2db06630340c293a9b62956fd20cb7a4089155ab5dbd9dc7e8cd5db2163e0c58430809e4654fc7e39234617234817e22739358b4d6ada0ffccedbd2626d0674d792632733be8de567915b42a2e478e15af7cf98ee1ef314e5c556348e7072dd787bd1c69b28a929f6f5b2aead92d69ded91655d41caca5cbb4a1a53336bb7583044bfe830c776f3e1a820bb3da8f680c5e2a2f744d903b0c574026e77bcc45f928f078bbf0f4440ddd986dd3c223e4e6ef284b88697b8a06b484d11cdc980c3a9f9baddbcea7b40ac227de313241cf547aef99ce522dc6aaae0a9710021441ec72b20ee12cd806448ae7d1a084429cfc95911a2e66535d4312cd1c49e86f8e1c4aa6addaec8d03c27b5c39fe1266d4b72dc6bdfb1035990c28fff90f538861b1d16e2fc5d774afd9823f58dd15a8bd441f634f467cc4278cc0497be98d3dad8b2dae0fc51896e12694fef7e89b6a6d31cd54be3eb8eab7a999e72f4dfe94d0a39ced2ed55e23b104e0d90690c0c6a2035a1d733a1698fc4e0e92f1cbf673325de23e5941468a0c8919c80e46c0885a50f2cfd0db55d0aa487b7e380769661db57d7c18f5181b0a35f35c5f50e45e21c045ec8ae7562c65ba478557929ce1d56617e8117f753893efcbe9fd10fb38a981646e7698fc650cc84156cdabec0230b985e2eb3dc5bad20c66b5ec1dfd1155beec731321bf81162f3c265fac0170dae51870ef02fd37f1a0507e5fb62c027d97ed3985cd242184683d04bdd315108a97ae03f19f27a73a6f1b6af3c8a647b782f28acd6cd59aaee71bfcfe8cbe89149f6d8a89dcb53df7c7991624487a68976699bee25ca07377d5c475ecf5afe30503f0e2b77550b3ea9013172d9f740cd28c18ef43abbf699d5dd40cc18d3169d21a7d7bca92b2c32cd7a43e6c1c02f8b205b63f36c8df21163daa2f0fa2f1962b81b84d33abc8fde14b401213cb108d7c8e93406ad1d72c04dde01932d7cc713bee249ffb7d0f54fe042078fe33a714a8ed47b540b461256c9f2c08dc2b2507b7367fee55e8bb493e00d11962a919f4d903fe58a7224532e4ddc9a283eaeccb06345ccb0888c7d1716ba727b476ae08c66445f2f59937bbb8d667a8af5adf19ef71571c36d796530984a697631c8a1a136eff907b26b81f915c12177d1cd697c7e7d759b2e72880cc37e28c1acb4163d676c573504effc0d050a3de59d19c321343b71284f8ab01977215f937a919ca5145ab48abf6a2c7e45a13e6dea86284248d4ed5b1586c9e0e02d2a852468687fdede88d38d985ca5e8e67a794ce693a321608a33a617c3431d61da4589deaaf47533c5b3099c514ec0e80fdf39b832dc2e251f3d75a39acf25d6deb8698ddd324957aaecfbd273d2f21eb552b57c8fe66f5ca1d4a4c015cbfca1c144616863aa822c578d7e525e42641aef1100cb7c7ec20ba12ff6ed90eab6c63086640d7249d27f2ba5579ce64ff89264de4995fddf97e3131d5e70279e36b5dbb4e30ebd6a65725e8d35e549c7c3e3fc36d0def0af0e1226144f17ffc3d4db09a90b184bd059c21be9c817755694191afb1619be403f10a2a42e295c4e85cb9c8559d5e087573ce9c9cbed90586f5cd117a886eefcc7ce818166ea63945311c2e9b46a0fbf55b355189d811bf3c3178b840a09095b7bf6837d3610b46e61683de8240ef1c6b3d5a3ba58ecc6560e1b8c212cd663931eacf209ac05f1b5fb0b1dd10972c2268c72f93d68f1a436c8fd19718a871f83ebf95eaff73d738dd6e5b58ee56abf76b81f437d5128c0ea3c1151904ed9b847b1668a06d3acf745d2e38d171c7cbc0a27eef384d967420fda645e805f3be1adbebf216e2c12119c5ab9ac13ca461b1e6f4802ca9238e43a404bdc7746bb5c68f6f587fb3d6747f1a7ddaf460c6a6110144e7b743bf76015ebcd9de7a272771fdd79d13c2ba88b8cab7296821f26da07d79adf5d602261abe43f89165566ccbf044c9eaaeba196d1184918f940777fb534b11b15265992d3afece156c7356ff5e842377cd308288dc912e408b93def8d3dd38ec5d71ce5b83f48ad151eefaed0a3f7bd5e8f3936c1340a8038716b448d242c8266b90ec88a316126e37881d3f4addc8474917cdeb99b6e9a3169bdbc014135f7f011c1b8b87a1ab14336b1de696eb98fd155305c6646d53ec49053de38f77a1d9290ed89ce6e22b5235b57800d3d75cafae81e37f2d033beff65e845c97c9ad532eb4bf76819701711eaa71051ac919f0478b9eae9debed35f102604fa29e043dee24ae1e7f1a3020a4ee661d93e3c69a475c034f5c1d972933e6c21f635c5baf66f7b2fc849fe8c2cfee5fd579ca4db3b9dfe53de8328c6448b25faec6a9ad2381a525ebb6628a2de98cfb89b9088b63fec0b63fc3915625802a795c38f3625086d630ed96e6de1201570522f5e4ed48c4ff9772fc23c817794f66f76b2d65e48891fb11c6642055dffa9cbd3b35e395b3d56c206d1ad722a760de0445a0442ceec46ce6fea458bda5c417e18c52132cf91432e6163e4d1e5d81ae72ae94c8e6826ac59f5895ef158827a580fac113463c5231ea047f201b85b4004b4bbd3f657c3fd32f3ca8ee440c98bd98f9d4bde9641a45c5f582c88075eab5ae072db195245d4eb37e4bff8bb1081af41610e0dfc6cc31a02fd1cc27c0076ee6a7127da40c895b7cb33f63a2955c411f04aa59c6c09742faa01add7266c8104d43668646dcc79a3756e7ba1d74a3e43cade2ccc99765e5ad188a97ddf55762cfeacbb4f0cc81db080b7e94f59346e6de3b16e83f5dc5d71460385ce78afd77ef2acb5e6e3f5bee19c31b2b649f82a4e96384d3e78e3faa35c1c4b14363cfea64c6b58770ec313530f096012b2e5069770a105c16f48dc9a2f501e98f6bac82fdcec325525dc8e1f032cb39528424fb03986b6907236b10f26811ea2119d2927ff9f4288a7cd79aab7517b87931561c54635d5698c4597f95bef1e227de03be34960d21d747a15919cd9d76862749a432c4a81746d8fecc93f7b6388bd48d8b021ac6037d01a89e92f9e9128fbe2ed6ec9c430eb3f21879697ec1c6d50495faad636a044aee26a359da3920773192d0603d2d581cd854a6cab120b8286df10ec8899c2cdfc2de7a8c58194fcaa1f2db125eb3f75459ced6d67a5e2d8055cb3a52502d6cad6766f72c78b9707195c7e0ce55e9fa0523499bbd3084056d38f1c208f4cb8ff6b942035d06ed2bdfad918a3fa16fec8be6d6f9f120f29e09a86260bc757cf0e9f4819b392a386794518f3308261a34c1e682211b24ad0afa26b9d57036d9cc873189190950570dd02cc8f8999ca9b3b8b73f9221b548f079da6cbfb6c5868be15044a6995afd849c478eaa48ebb3be99db5729739b6858c997f689fc07e56f85c01e6b45556b2c8b17ed5f77eae23da1fd68e9d6fc0be422aabb46d676c4f7fa7ac3e3cdb0d43773712ee6ea6c51bfb6e4e80a24e4269cf0705407fe9950f91ab651341a86552ff5e63cbfe817880e0c3950ae266eab2a59ab16b3d299fc0457ffe8c9c92a5f9cbe07f350dfea9328d227cc80dce3ee42e920041f02077db097fb57c68e8a5ae615f31f18f396986cc12739895ed5dc8846dc68691645f96f7bbdb0b5b15e9c469639e8f2a833165c6feef3b2f6f5d450ee8d63118d293df2654d259d998e6a85b2f3ff10f6ebb0fd538bfb6f597bf36fb298578c76a769ff34b36a9e16fd98070ad17cee8065516419301eb2dc93c4df32739ec803720a857fdcafee3b74cd4cc021b899635be5c5c3e61c8e70350cb0823eb5be7a8428968746543f0e8d34b3b6d82fe049563fa4b571917915fac1e72ccbbbc53076ad603639b637e865336ee06fe2bf85275a31d57310124da91f7db8ec3b3099b80d958dcab5d326e5394cf5a3b2a93af5c4316766f9e6858b558c12dd8f3992daa3c07d8b756c4dedffe9abf648fe1d71ad20f0e6a62675de4cc4f893fe9b000cabbacc25b43b1bef752f89de30c37884ba7958d83b19e6d8d318793a25e802bddc52b9ccc2c21f6ea072e916cb1cd0074b5f8ab65382f191ade85ab9f56e19bb189739a3b2fe57d8a50a5fb5373e41924092709971a73cc9b7a5371d8f882cf30dcc249f06e5093aa8f0ff8c227877cade0f283d42cdb67536da0341319d0ae7c9a38396dbfb41fb2ac9f21f4b5553c457404a0680a15815fe73163d2d830e66309a0f9a62f8f30e934455edaf33ceabac71592a1dffe5a62d7774375faec1200ba976e57e0caae5f3f716e7dafb35e4a7e2864b87d1d7336fa74f3a1c7a27e62ddce2719509250ad13fe8ef2914cf7738101ce7feae65efe4d6135c3d9aae4a74b934643c5418a921376fac325e92a6f771286781f2a28b95bbd341a15668d8a6b398ec17309523e79ca6faa1443c3886ed819ee9c2b701d864857531bb3795c1d4331c3ce48f2f7fbac7d3062092be047ec264e864dbf24f4bb1a0483886f1cc9cd720a0f11ac408365d59b60a2a691d96d8e5ebc39b1b1a3ab8a772d367fb240401ed9160cb4d4b25c7e155c1c8db08fb8c0dec0e74b5caac0748b0ec14cf27fa374b36b192d520a523489ea4114c42a0484847d95c47b7f68a5c1d6497f8b36ea9f11c1e6645d7f88d397a778269c838c09912cfef3081e6036486eb17fbb28c22c8f5f041cf22ff787bd5d75f243ebdc52eed80c6c3d5eed2fe130819bfec6d7b52b7a44394f155d532b84cdb972b51ef5f138b303efab600294e101c290b8b4c4f26322b0e6b8183c920c9a80649a163fefb095e7e471867db7481ed2f35ea82922c55f10a3d940b34a639c5d73a3de1fe6c27ea0fdbd876820b6a77ba03800516414ced2c55461779a931ff2a808534cc7a2692ca3a3d8596cb7c8b4e81d214cb8c34182be8c2be96ad34936c30818ba8fd8a4e07f2767d50209e3ebfbd3e399c44cb713321f189e388dd2570687afff411f9e5836c472e9c74c8a3c5155fa89740c657715c78c17077250196c6ab62d5ed1997c7bab86f489c55844a9f5cdcf1cc258a67c46354befa455cc618ab59186497d8db33d6ff304ba7ba2d9d98d25dabaeea71c412f6f7f04278040b3adda51eaff947e9b4bcc812f7e692c151bc78efee5f486dc4356eb7495fae506c3f44e37ea8a08e8fbf6f01463570869748583a8e40d058d6fa831f5a595b1416e1d9af6fa814e04aa044c09fc01b7bd8e4687d157f4ef9ab4f7a953b40895726642a4fe3644d13af56cfb1dc613c39734fd929718607593aed5cf3b27dfd91fa186e99282ed33ee62120426ef4db265b52afa30b52d8b423a69cb320e7ee0e512a2308c6f74fbc405ac986075dc2cbe18534cdfc9c5f923462e1e3a977895360fd71f55298d9704fb49fb8650e2d6b6ed9f424accbe59d59b8ebd5449f90bc087ba70c4f13cea95eae6220b2c757df52e41e51c67845960ceac22b00f26264d3233abc52a67dca594f5d2ac6f6815672c0147ae9ded74110f80f2118aabc2cf2f2940011e197335be7ef174c7e0e00126cf3a300a5700adf1008ab14667364b2b36084aa5b9d12a345572ed95bae2ed6643ce337e91e678dab86956cb22830410ae7b5c9427a110fdf6a3391104f61dec1ba6772adc471c9846d647a7529efb9e1f0c7333a10aa82bf34be2711cfa720f195838790b8edf4c622bdce0d7223af435560925229cd17e656e51bb8afad786e0a4d88d4f4ec0e995d5fd50b3c9fbc3f8ef17ba392c5b4819cb9a0a5d742ba0326ca550bf041bf34325d3302469319da68a66c65c1abe42b53ed34d610b311e966df3c752c93e4fbe26182486c790bc7b668d99c4152de7ec416de77d7e088bafe68d3e560ff71319c2b7c19c9df4eca78dd025bce65c041102622820496660b46ba7e4d03943dfe993aba0159afba031230567dc92862686c2c84fcca702d09de8bafb12f611aff61e641f420d76b4a007e8b941b1503a152bb5c81ed2fcf154b3e50b30f5bb872aa0c5c9239934a8a71199c2bde46b3d59e3dc9f5e526b28d15b17cb3f22a20d665cf8f05f1922774f2a7c511a0586768497956b916c2de8d8eafce2a4a4d08c3aa6209996e3c3f660ef0b792bc75e7c4e40824bbc817e25acfacd5c26880caa273c9ba5f89de153ee4c527f6a47f5d32c193bb3d878ea78ec5f67e0ae8b61c4c679bbbeb1bdef494181b91fba7106f29ff00921e9b190d771fbbf7c3aa6a2d69d5e2f73707f1ff81ae2021764e3c1b972449eaec4da5db1a449cbeaba2624358a090df861c5c2aa54d6b3cfd63c97923d10d1fd831f5a08191fe85f2d33e13d4975c54224c03b99860a0d5771835614d7d701506037aba0d777726829395ce559828f1f8d80f561b50fb343810369b3bee7471287b4c950f7506a5b208d48b80659395e122b627ac67ea67a28e61aedde81a01eed797f4fb598bf75e70b8e961edb0c4bcd5cce07fb44274605cfec29fdd2a9f6768bf58ff2581318f94c9ff7c823783a38684ac449a3e3221f2efa6aa5c1803dc18a3f34f952af2c43e3466b4fd4702dee60bd37238dfa6a0be8f308540df3a39178e083823c701b0aa43eed7f4258e9c3a2e7e9ae8a8c8fccb8d511bbb785192ef44677e6be010a78fbed1facc5b51cd0de037313086e5ccdb98a0a23bb63406dcd3e6fd0f7c3af4486a28a07ce0b659e84a0778179eadc8d247143fc4a948f12a958213e1d223cdae2c1b98c7cdee939ea99372cf5bb4f95cb607fa627e8075e65c61f1d71bdc8226c66ecc3c8b9249e9d2a9409a964998280745d9b1bf9a1f12c043421f17575d20bb653ef1a2ea31c6a812b0b13e9f4c100e337705abfb7e1a6f465fed10ef5897346177e703581bde3491b1d3950b819fe873202b7b2467c4b3b72dd1922941eb7e5503d998b90367e960ef12101c267a464334ddbc7d501a25ea9312fc500998ab83ce99c9c9ee93004be1939697ce31131816ecd5f1182fcecf3745179979a1bfd72ed9ea3f2775ee871681a02ebc768c19ad4a3c837ee42946bf379ad655e54a7dff04b52cd16178cedd18df4ccf4e005bc3b81031f3745cd3bca1dd4832c283a036e672bef6df75896a60022ae90d177485dd0497d0c15f9690c50f7dae045780461d0178d6d479bbc93f665b8db5b5e492ba9877f842a2356bd7f042067eb3844c55fcc22267030f26f6d41696528d54e05b40c5160e561e47399dff9f06c4d306c0a15df2d82be30f0297957ecee76cfeb3b48a97fb276b00da708194724c6543127b3199c541cc2e80e8d9a12c36692101a15595bb02d21ea6d35b96a0b1673ab7832925834ba8122f3590dfcd1d4947a97b659e3e71fe933a186c0b112a4fc72f5c59d1839b017c88f601f46956fdcf3e6a4024e749bebf5d17697629349ce5499426b9fc3276562adbd05da8d6688fe6570d318875ae0a05f511ad9daa5446c1bc19dcc39d883e6bd77e7c20c9bdeac3514eb5dbf7c6ec4ffc840fbaa8a713a4e6690c9cee6cd29fc26603d8bfa4d3cf97e777625a0f7a583b1fc24696e54b0960b12f2161d0a26fae862401dded56233b87159a516e02ba133c860c6f213baa6fe7b17f16bd9330320f8d3df64c366a586d669d387081ee68eb868b772ac7bda695771512b0d1eaab5d1711e9401286789d48a8c9ee09f1a77d9fa776fa13f2e48472efa98ed6dc2ff51a4081b26b5aa828a9a560beea3e75d2b35c5e2880a21867747be27a88dfd6cba7a61ae39fb622250afeddd163d219bb82fd4d6709471de3910608b440331dac7424e34a0a623e439d30be451d85bc675cdb131b1f6de7ab1d6d8007e09becccff7a2082882b0be94d91f9ec0657839ff6b0b420c876f3b6fb79d6a4e0b3660ba9e4a14272de4c681e1d99a851a34a546db683cf955c44222f337f3db1691a9f8cb46bb35f1908fd368b96921e3cdfee401146e3700a4d77b677d47837a0068544b076c6ca048d5c46f1173506566f9ca1793ce3e10281333a96213d707d99c140deab35590687a8370f387b2247f9213d12c7ac1aa351af7a811b372c9d1a0cb6e7b53c08c1acd2beed754ef1d31bf3d0cd410062dfe5123bd0c54d788b1a6e6e80904c88bfcb80ae534e851aa7b286c5e35011623de4f83216263abbdb93bd45e148f5cde5343f4c82dd4f480ad7519b56068e50713812c32116a964603efc05d0dca2601e3d4d4093ce0207233c3458138fc8528824f907b869dbccff4114f0c75c7d1c88591eb9ee3b79b4960a91bd2420466ba428db5660d5bca5bfdef3c71d282f687b89cec4aa938d33220be6d7c6bc24dc85a8477dad6b5983bda27da17b14a4126e164893d1608fb01c8f7a7fba41413a5da07e7d577cd6e43985c38885f4d762089efd8bf8667293880074e9c200b81fc75b9201ab6f3f2ca85b6b0fc02136e21aa29c901d88156b9ec0348ea4bf0dc180f9dbdc57d377c2f9e9dd72a8d5dc067823596102dde9be93374c9bc98153c96d27d0ed2a7d956eb6d4bec2c1c8294fe569ffdb6dccc80ba499699c1e1ec182693c7d7adc18c0e5e4f543f381193ef86936666083fdaa51f5bb06956437b676af9e38d5187fa12084d9e7060b091e5dbfca3248d5d3062f74eda0f83f3e72a0eb28f0255faadfc5c64135b74bed66fc77df11a763d2006769f52c0940592c19fe49380c93a3d7f8478193b2bd76d8b51d821132bf2f2ce9194cac10d24c6fdc0ae9c118d8930646d84b41bba7786d87bdb0e9c8a0c24111ff56fdf4ddf445d9dfa928567ad4806c2e2e68260f973839b3662820eb760d97d67bf7e151d79321e92c94f951d519ff69763067620d6d27eb7add037541b2afdd1ae5ac054364702a8352382fe0a80921a0320984f078b1a761c25da6eaf0344535054e1f8a2686c3cc97cab1915137040baa80f19f124a1bfa1aafe47190310fad2b0b61bd80d3076d43760a4f441cd1d17cd1ae967ff5137ca3f71320b578811f1593abeaa4e6bd6234d1bc9ef2ff1454cf32a8d1fd71729279c898e93158da443bf05d0c8954905b68f8e65aacb9b506e871b573528123f88ac574df668b6d071fce06aab96f6d1f9094a2fd6d59272ce268f2608d9d23c357a2868be9827593fe2120bb2e44edb0c361ec0c17e12049ba1a66335b51170b36eb12c6739fb2e66c4895ab25d222dc641fdb8a8848480a047a76e9c5bbb9158872ccf53d87e14c9d9716869c8b8fd085a7f320d80d1e0737810ebf0478473f0193d2d043d5ffed5a10973f04ecf1ff2208f0dcd1d0d52600f9a40c0899fa69a5edbff3b3d70bd90e53bb5276c72eb21dd5f551471004c7cd0f29bd4c872d057ec43c79e1edf2bebee673b967bfcf5f72b49ae8eae53b60f8739acc0065ae568e4faef0e56057f9b9a109ea6a4afb839fe26df486cb9b732e98f37fe523dc8aea9f8839fc1eff7475bedefae98e37a315a37f26a56e1499e5100aa33c1f60bbea65c8c15ee82350375a57ce97a742edb34b9bfdf73e52e3e493a28234e226a7127c30d359f36d6d8ea835bc80192efa4d3a9cb0f38caccb4a40ba5acf1bf79f814ccd781a77f29968ae425408da09046ab46974521ece8138de3baf8effc882bb5b4a21102960dc31ebec47e5312d64b381c40b570479f841da5d06ea204c2b8403b6926ab4b8fab648413e7ae16d3042a2fc9009037e7ba61e8cb2d1967aa22b32ee3ccb9bff289a6bdeed5a15cda80253c028134b5b28efc42c3e25247cbbfcebe565a26cd86aebaed7e2d95721816214709e4d96fc317095fa93862b576b8a5af01a613dbc260c89d293e710a5e7cc5a73c525862e3ed2a723b358134c9bd9836c437ddbd80362a660b931f947023fd49f5a303a4fc827820ecbced414611107f9c75614ecf1f5039458f11bf6c91896e4c09ca615ef9bcefd2aa75593186f29815c1cd7467305963e255a1c5aa76a420b8a1b024636ac92c0f2655bc7f8c3985ecea4aff776dac7cf6da015f04599148f41856678d6a3602fcf6991f300cd5e8e84d3312d00d65bb6f9e65e39d5a91e89a6b85a097463e516db4bb44187363ddb2da0b81554b581bc91d693e50f5dabe909d1e56d50d9ac5e6183f01da1e9482602d9cc69bd7cc298b4cde311092825ca69934915187f0a411652cba9121300721fd03fcc0de322dccf1f6e1323db7d0b519ce2e2be72fa7619e8a3d05325677a377daf579fc4b3c227c8dd28b43f6ba9f1c651b44ed250e2b1a601ab0e5c4cf13c9c2041d18f9ec6193ceee0cf0edc2b6fd55b99a8f46be9088f30e9634196dcc7a4069871c464dd458159f17fb4ab413d605a20087b520df75bc7c79196bb0a8517bee895a6929fe2aafb5e0d609f0454f6b9118647b22af7aaaeda2211d9472805c11a0c77b659e9aaa1d38167d2d407d622e05f25b8aab8df79a20af4dbe860dc244b33b20ce779ae9d05ae0b79a3d5345115e1a1789a73665cde30a78e5153e86e04510bf82bcc6598868938960d97c5c536db0491a9f78756895cf6875b629acec6e76a0ad88df3d13869d189904d194173157ce2657aed50fce1647654483cc9c13dd8ec7c3aae434cb8c213aef53180fe50f550442f5628a9a32664fb2050db24d306949c3bbf4ad29acfc84db1abba0b9204c36252224c9bdb5e412fcb42779e8e7b34fa8e9121cccc41822bea32fd093ecdc0ff648ef96ef3fe1429c9a84a864bb3f78ec5862b8a6de31cceeb1fb50eccbe7b46d64088e5823ec31d83825b48ce09934389755d9920b94a6fab67f48e94dacc6603153ab73f035e39347b705a5fc16a0ebd6827b790571d373c76c5c0d16d5ce2dc89b55bc9936af154faa2889c5bf6fab79a203a3a9cf378b7115ab6efcb263f58fc04596b8de3c213bfa4707266797fcff496e124932c15b96764f3774005eb4578c561efa49d835b191f3d9d2b5721cd096f1899c2b84ebaed092b8b2232d60a742c1809c291e911fcf3303b7171423c5bde8eafc1ea333df7e6d0951733e9578820fc33060fa06dce633c8409b9fb5dce0015af6a72c0df3fa7e17db7db633f6461d1e70103538f2b718bc33ab66bfd5b5a691801f6e84112626a2e688eccd6c951607f4930115aa7fcb69532e078dff29701fa53210b6fd1a88f89b42dc7673ec5802bad7f716911bbc92a2cef1a93d6ff5db2c862aed80c6ee77b58ebc6a30418296027772a6d4ccba9cc4330766e32a86ff47fe37d325e29d930db8eca1f9e67694eb33beb29a211e1b60581902f0d750fea41663dc745c34bf0eaa7f655ce78b43b6716e3b90a660224adbc8e148bed31a76a315e636dbc6bc4d45e76d07c47621da762f1f942dc9bef9ce29601a789f73c07f9fb81a06d4f52a742145617031984f1af56c62f3983f26d3a1fac8d288504c43d80685caa3e401f4064015e612b1e805f9da63044ee41f1310bf9e342792cc27c055df6713839c99be9ca2453e834004bcadc104d3a829be874d5e29b65182957872f7096fc75e86173a35e3dd05077c71df2c09497aaa557a28fd625f330dd375a7482d0b6e8d10ae3f6bedb40210e7831885c6e22b6a5bf0e0cd3781f3bc69285aaaa77484a9265da0b72203d9f83f28a82c9dca01bd3c787f402d9aa4f5aef7a8330b5d5bef702e078244a1021e67c14a9d589cddd676ee3576954056de4d8f5fcc7aec1fc5d2bd43bf7d46cd2df929e3bbd417cfa3506a2e03a505b1b09ef90b36236c484e37cf4e8f425539df0b42ae9c6de13be46c0a78e8ae31d2108257a8da3d9fdcf86939506ad9c05bfd852f7c637e091989b54c642667bb2bfa732bcbea11d71ce0840102e5c9872b87607fc584424e9d187a4624255d35068cd8e229881cb9c196c99738212eccf15fd1f20b75799c86091fc9f457a75db9b663d3b17f9f3e7161b83f44661ef79bacd0483bf89849b4d5478d125ca6504697fd4a6f2d73523002e2f02f959cbd479bfb7f426efe688b1bcca26fb3e34c245d60d11e96015a5c67d15a1c79bb1ea14299889bf695426229e363bec14e519f0cdc2d5899a661d6729596a72bad92b97a9de261595d5bab4da8f5cfb81db14607a442caa57297dab1de4136f0bb357b67d8914054bc4fa4890ecb65f4f3ce51d1722ca0d0661cc5bed06d7506a03b4c501acb99b73b6dd3ef1c314511cd41acb1ebcf14b9bcf94a53ed333ba3aa5168a1765423af31e319e25ddb61cf8e42507844ee78babaf4239e39fb16e83228c0a07a3b953aadd3940f8b1efc9a9717950fdbddbd1b7a8f02f379f112d8ab9b1c8e9cffc3a6aec9077693064992f6009dc9ae637ba3765b76eb2e788090f156e1a799daf0a2579d4a017f65cc4a07b44bc951cea8705b57894b37e279c627dd546dc0ceec2700ea9ebcb63128f0d9a22b20323d942b939ac4ed778c1fe1f419a0416384adc914e187329f95fe759a69b8d1b5b25cf76b8f58482c5c7ed8f02cbb185d84b42eac43b5d35aaa55d30aad61089e41d1ee65a737f8ce728370b60566755463df123d525b3cccbf721567e6d3fa848c1349c781fc6df03e7f5b5b690e6e437ff6763653645d315e09b5a20ae5372fc3a20d9d7cd177a88d5ca8e8a412b8627f5a8382a8f91d742d3f5bcb15e9a36b0f3a1dba5335eb1e2963e52cd55b679395801f3512a2ab9b9556a7e35d431eb75d23fbd7ebaeb573dc7754cea18a49dcf69e10d9800111b9df1431735d0dd4b6d991a0b5b54ff253af59c7c76d2e33d0db6dd0762ae0f7d2f125ed8da2e7b1170891b16bfa0cf68be1e8001ab43d653515bf11219cc5cef993f47cfb64b7ec39f673fb1c6eb5122e107a00bd2683afe8387b3e8e65f3ead3687a4708976274735aadb16d1bcd32de682a5627dccd73c608a86d55f75c28b679af4187e9fc10d9b35f3350c746f002e56aacefd2883437cb035ecb1b6a88aea6c1d13652d798bc64c95df3d5112971d9d0f062859520d3ea1d0e06973532baa80fdc3989736096d6c9609c7400bee05a41bffb323f419f16f9ee3c8e05879db4c8ac7b582c7e53b766920885f01a0abb909de5e600ab11a6471569305c3d403a7ced33e187f30ab11d413f5b0844282fa2c9cf1f0186c8004f31ba3c81dc0b346d29406a9fb20e2fdf99e54036632009551ba0d6c04b1a8a7bd6bca1597d07adf3de42e8085547b6d8b1ca4209efd47fdbedb9e065d7cf5a8b8140af1d89928f98506f2b6c7ec902b7769e975a02add76865a8e09163c65175679884ef4a1f18d916d105d10068588ad1f8171ef58bc8bb2eb82176fdf5e1d11238e952cc11ce925dc2db6372969063e1008935c4824b04e93f7545b7a2f54fba30a70d65973aa05c55282f188731d6b072d06f937690f509226a9584bbcb802cd3913f0a1ff9824037fb19c78daaf39e01c4a565ac2d548e92e10c6775d598fae0693d89a7a1be12b61945d1984d660fdaa86aa7612edfda98ace44bbe2169638997e6b1b4732bb564a2d799fbc2b2dda73d31e6a7f12da24b198d7081e6cda81f250be24b41cca34669ebc6e6837c391ddcb6d39f2e4204c09cedf5f2fa00ea445dd364f40d2230158f70b153978d3d73a34f8e37fcae943125b0c9285b35999ad5551a5dd0d0daab9b24eef0cb7d2ce92f0a82b09917a8bc1d3a16a02f7c8404c55d14f40c228b53da397ae82354fe756d78b1c33725a130efe047d0f3e0855309c061da09133dacf845958b01fe8c80f8a2aa8a61e5c42d1f4c414a63812852512fe1375092435b3f1d5333b8c362814ffe4015ff2b7e1c9f17c244b663b2ae7c945d863866fef801382cd29f5cca1d8afe58466965eefcdb61fa2ff9a47ab5bc4a375a679639c13b8aeb494bda4db037d2ef73c52d01bf38267f2abe3e9b0c25d4fb8299768e8cc09d436546605abb49d4102fdac4c611feb339bcc0763837fdc9abc7deda9c41f2522438dd823565bd713fca9223dc63518ba2e6eb8927b1e1e9f36861c8987a8cd713af162a4078942cc0571cc44ae7e474c63a15053828e115d591f84a1c34aaa9857f2bfb0f68db233f025139f11908694d6032b78301ce78b0f01e60a30cc78a8898239ab0cc02840c2bc68a63a8b25e738c9d5c01bd9863cefa1867a3db95fc75e25d46b760ef2b246f57a103ead2f0748dba317a0f0f9cd74028399b24aca79a98cb698d390f8c3db63834da328740e7a407a008b2574b8bfb8c2b02901f16467568475266672056d48852a770303f4c7c2c10af9e8f12d5dc03a432288dcdac88ebf67e62ab78383c4e0abf1d2e9f815c4a0dd90ee761848e5e1544297dbf9e4b87f5bf4c0030165a936d05801f9f0fb366ebf0719680f5f0096935227e24778e69afa55713c45c4add3923ffbedb90d13e5c90038db3348ebc56c25395a2372ea1623d96a6037f10bdfa88ce4c1be7340f6db835e81b058fd00657fdac706ab1ce0baa44e69c9de18cae46eaac99d20c71cc42ea7f62918edcb96db54e7e67675d6b26ce2f93265130ec87506b7b53ab3c1fc9e9b47e3a45b653d7f2d2d946bed601d39f1461de3b24b3220c87d4fb02d5597a0e6bb11e7bb3e22478f4d927782b6bf6ffced479ae3604491a7a840f59f67b1be9779ac6ec71a5ba7450c7c4f376f08e27fd3823aa907ddecd48a69c01e95d753f93e7ac02ed34e907e7539c2c0ad2f359e78e3fb64112eccb5935626f5e836a0041ed7645ea63809e6a42f5e5ec7cb84dc31fbc1222ed03fdcdd8c1aaf321875d5b6d5ffd679ebaf05d059988cffb23d0b8d221b431725a98254c930725cb55e669f1c6805f8126c03de231768d1536979a58eaf51b1777a1dc08ad856ceacf1ac56b1633ac19a7a5b163db044f783e83c9d00e2f1be83cc477027279219d8ca990fa6e6fcc4dcfe7c10718aff69d6495d555de40c2717c0193265d0707a1be6d570be8696e24b265b74c2ac917f0f90637f244183ca42be37da69cbfe625af857f0ddeecac5b22e2b39d5cc5bbffe033e929394ffa49258a6df016717067403a5ff1afbfad3a2811a1d9a308b71c7f7a05fc66e755c9dc6a12ae545ce4b46736921b8056c4a538cc5d0dffa1ee67d22a6cef19d295f9446b262096c4b0cf6f6ac87f0a9ea408a0b8a47cff828c17ecfb0aca6a71f0458fc538df6640e8515c51e0c43b876a9121c13fea168a55de47cdc91eedf2186c31211f5693dfee15d56c05c017c288420de90e488e538e068366acec5fa546af5cccbff24853ccf69ed058483fb48eb9f3e725be0d1ab10b0d08020f6214eb1acdbe8404bc9aa208f27082a945a9a9e64f3b682d67a1a9973910c6baf9a6c9b48f9b584a33bd306441625671c90e1b9901815157617a5d7dc1edeb2a1bb12e166d6d87b6deb78ae13c73ccda3ac26d15fa3687e5f4050148a31f4ac9494f6ada633c1057654fd860c249475e18e4c99000cc703b88c155b29fe3f62bc93b1fc1f513bdba0023e858962967ffb3bd5c16375fc8be4bf162e287a631f0d763530bb699888456429dc3b6b6177e3e32f291aa0f1679bcae28d7ee27e92b7eab47d52127175edc7fcd3d4952050ec0be0ef9d96144bd456431e3b68ee2b813a6cf753a6e2f8da75d6f1b7df4bd00f4fa4a18e9482ff8385ded4a1aa53cc86c7524b0733bb34db3e2a2bb8cd922e9b1a5ebc4e2b41afe1bf283d8ffd347f444f424bb6d1482414807752c822f917408039089dbe38002712056c57349cac9d3f6ef8ef8e2a13c87d96dc16218fc484f0adc0b06a2928638373577a6490e9663ebdcf27c8fca4b4d59f027dfc9c6058c2168bc9fbf6ae605b53b9a9971a572b1dbe9d812e4e563975125923fb34c63124933d8f40884212820ce9e157fdba7082fa4db078e845e382d6b46eed17562574a8bfb3f2e9860a8e46772e73de6b6dce0116a81f17b460410d4902b7f44ab1aacc31c86084179b19733d813b34433afd25a6b366921b08d88280ad58b6508784b40d4381684fcf95c505db913e8b20b73158b59f75119ef1b8e8d4611ddb14c45f31121e7fa2c216f64b05c01b741612a07a1fc6930ecc1e68e0e9a0953ccd4f6c27274d32e1411d34efa3af9b0fa766fe73048e93128b5bf56f9741d2fe9adbae12b5a5a75718597f36a9955c341a242e34b40b651a0df642ff25329abe2bc0fbac706a9770d0d997c240a8901afa40e20b5dee85973545f91b50b1bd0cb7f640add27371c4713ab6e33932dc15e7e4682409fbe5a6473e71d948abd954168be3a5c9f76b02044c67a270b4f919b8334914383fb467382d9d1ce001c3ea511df2507ef1be918608a55bde71ec37191b0884b0b5e9ff26f5a322bd0660eca825dcde7b81d5da5f1d8260b87cda6a81e4e8374f3fe4dd6473911bd6be8b74a0c2ecfc2eb0b6f62da904ba808e173095962e99add0a33e9d218d77053009fcc1f0813067b682c5e580febdd5d37294538c1812e8c3de65605b5f415783b35f5b8ed85728343ab75371cf063589162d0e3923a1b54ea52d88690b9be42db5b6b0b6bf11b62c47f8b3f23eac42666ec491453673713db7624229ab7875b706acffee508c34405bc9bc574030abcde7a406d308dc23365582b52d3ad9233745e1f5b56b42f829549eed0522c77269f80061e04426455254d2a64dec99ab8c63ab90ead1cc747441e86c8bd09259395ca2ec5c287e219b45198ac1287afaff54ae7c1892373ffa404e83336be87cddb507622bdeb8683ed88c95466296c0b8d2b305cfdfea8be6ad6cdb74f0501df4dfe94569ebe948ee01858586ccc978312e9b5167fbe1de3c350a2c061e5f30e7f2be2b13a9c6bed1b666b8203556ae810f0ce4da31586d112b8a6b33bb08224c2201c4930192e1ced26dd78a91049cb664a4c1783c9f1c389b5fa8d1c08d99c1c06d843e0bed1bf8112fc538951272dc28f1822b933f247b8cecee4e6fb6f743f2745a367c569dae71593482b27e92bc0dffa1824041403b0018d5e1f94477d04e45f5a7cd0b6ec2496c2f81897bdbffe7acb4bd071682f83cf734cc5307feca60ed1b7d06451f9492b96d830656f048854cd70fd399c892e83f5e88c698c769eb98f329fbddc018593d83934ba8ef1efb8abf84b0347cbea966f6dada77a64c4edcfe8182f72840e4487a0f16051854f1ffc7511d3cc90bf6f0ce1af69f7c0b50b5efb58d9e838f301b705d53ce38334ede88bd546c433ac1df1fd1775915498ba59fc7b9d53fdd5a20f8c9df0379e77d27f5c137c41928ca3ac856a5cfcfaa9822fea6e68fc0d961aee79ed98a6c73096fc04cc6878af80a98f81b8221f6a65d576fe4e9f72f11dbc16b4b0b1becaf99fbe4d43414712e5785f5efbcff8d9cd453c1003927a4d1ce925ddceec4cde197bf75f0c5222131d7a615dc2cf4b815da68d0a9af5ed3a36fd7ee417a4c87c3e8886a9a4db05386936b1be304a163511ce8f425d4f549aeeb6c8aa609f39f4dc7bdd6df3fb5e30137ac6164af6f4e3222b19f27a36be2ac70c30494e221daa972c51ddd7227691943ac44b9ab4eae81f8e0e9acfda09ad8fab1f5847cca956ae49c378b8a0737bcbe3a8d5b930ed573246d3b360c51b61f194fa32ba940687d3d6a12b6df4099898e7dc73adb1513a9b5ad66aff4ab3984dbf9eb6f4d1b51ef1982f86f6afab9994e907dfbd8c78ebc1d5716f736e6dbba4aecfc4b95bb6aaae98b53438ca1c1f963daf133c8d7ed954ec967b2cb24e45a4116c5d785253c6755d79b807c26126bccb6d70e16af5d75204f0e79d35b01f247da153a524d10f403b58b0fac71f4b856bf23df6e63e7c7a305bc224fdc40f5a8907aff4c2de5dddc5a939ac7629ab6528fc705f84b48ebf36ddcdd436db3efe424eeb743b7d77b112670f6c7896dcfd3ac6ec6aaf79f41ce55d6d16a4490bc1ed929c80b91dfd18dfeb11647aebdd92a2fec4882c77e747151531cd6a7f34234433e236fa4b2cd1cc6f395c633ae017c7b89b24157842999ff1dfeaa82dd39a036f33f49c6cf6d3c2a2a81f6dba0c0fadbd9e9eed11685051866ad8ee7e0940e76c656b7a777ecdb951f0a51f0ea3c39480f03b5aea9dada0ed8e3eae93f500598f11e3c4b60a5963e5495649ebe1a4f1e74a34fc3a0838931058876147cb43f4e8dea3ad813cc732b2e2b6cf71ee95d357e3ba7cfcf9c6dbad86ef6dd4c192c27af001713641311cd5f8bdba86ed9adaad3d38e3ee0f486eec81d39571eb2e913e6006741b8f5194d8942590aea58e13de6c1298e6f104e578aeacb84f796aeca5af149c7e83db984ddd1ab17cca2636225714bd3d7866ff8f33f3ae90e5aaf99133b3e3414be663471c7d7e39d8991e161a56d08828e62ab71cd16b9921d2adddc1b12cd15aa35656ec1b9c3cc60b821b7f3fffd64e9a4be38a81709ac3049d69a42f6f310961d4e03324bb358e900d8d6cdc6748feab51256d9219aa99046453cfd8394e0349091b5a4fc14b5824d0b0baccc9765f36d0ab22fe1d4e138e3705ba2556c7986b70cc775f6d5ef148487bb2873b4a157381997b498e34aa62f5326945c58e36546cfa003f74a9f7bddee2dedc5347bc62944a835e6883ce4ffe9f215d3b56e6a3c89ab1f886c9d555f225bc722249581039b5359b7c395b1927e6973ea9787daf8194f15ab749efd77027b7f2ace3ce0ac279f166df30ddf3674df4e308725c068490de05f63ebfb94552a8c4dd9abce86492166e1d55309578bfc3df5152437cd5495b033f27817df26957ca4b63116d3f71ffc9d5ed644e67f7305a57d20e811e9785bcfe6777ab352408699e66b9042afb66c014c6cc893d3d80db50a0b85ebc88f3f9fbcaf4a9247d5e9c7b15d6c680a3ef37a2700ca704ff1a2978da79a48b874193f49b5da1a66fb87e696c844cdbaa9a4884b1298e71ddccc3e600dd3aeb91d57992138c586600aef764a532d6b2c5f47690223090bd3b9fac0e9ede809fbab2e5e90a1716d6ff46cc68a922495f1f04f13b8c7f8848bb90b178dd4431ae23f6ce4923d91fb71064f413967e9ceb07f338c6a9a8be79fbbbd6acdf775a125f7b17b0156ad1d32090a31652207e63e97e8d43b66775b0be712cf6cfef2fade36c12a41e78f775e0dd9fa43abe328857b61eccb4768b71699712d81718685248f1f08c1548ee09540c430b0926a51070c0984fe56a637b2615d2e8642bd1bf16670ed36f1bf0cacb4876ea115b06a36de4ee6b2a60676549e43e4a424fcb4d6878bfd1723b3779f4d050fc457c50ccaac7f842a8ebfe094112b6919e4043b29e02e0e363957ba491f009085a816cc1d1fddf2ec12647838cc0144187b956b78f6a8937e90edab9ca51515d9bb98a3e5eb43482e3ff8a4b061748dc3b88b19fe0d109b14b183f2cda3b0744b68cce9c1e90dadbf7569deeeeb941b13e2935fad2e775191ba4cb2455f637f90ee072180d568eca008502c425dc38f820c830dcf05168b0555d50343f670367f89d537acbb2ac371883ef0f921198d0593489278a0a684691e30e7b3e6f564e289206f667daca218623410af1eefd19acb2957fdb7276d1f7da294f6000937149a820f0c1f9c682663f3dbdddcb2e6c4707ca1cb67feb472f8ba249b1ecebc4e261df9e631bb463fd98950e05dd69263893be6709f10030ff7f4730e7a35d7cfcb1e46d5650694dc89458946281d9978e33dc8ed018993e4a96e74f41e6cc2962739992edc2daf1709af8a4cefaf1aa54c70488f33980495b569ea8665c880ee9eb35bd31243aaef607e7784807782b9351383d30a980462ed58344edb307444e98a074b97e595f8ace1ab6f0c46b81ff913377764ebf5516093cb7f7a45bc89612be36819ebbaa144d5b5f4889949f6c6448590894d9a0b556b6f0a62f0405bafb029a78192d4763fa6050d8ee9465a0c083e349e3ce4aaffe478f2a0f4a7addaa3c110a99abbc5bad6a1043d23933b84da26a56305745e146a926243e175c669b55de446d7f5838b595840b2268364b8872da611bc91d4b09142a282e095efd6e9ce652025cdc78d36e351df9747370461ed12e885c1a4d2ac6f64b5d2855a307c3c6cac6afa43959fa349942aed4d2e618e85c2212d6f018cd509f9f3e61131e35afdcb22e7c8df82c29ce4d50f09322f0ce527f87ab0be3626d8fcccfb8e65e7c738e7bd5e91ea859c2804289476da7a0ca0b605ec7e4e5e90a1dcf7fa8b93a7b3b3018dca964828574062950ff4466b7fea160091ef5f11ff560077147f7a3fbb88181e88d03ff11987e92e0d516b4868d5b46c6278b3f8e60318d42bc9ebfbe3fa42e23b04e8d1c2e147810cad89213d9bb0245e0385af22e8cf8bc2d8503bb398367bcda2661c2a51f9c04e674ca3425806dd695826f68263f818a110240a834ed860f7b979fffaffd1772bbda4915cf6bcedb23e14a87775fae0db42cd6a53b4f22d30fac51e66ba527ab539385c8e8f479f5ab1400b61d159e96400ad845ac4e6c5fe9c1acf024bf1fe8618a4808b78e221d3c8e16c972b05613e9277e8376c3fd1492bee1a7309da98bd7b224858c0e794e4700cf26abf94de3aee0ccd9016671decf533efffe561af90aa81fc8b9e2fe3c1eef882da54e980b45d330591b509767f9d31d0875fcbe2f05a7f0f4ef10d6f74dc841c6df07b562ded9fd3b06d9d323de7d03b2a4f4ced4e9c489fa9d53c18b78b44ecff69044bfd45a88e215e6f91733f90fe9f494d7e6081831d9e8c5e43809eca25df8958bab7acab42c9557dd8604355737261a9cfd0ff908132fffe8a498fe018b6ed0346eedfaf28539ef70718543986f6b16a37130436814f016d7acbd210c16a85f873f4048f33792a34d810f7da502439186350bcf7eeaf4c21c311df7f26419bab31ea427f4ffc3b3e219b927e49a368519c4d1b484fb60376d2f22c5b7c60bf3669d0d1bd24b2be780af3674d8ce1adacc4ac13fe35deff7edef03e9febf5939860b53d16dd20ba982db8cc3f3c525e97b88b64db62010a0ece01cb51606d956f05d0c947a8551c32f66a5408a6922bdfd78150b5974e8f8baa00e4ed7fa736dd82989556abc3067c3634b7df3090a51d3f56d655f3061ec47a408621e7347f56a5494defa8fa14848e17602459db334fd4a465bd7074a225268037c704d704cbc6dd0d7ca51cac4ea0da575b4c49dcbdcc917cf48aea44a99cfa7d6cb6d751e16abced875c3c19091b52c27bb263c388059feb0d7c86c79dddde70c0349f5d96914ec4a8d093dffcdf9ec40787f5289177cb388d84c9956fcf1634ce5f592555b0bd2f2ef9f578999d4c3fb958a642d20d3112bf03a4e616dafbe195a5062aaa5551eeab8870838dc4744d98c407730dfc24cb233077003833916fa436a691bd24d0324ff5600270a843e3894a40147ddde6f67b101ef959015092b692a083f57c4b2637ccdeed0616b0522907c7dd40ce9e384dd9d1658abdd217a407ac100680e79239a5e317acfdae6488b627e2b0beb4116a84784d0befa320c56489a51011c75423cedd3f2edee33b877f6cc29d1c763df50c67fb05aea804b505491300c12d335dc9c7ec9b9572a73be3ea75e6f51dbf1d164b552dc77e704902b80a88651fef0c28838c358a1a6410753e3330976dfa7a03f45d257dc32e064421929b2494be3edcea51aa7fe6a1aa53146baf5fe04aebbbfab432c4d2fd41ce2e7145597466b5446c89cc87e9097d38da6b9045765675f3b71a60402a0b16372004cad8746cf63662fbbd9557bb7a1f4ccf053dcb08e3327bb80c948de54be698c2d92390e31ce32c214236b7cc0336a449c2f477c79aaf5172ef81004965e27522c84c8414906dab1f0631493c6a519f0104474551fea8bfe6ed4b383d3f3da049c89434a5cd6cff618be29f543d8dd944a5713e3c5a2f7637f3268d153a5ae4d4ca662beb15914511ffb45240409da9a5781af99cb9132f345e65cc9e9891135dcaaf2141919a7e02fc8056e9b6a5f9aa7202e1c476893d31b29558e44bb0da028dad5918acb167d10bf8491f336e5ba24266dc4d0dc7f62045d8f669ded01e237a6f21f0143aa4cc0f1527d11498a93308612fd4466c50a6860dbdb60f0b321ffdac389227afcc7f0ed7c0883c19515cbae7d7877fe6cde6759d354e36c1051695d77bb39fe50967f2b92b20cc8ff1d65cc34d0583248c3b2fabc087e7ac8b598db53ab9dff687d8c286ac648780eef448ab219cace5087887e95bd3073f1f655c5f2c54665b4ab04c7d1bc86725a8f1f8ade3848da4f465e20e331f2bbfd2406accc7c08b7a79379112e8754f5df4d36a7ee4df3c69016a65263591df37c5afcd1603ca414ec2a53c6b6d2ec5e340545989f111152d670a286ea5dbec343192e3e4d6274d85d3ed0f76c0782575efbd27ce7258a99cc7d1fb91a4291bb4637307cc1aad5dd75d9a445a7ac78de68d34ea060405e188474f4bca0cfbe9d013b416812810662ea0dc0c5f103dc4a98c7388f8e770cebbebe483454afc16cd1f33aa035268cfae6e194eb05e2a2eeda1ea2590f5362373e438c0b945e2c9c12dd7440bc317e2147cb509b90359cd8f8dd40f923bfb255f5ad2b5f766e277edaa5edbb4f1d2674e05e3ede0db275ba491b5f76aa22991868e389e0490f6dd451257c4b0bf8ba9aa56ac6e90587d27d1bc809196610cd2b91cb173469f405a93719ceeb999d9d0c967ad5ce29daf64a0187a2585111939117dc8ad1c4a054c22b77c31491872cb4c81c464d93fe34f3e950d17e92400aac6055824469b85268a294056d4b0757a40e99ac68d199155e9b8d98d71c5c09be657fc7db0d4f0d375814a6b6359d66f2b41405842453d4832ff6621f35d139169c6b98cd8881acfc09632192793916aa49000e1fc0ddd2afcb67f82136d4c5da73a8796f5cc5182234cea4c02f67f37cae1cf0b814a5d7e28475f95f3141d700f34ec14a97eecd95709d1f3b7b9d330c46a34b0a8497e11d917b8122c9ef2fb06f7a00fcbe7b7d26606c6ac5ca1715452a233cdae387b5dbe2af3746ae7eb89aeb1114b309a457fc589f61f5682dd11450280375df5a254fcb747eb1c6aea3c5fe22ae85eed2b8c70accad04bd8b197370c05447663cc4a1f3790334011c3be743f821713fb59929286cb46a4f1b7a6edafa57864d2c050d63eff05aac73c14a03c3dd86c8fcead508cfea2796bbd67a</script>
<div class="hbe hbe-content">
<div class="hbe hbe-input hbe-input-xray">
<input class="hbe hbe-input-field hbe-input-field-xray" type="password" id="hbePass">
<label class="hbe hbe-input-label hbe-input-label-xray" for="hbePass">
<span class="hbe hbe-input-label-content hbe-input-label-content-xray">您好, 这里需要密码.</span>
</label>
<svg class="hbe hbe-graphic hbe-graphic-xray" width="300%" height="100%" viewBox="0 0 1200 60" preserveAspectRatio="none">
<path d="M0,56.5c0,0,298.666,0,399.333,0C448.336,56.5,513.994,46,597,46c77.327,0,135,10.5,200.999,10.5c95.996,0,402.001,0,402.001,0"></path>
<path d="M0,2.5c0,0,298.666,0,399.333,0C448.336,2.5,513.994,13,597,13c77.327,0,135-10.5,200.999-10.5c95.996,0,402.001,0,402.001,0"></path>
</svg>
</div>
</div>
</div>
<script data-pjax src="/lib/hbe.js"></script><link href="/css/hbe.style.css" rel="stylesheet" type="text/css">]]></content>
<categories>
<category>哲学</category>
</categories>
<tags>
<tag>思维系统</tag>
</tags>
</entry>
<entry>
<title>取差集工具类(高效率)</title>
<url>/posts/6c39f264/</url>
<content><![CDATA[<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span> ZHAI</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@date</span> 2021/11/15 11:12</span></span><br><span class="line"><span class="comment"> **/</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ListUtil</span> {</span><br><span class="line"></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">static</span> <T> List<T> <span class="title function_">removeAll</span><span class="params">(<span class="keyword">final</span> List<T> source, <span class="keyword">final</span> List<T> destination)</span> {</span><br><span class="line"></span><br><span class="line"> List<T> result = <span class="keyword">new</span> <span class="title class_">ArrayList</span><>();</span><br><span class="line"> Set<T> destinationSet = <span class="keyword">new</span> <span class="title class_">HashSet</span><T>(destination);</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">for</span>(T t : source) {</span><br><span class="line"> <span class="keyword">if</span> (!destinationSet.contains(t)) {</span><br><span class="line"> result.add(t);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> result;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>代码</category>
</categories>
<tags>
<tag>工具类</tag>
</tags>
</entry>
<entry>
<title>品诺王版卤味</title>
<url>/posts/7624ea2a/</url>
<content><![CDATA[<iframe src="//player.bilibili.com/player.html?aid=466087853&bvid=BV1mL411F71p&cid=496219239&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="600px"> </iframe>
<p>需要准备的食材</p>
<p>【主料】排骨、五花肉、鸡翅、鸡腿、猪耳朵、高汤12斤</p>
<p>【辅料】干辣椒3个、姜片、冰糖120克、豆油750克、红烧酱油、卤油、香料渣、白酒(少许)、糖色</p>
<p>【调味料】盐180克、鸡精30克</p>
<p>【卤油】八角5克、香叶2克、小茴香3克、桂皮3克、白胡椒3克、草果1个、肉蔻3个、白蔻2克、香砂2克、香苜蓿草1克、花椒4克、白芷2克、丁香1个、桂丁2克</p>
<p>1、<strong>准备食材</strong><code>00:19</code></p>
<p>①盐水中放入排骨、五花肉、鸡腿、鸡翅、猪耳朵浸泡1晚</p>
<p><strong>【注】夏天防止浸泡过程中食材变质,中途要换水</strong></p>
<p>②碗中放入洗净的香料<strong>〈如下图〉、</strong>姜片、干辣椒3个、冰糖120克</p>
<p><img src="/posts/7624ea2a/b1002fe9740bff6a3ea9e31d928ffc467e89a5dd.jpg" alt="img"></p>
<p>2、<strong>炒糖色</strong>+<strong>制作卤油</strong><code>01:19</code></p>
<p>〈1〉锅中放入冰糖炒至融化不停搅动锅底起沫成枣红色,顺着锅边加水即可</p>
<p><img src="/posts/7624ea2a/339e9eeff3a7de9726dfd511171c3bd69f7ba325.jpg" alt="img"></p>
<p>〈2〉锅中加入750克豆油,下入姜片、辣椒,加入香料开小火炒出香味,炒至香料微黄<strong>〈如下图〉</strong>捞出料渣</p>
<p><img src="/posts/7624ea2a/50f847327938fb5c5386947d392ee21c30d2f848.jpg" alt="img"></p>
<p>3、<strong>卤食材</strong><code>02:44</code></p>
<p>①锅中加入12斤高汤烧开,加入糖色、红烧酱油、卤油,把料渣装包,放入卤锅中</p>
<p>②防止粘锅,锅底放一个底篦子,下入排骨、五花肉,加入180克盐、30克鸡精、几颗冰糖、少许白酒,开中小火卤40分钟</p>
<p>③加入鸡翅、鸡腿、猪耳朵,防止食材浮起,压上一个重物,开小火再卤20分钟,关火浸泡60分钟捞出食材</p>
<p><img src="/posts/7624ea2a/0617973695fc94151e6ba0d2c2d652508c363be0.jpg" alt="img"></p>
]]></content>
<categories>
<category>美食</category>
</categories>
<tags>
<tag>肉</tag>
<tag>卤味</tag>
<tag>年夜饭</tag>
</tags>
</entry>
<entry>
<title>图片转 BASE64 编码</title>
<url>/posts/77673b17/</url>
<content><![CDATA[<h3 id="进入菜鸟工具-gt-图片转base64编码网站"><a href="#进入菜鸟工具-gt-图片转base64编码网站" class="headerlink" title="进入菜鸟工具>图片转base64编码网站"></a>进入菜鸟工具>图片转base64编码网站</h3><p><a href="https://c.runoob.com/front-end/59/">https://c.runoob.com/front-end/59/</a></p>
<p>拖拽图片至页面</p>
]]></content>
<categories>
<category>工具</category>
</categories>
<tags>
<tag>base64</tag>
</tags>
</entry>
<entry>
<title>多线程实现异步</title>
<url>/posts/91c508e3/</url>
<content><![CDATA[<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">class</span> <span class="title class_">MyExecutor</span> {</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 取得核心数量</span></span><br><span class="line"> <span class="keyword">final</span> <span class="type">int</span> <span class="variable">numberOfCores</span> <span class="operator">=</span> Runtime.getRuntime().availableProcessors();</span><br><span class="line"> <span class="comment">// 固定线程数量,</span></span><br><span class="line"> <span class="keyword">private</span> <span class="type">ExecutorService</span> <span class="variable">executor</span> <span class="operator">=</span> Executors.newFixedThreadPool(numberOfCores) ;</span><br><span class="line"></span><br><span class="line"> <span class="comment">//</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">fun</span><span class="params">()</span> <span class="keyword">throws</span> Exception {</span><br><span class="line"> executor.submit(<span class="keyword">new</span> <span class="title class_">Runnable</span>(){</span><br><span class="line"> <span class="meta">@Override</span> </span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">run</span><span class="params">()</span> { </span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="comment">//要执行的业务代码,我们这里没有写方法,可以让线程休息几秒进行测试 </span></span><br><span class="line"> Thread.sleep(<span class="number">10000</span>); </span><br><span class="line"> System.out.print(<span class="string">"睡够啦~"</span>); </span><br><span class="line"> }<span class="keyword">catch</span>(Exception e) { </span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">RuntimeException</span>(<span class="string">"报错啦!!"</span>); </span><br><span class="line"> } </span><br><span class="line"> } </span><br><span class="line"> }); </span><br><span class="line"> } </span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> {</span><br><span class="line"> <span class="type">MyExecutor</span> <span class="variable">myExecutor</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">MyExecutor</span>();</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"></span><br><span class="line"> myExecutor.fun();</span><br><span class="line"></span><br><span class="line"> System.out.println(<span class="string">"你先睡着,我先回家啦~"</span>);</span><br><span class="line"></span><br><span class="line"> }<span class="keyword">catch</span>(Exception e) {</span><br><span class="line"></span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">RuntimeException</span>(<span class="string">"业务程序报错啦!!"</span>);</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 经过ThreadPoolExecutor的相关API实时获取线程数量,排队任务数量,执行完成线程数量等信息。</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="type">ThreadPoolExecutor</span> <span class="variable">tpe</span> <span class="operator">=</span> ((ThreadPoolExecutor) executor);</span><br><span class="line"></span><br><span class="line"> <span class="comment">//查询线程情况</span></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="keyword">public</span> JSONObject <span class="title function_">findImplementation</span><span class="params">()</span> {</span><br><span class="line"> <span class="type">JSONObject</span> <span class="variable">jsonObject</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">JSONObject</span>();</span><br><span class="line"> jsonObject.put(<span class="string">"CPU核心线程数"</span>, numberOfCores);</span><br><span class="line"> jsonObject.put(<span class="string">"当前排队线程数"</span>, tpe.getQueue().size());</span><br><span class="line"> jsonObject.put(<span class="string">"当前活动线程数"</span>, tpe.getActiveCount());</span><br><span class="line"> jsonObject.put(<span class="string">"执行完成线程数"</span>, tpe.getCompletedTaskCount());</span><br><span class="line"> jsonObject.put(<span class="string">"总线程数"</span>, tpe.getTaskCount());</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>代码</category>
</categories>
<tags>
<tag>java</tag>
<tag>工具类</tag>
</tags>
</entry>
<entry>
<title>字节跳动CEO张一鸣2014年采访</title>
<url>/posts/f1a9ae87/</url>
<content><![CDATA[<iframe src="//player.bilibili.com/player.html?aid=1252080091&bvid=BV1uJ4m177s9&cid=1476923571&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="600px"> </iframe>
<h2 id="视频内容"><a href="#视频内容" class="headerlink" title="视频内容"></a>视频内容</h2><p> 在视频中可以看出张一鸣在这次采访中表达了他的创业经历以及公司文化,他表示连续四次的创业失败,并没有为第五次创业成功提供决定性因素,但是有强关联。</p>
<p> 管理方面认为应该招聘高端人才,认为对于自我要求度高的人,可以减少规则,提供员工高自由度,同时在企业内部提倡平等,上下级汇报时也是按照工作需要,避免形式禁锢内容。</p>
<p> 随着团队人员扩大,保证每个人的成长与效率提高,具体为在公司内部应该有高标准的工作观念,工作成果,有利于为高端人才做具有挑战的事,交付高标准结果,与优秀的人共事,参照别人标准,做的比别人更好,这样内部有更好的氛围,根据这个问题主持人问不怕这些人才自己去创业吗,张一鸣回答如果在工作时做得好能有很好的激励,满足了你的需求,那么他们就不一定会去创业,为什么要去创业呢。</p>
<p> 在当时团队做的今日头条APP,与其他APP差异的是:为用户私人定制推送内容,比如推送用户感兴趣的内容以及这个时间后续的最新消息、根据所在位置提供附近的景点娱乐等等…</p>
<p> 对于怎么融资,主要是做3个事情,第一你的方向是有未来的;第二是你这个人的可信程度+执行力;第三是能聚集一批有能力的人,有个好的团队做这个事情;满足这三点的同时产品还做得不错,投资人会主动找你。</p>
<p> 最后张一鸣表示得到了投资,要招更多好的人,购买更多的机器,研发更好的产品,有机会要拓展海外市场。</p>
<h2 id="思考"><a href="#思考" class="headerlink" title="思考"></a>思考</h2><p> 我认为环境决定人的行为,而在工作时,大部分时间都呆在办公室,有好的同事与好的氛围,会让所有人无意识的提升全方位能力,看待问题的角度,和思考解决的方式,提高员工对工作的认同感,所以自然的就对自己所做的内容感兴趣,从而每个人都去思考为什么这么做?怎么做?能带来什么样的成果?思考后动力更足,方向也更正确,就算失败了也可以当做积累结经验。</p>
]]></content>
<categories>
<category>互联网公司</category>
</categories>
<tags>
<tag>互联网</tag>
</tags>
</entry>
<entry>
<title>实体类集合转另一个实体类集合</title>
<url>/posts/c2569e69/</url>
<content><![CDATA[<h2 id="工具类代码"><a href="#工具类代码" class="headerlink" title="工具类代码"></a>工具类代码</h2><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> input 输入集合</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> clzz 输出集合类型</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> <E> 输入集合类型</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> <T> 输出集合类型</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span> 返回集合</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <E, T> List<T> <span class="title function_">convertList2List</span><span class="params">(List<E> input, Class<T> clzz)</span> {</span><br><span class="line"> List<T> output = Lists.newArrayList();</span><br><span class="line"> <span class="keyword">if</span> (CollectionUtils.isNotEmpty(input)) {</span><br><span class="line"> <span class="keyword">for</span> (E source : input) {</span><br><span class="line"> <span class="type">T</span> <span class="variable">target</span> <span class="operator">=</span> BeanUtils.instantiate(clzz);</span><br><span class="line"> BeanUtil.copyProperties(source, target);</span><br><span class="line"> output.add(target);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> output;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="使用"><a href="#使用" class="headerlink" title="使用"></a>使用</h2><figure class="highlight java"><table><tr><td class="code"><pre><span class="line">List<BroadcastRuleTableDTO> broadcastRuleTableDTOS = convertList2List(broadcastRuleDTOS, BroadcastRuleTableDTO.class);</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>代码</category>
</categories>
<tags>
<tag>java</tag>
<tag>工具类</tag>
</tags>
</entry>
<entry>
<title>实体集合分页类</title>
<url>/posts/c42bcc42/</url>
<content><![CDATA[<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> lombok.Data;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"><span class="keyword">import</span> java.util.stream.Collectors;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 实体集合分页类</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span> ZHAI <span class="doctag">@date</span> 2021/12/21 15:52</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@Data</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">PageUtil</span><T> {</span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 实体类列表</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> List<T> content;</span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 是否首页</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="type">boolean</span> first;</span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 是否尾页</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="type">boolean</span> last;</span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 总记录数</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> Integer totalElements;</span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 总页数</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> Integer totalPages;</span><br><span class="line"> Integer numberOfElements;</span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 每页记录数</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> Integer size;</span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 当前页</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> Integer number;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="keyword">public</span> String <span class="title function_">toString</span><span class="params">()</span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="string">"PageUtil{content="</span> + content + <span class="string">", first="</span> + first + <span class="string">", last="</span> + last + <span class="string">", totalElements="</span> + totalElements + <span class="string">", totalPages="</span> + totalPages + <span class="string">", numberOfElements="</span> + numberOfElements + <span class="string">", size="</span> + size + <span class="string">", number="</span> + number + <span class="string">'}'</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 实体集合分页方法</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> page 当前页数</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> size 每页数量</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> list 实体集合</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">pageUtil</span><span class="params">(Integer page, Integer size, List<T> list)</span> {</span><br><span class="line"> <span class="comment">//前端第一页传1,二计算时第一页为0,所以-1</span></span><br><span class="line"> page=page-<span class="number">1</span>;</span><br><span class="line"> List<T> list1 = list.stream().skip(page * size).limit(size).collect(Collectors.toList());</span><br><span class="line"> <span class="type">int</span> <span class="variable">length</span> <span class="operator">=</span> list.size();</span><br><span class="line"> <span class="built_in">this</span>.first = (page == <span class="number">0</span>);<span class="comment">/*是否第一页*/</span></span><br><span class="line"> <span class="built_in">this</span>.last = (page == (length - <span class="number">1</span>) / size);<span class="comment">/*是否最后一页*/</span></span><br><span class="line"> <span class="built_in">this</span>.totalPages = ((length - <span class="number">1</span>) / size + <span class="number">1</span>);<span class="comment">/*总页数*/</span></span><br><span class="line"> <span class="built_in">this</span>.totalElements = (length);<span class="comment">/*总elements*/</span></span><br><span class="line"> <span class="built_in">this</span>.size = (size);<span class="comment">/*每页多少elements*/</span></span><br><span class="line"> <span class="built_in">this</span>.content = (list1);<span class="comment">/*内容*/</span></span><br><span class="line"> <span class="built_in">this</span>.numberOfElements = (list1.size());<span class="comment">/*当前页elements*/</span></span><br><span class="line"> <span class="built_in">this</span>.number = (page+<span class="number">1</span>);<span class="comment">/*当前页数,第一页是0,所以+1*/</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>代码</category>
</categories>
<tags>
<tag>java</tag>
<tag>工具类</tag>
</tags>
</entry>
<entry>
<title>客户端外网ip工具类</title>
<url>/posts/4c3f96ac/</url>
<content><![CDATA[<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>:获取客户端外网ip 此方法要接入互联网才行,内网不行</span></span><br><span class="line"><span class="comment"> **/</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> String <span class="title function_">getPublicIp</span><span class="params">()</span> {</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="type">String</span> <span class="variable">path</span> <span class="operator">=</span> <span class="string">"http://www.net.cn/static/customercare/yourip.asp"</span>;<span class="comment">// 要获得html页面内容的地址(万网)</span></span><br><span class="line"> </span><br><span class="line"> <span class="type">URL</span> <span class="variable">url</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">URL</span>(path);<span class="comment">// 创建url对象</span></span><br><span class="line"> </span><br><span class="line"> <span class="type">HttpURLConnection</span> <span class="variable">conn</span> <span class="operator">=</span> (HttpURLConnection) url.openConnection();<span class="comment">// 打开连接</span></span><br><span class="line"> </span><br><span class="line"> conn.setRequestProperty(<span class="string">"contentType"</span>, <span class="string">"GBK"</span>); <span class="comment">// 设置url中文参数编码</span></span><br><span class="line"> </span><br><span class="line"> conn.setConnectTimeout(<span class="number">5</span> * <span class="number">1000</span>);<span class="comment">// 请求的时间</span></span><br><span class="line"> </span><br><span class="line"> conn.setRequestMethod(<span class="string">"GET"</span>);<span class="comment">// 请求方式</span></span><br><span class="line"> </span><br><span class="line"> <span class="type">InputStream</span> <span class="variable">inStream</span> <span class="operator">=</span> conn.getInputStream();</span><br><span class="line"> <span class="comment">// readLesoSysXML(inStream);</span></span><br><span class="line"> </span><br><span class="line"> <span class="type">BufferedReader</span> <span class="variable">in</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">BufferedReader</span>(<span class="keyword">new</span> <span class="title class_">InputStreamReader</span>(</span><br><span class="line"> inStream, <span class="string">"GBK"</span>));</span><br><span class="line"> <span class="type">StringBuilder</span> <span class="variable">buffer</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StringBuilder</span>();</span><br><span class="line"> String line;</span><br><span class="line"> <span class="comment">// 读取获取到内容的最后一行,写入</span></span><br><span class="line"> <span class="keyword">while</span> ((line = in.readLine()) != <span class="literal">null</span>) {</span><br><span class="line"> buffer.append(line);</span><br><span class="line"> }</span><br><span class="line"> List<String> ips = <span class="keyword">new</span> <span class="title class_">ArrayList</span><>();</span><br><span class="line"> </span><br><span class="line"> <span class="comment">//用正则表达式提取String字符串中的IP地址</span></span><br><span class="line"> String regEx=<span class="string">"((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)"</span>;</span><br><span class="line"> <span class="type">String</span> <span class="variable">str</span> <span class="operator">=</span> buffer.toString();</span><br><span class="line"> <span class="type">Pattern</span> <span class="variable">p</span> <span class="operator">=</span> Pattern.compile(regEx);</span><br><span class="line"> <span class="type">Matcher</span> <span class="variable">m</span> <span class="operator">=</span> p.matcher(str);</span><br><span class="line"> <span class="keyword">while</span> (m.find()) {</span><br><span class="line"> <span class="type">String</span> <span class="variable">result</span> <span class="operator">=</span> m.group();</span><br><span class="line"> ips.add(result);</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="comment">// 返回公网IP值</span></span><br><span class="line"> <span class="keyword">return</span> ips.get(<span class="number">0</span>);</span><br><span class="line"> </span><br><span class="line"> } <span class="keyword">catch</span> (Exception e) {</span><br><span class="line"> System.out.println(<span class="string">"获取公网IP连接超时"</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="string">""</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category>代码</category>
</categories>
<tags>
<tag>java</tag>
<tag>工具类</tag>
<tag>ip</tag>
</tags>
</entry>
<entry>
<title>家人们谁懂啊这也太可爱了吧!</title>
<url>/posts/439c6055/</url>
<content><![CDATA[<p>晒太阳猫</p>
<iframe src="https://player.bilibili.com/player.html?aid=260646365&bvid=BV1Ae411M7qv&cid=836145887&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="600px" style="font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, "PingFang SC", "Hiragino Sans GB", STHeiti, "Microsoft YaHei", "Microsoft JhengHei", "Source Han Sans SC", "Noto Sans CJK SC", "Source Han Sans CN", "Noto Sans SC", "Source Han Sans TC", "Noto Sans CJK TC", "WenQuanYi Micro Hei", SimSun, sans-serif; color: rgb(35, 57, 77); font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"></iframe>
<p>歪头猫</p>
<iframe src="https://player.bilibili.com/player.html?aid=303218579&bvid=BV1XP411H73p&cid=836144867&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="600px" style="font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, "PingFang SC", "Hiragino Sans GB", STHeiti, "Microsoft YaHei", "Microsoft JhengHei", "Source Han Sans SC", "Noto Sans CJK SC", "Source Han Sans CN", "Noto Sans SC", "Source Han Sans TC", "Noto Sans CJK TC", "WenQuanYi Micro Hei", SimSun, sans-serif; color: rgb(35, 57, 77); font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"></iframe>
<p>拖鞋猫</p>
<iframe src="https://player.bilibili.com/player.html?aid=216894004&bvid=BV1ia411P7JB&cid=801920171&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="600px" style="font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, "PingFang SC", "Hiragino Sans GB", STHeiti, "Microsoft YaHei", "Microsoft JhengHei", "Source Han Sans SC", "Noto Sans CJK SC", "Source Han Sans CN", "Noto Sans SC", "Source Han Sans TC", "Noto Sans CJK TC", "WenQuanYi Micro Hei", SimSun, sans-serif; color: rgb(35, 57, 77); font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"></iframe>
<p>窗台猫</p>
<iframe src="https://player.bilibili.com/player.html?aid=953434692&bvid=BV1ps4y1u7Wu&cid=1121805677&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="600px" style="font-family: inherit;"></iframe>
]]></content>
<categories>
<category>小猫咪</category>
</categories>
</entry>
<entry>
<title>使用流式数据处理检查list中是否有重复的元素并返回重复元素</title>
<url>/posts/ea92058c/</url>
<content><![CDATA[<h1 id="工具类-使用流式数据处理检查list中是否有重复的元素并返回重复元素"><a href="#工具类-使用流式数据处理检查list中是否有重复的元素并返回重复元素" class="headerlink" title="工具类-使用流式数据处理检查list中是否有重复的元素并返回重复元素"></a>工具类-使用流式数据处理检查list中是否有重复的元素并返回重复元素</h1><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <T> List<T> <span class="title function_">getDuplicateElements</span><span class="params">(Stream<T> stream)</span> {</span><br><span class="line"> <span class="keyword">return</span> stream</span><br><span class="line"> .collect(Collectors.toMap(e -> e, e -> <span class="number">1</span>, (a, b) -> a + b)) <span class="comment">// 获得元素出现频率的 Map,键为元素,值为元素出现的次数</span></span><br><span class="line"> .entrySet().stream() <span class="comment">// Set<Entry>转换为Stream<Entry></span></span><br><span class="line"> .filter(entry -> entry.getValue() > <span class="number">1</span>) <span class="comment">// 过滤出元素出现次数大于 1 的 entry</span></span><br><span class="line"> .map(entry -> entry.getKey()) <span class="comment">// 获得 entry 的键(重复元素)对应的 Stream</span></span><br><span class="line"> .collect(Collectors.toList()); <span class="comment">// 转化为 List</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>代码</category>
</categories>
<tags>
<tag>java</tag>
<tag>工具类</tag>
</tags>
</entry>
<entry>
<title>强势文化与弱势文化</title>
<url>/posts/d68051b9/</url>
<content><![CDATA[<div class="hbe hbe-container" id="hexo-blog-encrypt" data-wpm="抱歉, 这个密码看着不太对, 请再试试." data-whm="抱歉, 这个文章不能被校验, 不过您还是能看看解密后的内容.">
<script id="hbeData" type="hbeData" data-hmacdigest="8cfc80138ec235829ba57721ea62f34132222b1d693ce23dcbf644a5afa559ac">601b7ad76f4fbd60ff466c34909923e9c8f637ce8db723aeeebafec606bc5c12a7bc0d0cf3737c27f8b04ea83c7971af12b7c949f39a8dfc6af4195795832e2922dfa6e6a774b8cff48ec9be86969e22526a0a2375d3cc64b5f4254029629f20a5e88a751545df9f15097ecfe6c32328940f1f5f55e7afc338e564fc7ea5c7168c974e41c67afe6f29a12bcdf714fea1586f94c8ec82cd5957a19f6590f426ed89e795841e264fcfd25b53503e14a67cb4de4e68e4505392d132c7d61372fad7ad409e7d14043e82d1b98991251ff4566c9a7bc129d04e7c3c6c27ed8d2a1dab2bb8926f1c182c7415a8e1fd2d935cd029512c4868ac802d5535b82a6bb92159b995d2eaf9ee0595f4742c25b4266de0473fcbc4c6757df831675b47311a28e7d29854c369c58691f81341b3989edde52605df03459b8bec5484498f5a22e5079d3345767d59ae4219812fefcda94a574b22dbd2a89f9710ca7c4fcd1dbaaa12f915f24378e94fa35119ba1b1e7cbddc76c6ba2e52fa87c54e1ae0ab74661bee10ef5813839eda572cc13767594803fb68a4df2c3229507ea11bd878ba4ebbe16312a28750a9240e99fb4104be7db327350825fc3806021663290b4d602f3be0851a2d65bd7b1037abfc194361e70a76747e0583f0887ded63b993ee06044a36b81a69691baecd8c3a0bceb5fc1caf1788483ce76211136761e5570fced29a85435914893694f2bd746d1bc8f0dd0940e87d94ee0d4db2291154645ab7e8ae6febd99538039324e6e4341eebb8f0b15eb5a71b0a4f0e34c16e556b2d88e19ef7342457301576cd5623b03ca3d0a5f85293ae48ee9cf6b1fc02f5d024f5ec1eefbb09cf366f9fa9f8e692bd01b5b60fccadfb2ecd5121ad0225ddf5f1d8dd2f03a5d5a8e46600ce676aa04e3930071b8f10fb2faf0baaade556d398b3c05d1eda258b169460ec9971c399ac5d1009785b9bbf055d284916aa81cdbdaac1a45aa68dd7e62ca0f94ed3e4048765dcfa5c2763a77a8dff7ee25baead234075f014987d0687fb6f782a4b58917b9c4f7068d593eab0e16543304dd2be1f663c065c6ab4eeb443bedef406a1265d148733ce7140054087d01bfa15528a9bac0b0d930fea8bd4e506bd144709825d5517d7e37c2561249eb4ef82dd2dbbca6dbebfc4e8890dfba2f09e020d139cf866e716e0789d6beee07b55a11f317b651e1ba7266b7d7632647cb5946e6a5526fbe41255fd62344a7dd2bf5fc7f42231f1b11d00a38bbea11242f94be62cc88c0ca26d4f9676314cf28b49afa15f0a4c069f34103b40e5a5672ca30cb1ffcdc6d2c3dcad147932df29649a39a8a2925c51660e0586bb5fc53607ad7f0a7595d6163983e850114acb9bf5bd2f5b312b47490f23b042f1a3438b81b1ae9c5ed3d8366233c583024a6c0421afc1f412383b14e8404b2ee05ac92eab7070f51995ceb949b502acfb9d7dd139346ec640acb1c25a213259bfb6d29e3023a6f836f36d2e54828b3572166b9b9fe84cef8a8cce0263dc247fc4ba83433f1758f0fc2697f1978be13c663783cf5bd7f305d0ecc1b0789deacb0e323826922bebce649bb6256860feca69658dcd78d6e189495ef4ea702e9e2a7692f727abd431fc1a2f514507b5007cb6a8bb2354c61f77a1d57557062ec82b194cb80bfc34e89437634212f126fbdd0f7e93f2745991f22d638ef18a46beca23613d494b25a7e4f02be0ece9521bc9a081d737ac0559eb437e0a02de9ae3812570141c746910aa9f2985e92bb319b370327c67342fb53800321d43485bdb7e9d2c1653a9fe97cbbe960da20cca7ac5c0c9d4b2e4fd4e20581b282367bc9661d49d0bd9839bec15e9b0aa54c30235d9826818c929d397d3fd0c1d855d405b25bdc1fe32fd62a2606763afb2c802f28bdf13bf2526528b718ef777d9964b3ac4851db56be00a22aaaf1df106c173de2a5865c935a0c7729b3f3b627dedf6f4470042449807072e0b0c2999b0cf42d13ed7f41b3703023271a08b8706ff4d70f1265a25526280317ee8ce9155b0339f4c53fc9cdb05e38e76ff7eb42a8cca4c0dae16739aeb70e891b84efd736713f1c42ad9792a1070ec4df2ae5024a4e15b62db1ab97c653ecb56821edd537891cac95bf1e260a9380ae94db093d107cb6c43ed4dfd52e329ace3a4bd15e32383e574c22209eec4ff53e5807b8bc1116100a3ca51c6acd7432bdd6ea0af6d09d26fe775adde6bd3a283c7210397f869adc31f637ab58c8fd615d2725c1d176818910231509362f8762a12aaab7d77272143a693fd49a80b7144d322f1d9c7964a04cf5fb512f3ce2c43bfed38a58b995e9a758c3b04cd9a9f113d84796826c4b526a80cbcadd3b1ca49db3483d7edd38b5e0fdaa52cdb7af524cafe0b8d84d3ac3971c35891d9645b54230677dab12fac8ada1423dd48a97e353f22ee7434761a00fab79c9b96a3a207ad7bf913c146d09eff3426e1e69c3ccda20b426201462ecce77f8e1dc266afeeaf8bd58a1e0273947d939d3cb5508f3421ebef68715a454366c85fdc38fa3442a47a36bad41b6a853323ca7e2714725c4c9c65041b619331f2e34d18ad2889bb7ca1d1e3cedc0f8afcd97d9cf30fc0ff8abcfa27eae495be8348f983c2107f2d8378886c31c385fe2c2deae4c06bdfdde1396e7a12fe774b44deb1b9df016e43c62361becd2365fedeb28011e81241f7512b16a1aa8867851d6256488412723740fb03be9efbcb2c751a297c9fde2ca761b3dad201dd20df70e8db3d54096cb9f7f97f0b1a924ac2de8ba16d19534bc62b3418457251f42bbf6f24d9556ad9174254d74e0c0ff685c3b59c4f5bbbe3d291f3819c6571f20edbd49e466dd5b232df5a16eccf2db5720286ceebba5d87390c0ea010e06ead232da0719bc0320852753a4cc482c042640a8dfe45c66a5ea1ccf6984cf2001d7c54051ad7ed521e23789038042d7dd76466947b4825347cb0aa6c3029452e324a4cb0abfc8495e19c0471b53c977c07ac6210864b4cd5f37bb319e2c33e69674e1568e8d10e707390badae26cd325db94a1658f67b84be35e258bae6d45749c5157c2f2572f5b9cb2a7c668f5885ced5fd6f594fb9fbd0c8b3787e3876b9051e4fb7600366c764aa5b418f7575d4db045f553acde34262d66603653acf0fda202315409dcdabc7465aa89d7e4660c4aba1269aee398c27d967a9b3c7f593f34e17ee8e6ef096b57e85ec19c4aa77d4ad4d5c66e0784aceda0e12eb168a4f64c06e6d5d76f7f01b0944d829ddf4d637b48b8e708e429262175fec823db596f061fa97dbb456d90aa9dda7a70bded1b65b30df93b529cf8bbffcda8890bcaf041cf1f63e91b79df13c566ed55195cb3a0189779cea7de59f5d0dfa8b832fa8bffb65c99d7a7589e4feabd0d9e52feb6516d6e6f0deab94c4f0af8897fe5b1bc7a55754e9cf3ad96d42e7c59af2ab46f648ee628ebd819013a518145a61f25321625f8c97594cd3bbaa05d9d41c9cb74d647bc1221c64ae65dba104e2b0a77d14d8b95838f7da0739798759430f12f16016945bd655a41e8871286ca1b94fd746386a50d2ca780e859348fe61f3909c956fcba52b07e6ae5325c2f4ca5170542cfdf3cce3e8afa4c11a065a26c9ef35bbf1c9235b3374e9cc9c8bb8f3d72ecfdd7f043e95e9aa47f0ebb820967f169c52320985709248dca81bd77de98f9a37ba6416b0854b9c8eae39e0555adb1b2af1255ad3af5843ad4549de112ceac5a34f8bbab7f7540107babb79339abcff4be8116c0540e2775d7d3a6ccada84c4046b9037984bc8d379fbe927784f340dbf1a7051c9094e31084a895b871991fd1c97e3f1505125da81ee8e4c64fbf9bd0ca683d76ee9f4266d1fdf407d72dd2a446211ac44f61c366a6da8565502be71e533958d1e37bf7f3be433b3d7da623185ef8a6d1cbdc7f6b15b32ab212c56cf948216dd779990ec26cd40c660291215ae9d091a4712bff5e0f9b17ea011616b2bc2ae9e49284bb417f9ef7fabe71fdf1a955af8a07fc30cc41823d3389f0a1bfedf2fe07b64ac447b0b3a77bd610d73f0c45adc13e042617b7a57e7d3db5afa2bbf810246c33ad7ae91537e5babfe86d36363f64e88c7e3b44cf076df60dc63370082483318ccc351cbad0b5ab31d649757f62a21dfd55fbf4594317917af66dfb86b3ce1a8b3ddb7767e826c8baa66528d2ce1eb4c617443605c3497aa82961cee3867bb7c96dcc742ddd47b7248d67deeba78741c43ae828b5bbb5800309a6f37576111a4449affa7781a20e5a01d03fdcb12f266360280fc7fe42f7277e3ee6cfedd11e89721b51cb473d0d22a57669bba7e690299a0b7370b178d1797afd2d16f286f7bb45b79abe61f58a96eab96dd1657dfce33ea0ea1c3831067bbe719cb8e9b65fe73ed34c92bf727c0b506d2b6868046c71c3f66a0089a88d1cb9e050f3d17b282e021af4bb4124989803e6efc383811696c217d6ed7dcbb0b6bb28f095176e2debd2ba4ca640cbf48e46f7bca9052297128320fe8c6d042678ea5f73d86b8811456d31b0d9c5e34290533d4898cf73075b8e28834bf4c952436af4ccdebf0deb807b6f30fa61814fea5741a6f68c5212a43174e21391c8acdb91bce9a192c155f66358af652f468c3a0198f945a4221859b61b03836e572e3fe61aeb297a0ebdde737d04e778de996e927f422141ffed94751b2a1d0e3a5a47ab97476316f36351baa6d0e3b2cb19651ee1782c2d91cc6be1aef1864b2f497af0bea5488d582c10eb725fbedf1b2fb01a358676f46a6e9eec6afe4113f7ea66b5925276e8e41b7f30b719cc7f06b380704ccf5affd2696bd3426e4220cc823f333bc093e82133f82a6ebc3ae23008446d1f6146fad93814f22a54bb1fd2d9efd9df12fd42b7623fbb964cb1f807a68e8767d0c93a2b0765d37811411c130953efcf0e275d6cc7358733763b57761c12ab97cf5a5e0e65f2d7d202d6e070646181ec9952e145d3a87bdfc97cd8e6d5c14af2039f13aff35c2d112bf11efddf2cd0816be6edd82cadd9acce4fcc1370b803408c5c7bebb244e7d090d41f77157be36676ef9d476442619ba6b159802cb6d5bf686d933097e9fbd3b8640c6b5f5cf62e90b605825d243daa558c6096627bd954e2586c5d5eef25b831345fe9492ce2e399509daae69b6abd07419267e8b5f00aae33bd1827ab12bbcc3d50e5f3f47a60ba3bf246d39c7bee9ce688433c92d483d216796ede25c7290d30e48eb598ab90b3f2434f7f43986d09c1e5a4d4188197ce521cdbb428d1c7f115114ba4ed52a9889e0a85fc22674cbc0005dce18d06219aee8bca4c26c8ba547893c5aea1d6a440192c5c5794c650dc456bd8f4b5be2e2a93f4731a5399cf9119cd22b80fc07108a1e43bfce9599177b9fba653507005e51e33518c8f5fab25d4cbb2ddf13371c14f319a8161bd6b38684f21ebb0ca31269fd95793a1f9e781078500ed95523485226d3e5efff68d10970f9ac0762c2c75ced23feee84d6462b7437140650a2687cb32624b2f7ff727d2d1fe4d27b6d168a6ec4df08a48ee099fb320a5d1fe302a811ae72a8bdb5b7d02df6a3596dac4e14a2d5baa55f37844092fda07a87835503b3694cca0794dd009412c18c7143678fb50194907c97f4af9131327882047d92342b9a5b11a9db6788f98e02683a3256ded0ffaa931086f258953660ac99795fba3cad30ff9e52018b8aa67e0cbba961795267023b1f16406b0fa08946e32a01dc6213ac6315c1009ab803de205a151ef4d278c8163037611248ad192b04e2829466767d126ec484127ed50ed5951307066fb1fd34ed7d83d1e75d1dd58e483baca57666f90b173411bdfe9b71e20738639938ab1326ee0146cf85e4157715afb97e5f9551ce12d2f1a20f51ffcee7af937d007d90e4a1205b7bd1e3e39512285a34c4ebf669cae42fcedf163df08a8abe86d4051fa01c3b3ed0e06718befe597420d52af93eaa3c18b58b5b23e694e7c2a3bded1e78c513de2899104b7a532a7907fb6d4b38b6946d615c219971dd5b3a8c7ae4d61a8d6d1afbd04d63c80b6bec97d62314cecd16362872506a01f4dc16d9333f0d0d6fc014a29ff8a61598493aa5a64ce22beabc064469db10733000072e8c9fb2cd9de098cb9cfad6ade1981c600ad336df5ab7dc725f593068680fe8dcd4233a26fdcbcee4b07bc5187d0025bcdf51f60c069bc003467bafa599af724c0fed8a45a6fcd651e9d03479903bd7d1237e37f85f5912d6d46b75c13cea95da8a9b177ac756c672d9227b529d168c3e95af7cbc1a30ff2d0396fb4ed51dfd862f6e4d9a2e807e1261fc48924c4b0b9e4e28c79416ec66754c3af0ea2a61fe5fc21d4bb2a600864bbbd6cb738a396b94f539c390f4b0e61f4998fb78906526a07c60d1a238b7831c0f7cacb5e938d8475647c89e7805ef25b84a6384f43272ae8354d7a4c757ab190f34dfaed0887d71ed264ccd12997871247215758ba8baec245b4d4926f3722e03b64484e1e1196f92e584a49ed077e8fc5176f5eeace6b361cb4c97a7377dfc583139b6fc6c11e8639c4337aff231d6bf5b2c04981c259e40af36e8a6f429be1a567bcc51b604dd6360c2981dbc2973b21cd53f825016ddf70acec340ffd840eda3edc62608b246e31025a27816b11a47dfea62a2127df9d272802f8baaa6a60df348f9d210156db7171f929a502e6562ff94ba15f48184d9022dbf4002f0b691cc837c7af97e52b0bca35636c5eb20fca7cd17a0e13565a56934bffe8e642e82114a9480b4dc0f8834191f5ab22bd6d01bd2d6b6fdd2ef3c9cf12967eed15ca6d10734b7df8b026231d13edf17f63ca4775cecdd314841fe1d0f19e52c71775cd896be45a4a71686557973c60c0d4ea0ebeb63a9e3caa583c8c490af84ead96aa3366029b3b89d149a03bc65f7e734c31c575b6a50b020ab6dbdc730949f939e7e9b52f5e178a6f3d7955445ec32341859650f7e9afd2211d91498165ae9a43efbd7fe58880399efd1d8ca95d31368c4e0c629a0668eed4e770f98a0e23bc7ef099562f49e22eae10e9a2be632e5990896e54075e8430ca2ed1b79dca4cdd48a3e8984b660a45bc80472c490c7d14e7a547774d2f5bc8a562ab1e1e52a62edf2a506cdea8f5fa96f68703cbd9c6d7233eea9bb80c752f1264160f6731a0fcc863c62d8f2394851bd218ceb94557ee7f5a2e2a0f4b55318aa1f6f6aabac44c052d17cc22afe33d9090ded337776712f9fbdb8592fb54103e5254fbc8b25101fec21987902c44f0bc399ed5d6bac097a7428c62a3b3650adbae4119f58e1820e54d38855ed8ad21bd363f63f0e2cd62d47f1146153e9a1993827bcc29ad00ad427fdca8de9683a4dd973b19f1db528f4e163344920ada38377e398dbaba8c505e7917ce14f865c60cabe3f50c0f53f9463aea84680d5af3abbcb623c2eca610536975da373d13622d265d9553ff2a150a6b0f66d464cf9114c9c78962a9e81c72785ba24c021ddb7679eb2ab5953cc05735dd4a8b481ca3b05d5a0e0ac4b3484bdab43b291cc330c77a7a15618c0e5aa7330f412eee067e0f60527b44467a0f460b7828475f9d75d345c4c7490014bbf0b25c918a166517548501e1e2c92516f98f24a83139ab631f995f33c89fa65d59f20019f9f662917e0b11790a442f70737f3848f8c12c137a0f4def5a019a8d6154e25fe92155167805272daff4579e819ed6ab4ccb071e522e9d03d7471b3a4523a264c92cbc9b65068836595d24e672a540331e6a895c945cdd580516b7c9ea83e4b307c84171774136c0cb6da70ba1cc8dc3960012ac0ab42d669887287f88a8f108366d0fd6d6438f2a48c1bdc8947303b6a070803dcec332a5754aa423db75c562c51f6569eab8f3cf924a7ee4d6130991e92a9c69bfce7085805bce1bd98abadc2c811d38e4971666f344d8b120ea15d555b04c2f7430b5bfd2896d6ccad908d0c8aac20a7bb3ef75ce5ae97c54e8f10238b9d98b55af967adb36eaa4424221e0613e1548421fa6e936959fc1a49b73e21a0831e22167406990c5391701f5e587cc49ad9320525a667c247c51854afd47f70e9129acaf917f5ca45bf4f18cce553619c9b436f7b0baa0f6d14f794b412a462949375991f490891a9490ed5d68434363eef665b3fa3883ba69014211f2cf2f9e580e1be80b328a7001e6a6fa6e31f32ad4870eea19626f0a049aace22f32fb4a6e4a396d6d3d36e6117a0605d7820717817150109a0fe3b472d8e4c0f494a0a2cef1c5c06775ca40f2d4adff5f90df19177a498caa682bc0f3b7f63d8f6c567bb9fdd1d9e7a386d8f028ccd1d3089bdf77d819e32c367cef9e2a9dff6aba530e3557c3d107fce18c01a62b2b2921fba28dad0d4c6a26199869414872c908e1c3d47922689dfda3fa6b9dd87b4d976dcfc908d4f0236b24183893351e9d8ce8ee3102828098b87e44ff97916b58c2cacb8c4b63d9350a7260b66521601180243f7d9a574a94e91b1b911d9ca8ce668e15a601cd8ed2b63557fa1daff3e4e71effa09722093402c8262da8233465c439d9481ba624cb4259073db5f2578716a18018f89bcecec376792de49242a637b8fdf42cd63c42f82dfbfdac57b197570150dfb48c903d0507cf6ae7de0cbe59ab9bb69674e8933f86d5f1882243055f762d0406a3874b71bcc7bbd055126cdc5fda4189ad927f8187025a626f8902108e2c49ef63d0f7513660a883b9e2a968b8b20a8f60f8f224bc3f1f7780b256a5c7fcff3b082a8368250668088d5398d2ec6b29de5aaa22547d37e9ba6fc507ec8842c3070d672c3b6d70e1e59d97f6e8547fc3746cdb28b3a5b9da570bc01203d599786a06079d09fdce152ad8e47e5d56891df6d3cb330d90f69dc6c5a4d9ba46dc71f029bc4eafdb8c86a8aa5abc890e6adc717fa09a0f5d292abfe6817bcda3459f27cee38cde2d8797ee4df442bad4a44dd864733b6785fa5f9e5ad63d9d807c54d3a6a19070c6a1fae7977464f2bdb337f895b4082afef75d0b19d43072708b1a0a63d1fd06f25ea0bfbe81c97606e4b5fa7aee998db55c6c7430b116b6292b005dfa563d281ee132beecf636d6f9de920b9045e8af4237610f3f2b33fc2563053a63e0d990c047b1d41960ba2da963516fd3a598f49b6528f2fa312fd109e2c44887e9431521c6cc0e35f3ca671d28b604310597bb864753b664cd26f1f3c95704e4dc36239ac14cc66139b2b14f77d1c808596be398a8b6aaed89cd2b852c909b745dc668b9bb9ca355503edf57b33a003be67de54834ef37e1ef5cfc7ed77dad458517069b95f08df8886d5534ad549ddc1c6606c0ac814510ec97be66111abae2a0c94e96c57e14eaeddf704c4a420c3a07851b530e4e437998d903e49c78b129d0f7c874a20834c60e34a9375661dd73f83f0cfd2ba9c1b7d3463471aef366120385adf7cf39e60599d705b6ba80f1a32ee784fb46ac32ce5a5752145e361fe9f21a98b7e97a863dd1f33554cfe7c19b5a4ffe746622aee70f16e53147be105bab094f27b18f0150464add1a8b67c47a7b83179d3d92a19076ea5172e26b720c08f32fb2f937bfe66abbb719ed9b92113e5c23942a6073310005da4a8afb1c6bb8bb2050712a43c45ccc87ece497f6f5c89d716784880c464b72450b8fb40d2272992c16738ac86d27743a713dcc6ede20b2263d89085bebea2a84bdf34e339fa9c727a47f9f438583d46fdb9ab108df039064f95f7ae7802035eedb98a421f83f5f60a51005167857e65b6ed78048bbddf8e644c40c604a14c17796b88d30c99a989da1d9a589ccc5620e8c849f2081e6c8a90a95e6dd802f41e1167ff00632f0ddc1ce1e0ef39d805dcec89f51a6ed88cdf6110a9a30b85c503a99b2f8e70edf49f2cda87b4a260fb2bcd59ae98043d31005601b04c04e147dec33fc7650f3d9f5d83dd19bc12c3d4826575dd9738db132543134ae6d83edcea764992c256f9408308e15dc825b50896617bc85d0bf4e9e30aad3aaeeb4face163b9de3470e2da25c10a5397b8cae01a2cdfb97fdbc9be1de75fe0f9d41feb4dc1dd105a104069ff72365879d4a3c63e6fbec2ec7b99878bfe1fea3409f150e44c4601feaa1396edcce060ee5a1341fad320ce3330cbfd7bb3da7304b6a7a109382a286ae453787046346c1f58ff395473b10922fe6d4d1bcfeb4904fda0bc62fdbb1a93c0c2d335abafce5edfffea0c9d3cb1f9275a6055aca98fba2bf396d66612b7a561e93cac41dec3b05fb20f4ce4fb77b7a5a2aae6a3fead33a8badfd6c5fcad5b773fc563637919dee6306413424ce766b806415117ffd96d3365f0de64057406dd318940da12b175474011986ac4be9ba6bda619447000a706e4588aaa2017eac60f2bf4189a9af6882555fce51f3a5947b2b9d7301e4bb3f44e80d5bfa2228758c10e060fba733c366d3602aa2380721839f8e165bd8e0ab2dd8325a9227f288dd7a63faab1c4139e50e9ea4a4601a93b6b23f59e6f95520416fd452f8d22474041d14cb320233f5531a667f697411e462235bed146da2b2a7d188f81556adedf0e117068fb8f11b49917a5d28caecc0720c344a9dede2139c0e96a585d2ceb7dcc7cec30e9adba36246e091c2b11bd003beddcec2aa0943f34c4a507e56556a8735f379b60995e2f749d92332deed1c08a4309ab3114d35ae0421cce80fb22130c547f9b5a88f03bb57fb0568a66ce8bb0d6d8884a954951497c9492465d07ca6003b142f8e3b2779f1486cb8cd0c9f4dad959ea4f2a43a5f6f5ef72dd42753a2756a5e0cab6d6ae20ca40453e19451f9a67f8b1f931d7199a2ab74848362ae19dabe0acf621483d8c33dedeb01431bcbc2d63d8a7cf40ce43042f3f092e88a1c5a9d216a2d4804c836599b4c7fd6259e96087c2505388f5619ec10993cc31eb6957ec13c48c127f653cd5f804bef457c4c87b75bcda0897e57b3150bb3c9b05378d1a30d61081feb6dd81940a1a01d2211a6b4eb71e858f17f72e3ceeac2d7db51c43e342022b4bd8ebacff106f3706706a6aef8ec09e81f66761b00fddd6d511802a29aab2deb711275ccd8cf59dc039bbb0c1382b6e7549836d21a7ad146cbb2978f910153ef18a276a7ae34531a8e5319272963cb2a8761e94aa5715dc85f3f83ef9f28ce8ae362e0d3c99de0f261574feeb108a877bb3ff7f0cb2db055f74e29b75fa1b0a655e34d0539a07dd7734890de8003ede5c92fc662df8b29942ee690612bd24603bdca7a6804eabde4559fc71f886ba1578e44ab2cd9103c3f6133415a609589c37021a343ed2fe020679848a4ca02ec32f4b04c5bc2d4e7d2d2e02b8a8585d0ebcf826cfdf3a9e9e0eee90784c70eed0fcc5aa04b625ea227b03fc70ac61bdb779370d125b7700cc549dd1b40340791d9cc86a99d15214fb130afd67f6296cd0b8ffe82357efd792d3ee6b15a88a15553276ccbd1b34e461fdc2e9362ea671ad59968b332bf738a671a8271297e3ad01af41bd9a33d906bde5ba192ed6010e525757dd24c096293d4b6d2b8c73fa4b17a33c22bcc788d0884bd9b213413bd22388d891ff5ee0f96aa5af5c2ddb38de6ae91a90ac2838c72c2469d59f3465dcc33bbe6c407c2a9898c21ff0667d9a21e9898ec1dc6b9f1782c53626edfe02c0f2714405473e9a6cec63e79b2850cd6126ddaf7a2a1f5db976c3317bdbddab43bdc110fff49a2b12a1b962f74736ecbb0347b8dffa86177d4a44cceae0bf7d72ffe697d3d73a6a3b43ab2b6b99fbb7faba20ac213cd225790eb1dedec7e21a7d9f76ae77bbebb5469e862758996243aee3d9526e844b4667f5b3a87e53a1ade02deb321a5e539ac6c46654edcaf001d4325f74b30c099bab1c41ae4880006b1b00b78f6a7dd62d6538f5b0928dfb6265156292ecfe41dbe33436a3a6f8a60d736a17c2cd68a1ab982edd24c99716affcd369cc65da706f7b7403ec3052e42b9ae39542f112c4c2c61d84f89a9f457b30fff0798524bbfed7a565f702098e467425fc63b1e4b6f79059d4597b6f792e4c6ff88f6b7b4a995aad6cb620d085a4fbed848062dc49aaf3d5abcd98685a37eb0f2cf925acff7164e791dfd8b2e76db7b5a9d2ed219183e84ed5f5a4a74639943f90dc2d51b95bab097438baa009aa63dcb0ea9ea624715595991f020053fb428f5911ba267860f15a95e1a683d171a57ece912c4981011e2cce4217a582fdf43ae917c67133a835d58f8e117c775c0eb4009a5b1d5ca1e8a88f7ae35ad6a226f97456c625543e2b50c10dbd8f7f8afd0bf0df76d1d79187c69fba7f8562786e5c1687873ae6f97b55d538904bacd3a259aa7852616650a1ca6253ddc15d0bc03cb6bef167edb6c99fb04c0a31c15ef6713986cd4739bb836f18fc949050bfc1234d217173f09b9d2fd23a0e4154278c28e253a4dc22a92c891fbaef9fb1b70645d71c2a0e85ea580a4cdbe598ad4c4b4d2e36231cb56b987de2b</script>
<div class="hbe hbe-content">
<div class="hbe hbe-input hbe-input-xray">
<input class="hbe hbe-input-field hbe-input-field-xray" type="password" id="hbePass">
<label class="hbe hbe-input-label hbe-input-label-xray" for="hbePass">
<span class="hbe hbe-input-label-content hbe-input-label-content-xray">您好, 这里需要密码.</span>
</label>
<svg class="hbe hbe-graphic hbe-graphic-xray" width="300%" height="100%" viewBox="0 0 1200 60" preserveAspectRatio="none">
<path d="M0,56.5c0,0,298.666,0,399.333,0C448.336,56.5,513.994,46,597,46c77.327,0,135,10.5,200.999,10.5c95.996,0,402.001,0,402.001,0"></path>
<path d="M0,2.5c0,0,298.666,0,399.333,0C448.336,2.5,513.994,13,597,13c77.327,0,135-10.5,200.999-10.5c95.996,0,402.001,0,402.001,0"></path>
</svg>
</div>
</div>
</div>
<script data-pjax src="/lib/hbe.js"></script><link href="/css/hbe.style.css" rel="stylesheet" type="text/css">]]></content>
<categories>
<category>哲学</category>
</categories>
<tags>
<tag>思维系统</tag>
<tag>强势文化</tag>
<tag>弱势文化</tag>
</tags>
</entry>
<entry>
<title>思维</title>
<url>/posts/e8831614/</url>
<content><![CDATA[<div class="hbe hbe-container" id="hexo-blog-encrypt" data-wpm="抱歉, 这个密码看着不太对, 请再试试." data-whm="抱歉, 这个文章不能被校验, 不过您还是能看看解密后的内容.">
<script id="hbeData" type="hbeData" data-hmacdigest="a7f07126945ef94c8681f09c8cd550f9e48eaa3dc2cb8e356efe26751cef3000">601b7ad76f4fbd60ff466c34909923e950b1935d7fcde4a9120557883c05daf6063e487bfba392b6d89d2e3ad14e101574dce9d216470eafcbb9ed6da1a31c037e9da3cc486ce335fd18f8fcd0fa78b0908f24465b653193eb11d81a1b0d830ddb4944b01a7bd0803953b1486013bd8a33e86f97b304896c1471012791deb1a94b6e911eecb90c13fe9ea25b299a1a7aba78c22af8e5b754f86615d73d44226ef97db5fe1b67bf731423300245bed03f629ecb83c7881564b596806c37b4bde8a820e8ea72d79965d84251830f486eaa41a15c51529fbd3a3a139ab7da493a002c783199022e9dab57e91145978bbcbc8b10b6149621bc89f654ce7c148ad0f13d2f9205e6df5f021d32bc1123e342d1d8b2ce9fc682ebbc8e10c60d6b2d72e14b646752488831d005df75798895ce6513cc90b5ad037df36a2b1beac0995e5ccdd0763b52d3337813b518ac4a83249fb7ac7e14d595f41859d38383d6430841a6127b54f71c6267029ee7d2da107b53e8ed939e68ffc7ab593af1b0209a0aee46cb58e0e1cfa6e9486a4b09409cd0d3a3e9c53ccf12df81c1018f39c869c5a577fc319c4c1d0457dfeca215658836658f5c744116e8ec308c863baad7e34509cd7b93761ca07d669f4b341712a02ac69f8b1ed864b1bde392edccdf5ecfa5457cd96e7285f40bcc308b6b519bdc9bd144fda71cc2210e516ef85023cbc6885326d3eca3d01e73e69e046ec7879f206f45adf8a01fc6252163f0c3a00ce00c85e38740c17d7c4d2481eb0c80042c39feffd79e22c357230879b104ce11b9fe53e4fa3bdcbe86c3f2ad9bbb499a9bbd80a5adc61743322fc431b6be2b1bda91f42482f093faa0500705adc045f9297c0c5905184ff26b5e341e65a25858e6f7dc7b161e9bc2f548487bad4cb19dc6bce744f9c59dff24247c9fdd35638414ff7d0c04a2c08a1a9eb56bfe2ebb5be2b670ddd785084f1708f1d74ce55a16f71c7b37be7446d63bb22467f97cbbfde4fc5f732d7eb25678c81743ba7f0a2f19fbb41466b94b14275aaa87ea0410e282469658c1ccab3e0e8024b9a4d10d2f75447277a0ce359a463839c9a3f94bf67ab506f2f8c3bacc35e101a90d42032078191b82c01a1c110a7217f1209a5db6b5f002d66e3ae1577c33f72100219dcd22b41eedaaa46631d87ef5c795cfc63303ed4626ea388b64a2bc20d78a3797d885af15cbf75c13d1916353cbbe8bafdaf34c0fb9db071ac4f31463733e9e171319f9f208000ec2b9773a4c9ac18777b650d54a3784c7193924df2b9ab2d592849eb650e6072dcfbfe91f300d88fd714ac150953c7e81916dfdb4affba11b8d01d1ef215d20d57d16672c3d9fb1b283b2f7caef7eb34728eee1a90585f8b8ac0e621c239a5336780390c430bcc99516ee7cbd9a1ad7a7ccf22e4050babadde337a4e112f1e564120ffbf4b4478ec3f1afbcf7b22c480a789f5bb24d98815c35d9a38a1edbbb3a72478584b4dd7dbf572db653bab18d1366f8354dfa7c06fbf638b399edd1048dc93ded159abec192ba6dd88ffa33c10a189918a0594e58c9bd09181b833dd6a5ace90d38afd0b0c0f9d2273b7a334ef18ca0da6f679b60c0a137d9658a8dbdd1c6d08f25020d9bb7e9514a295ac9a18e9c6a7c1988036dab1f0f674e72d7787f4c9ef4baaa603346e2e6454cc2647ed719912afd01659bb2021b58fa7c995f611b5ba2a43d7a53978b07d6be0814efd346ef4ddcfcbad863e1f1802f003691d23b00cdb192d82eec33ae77353aa59afd2731777402f379457de84471d292596f9fab095762e415e237f4fb788485e8cce5fdd74d013429259e57ccf64484575d4a3b01cb26cef2d33e016ebf47a896dc2fba0356b497567939eb2875fc1b36e01cb08f190340cb919b7af2e4ea234c8faa964668238ac14ba0c0b873690ce31271a86d265a9e5509c6ee58ae262c340799724aa7af06e1fccefd83b93f5b7ddc4d10b9ebb69352a00754380841dc5f35f3a3f7f143e8de7f7661da14970f8f5ad05bbed74133bd47205964738f6bfadae90ebabf1c35d151c7cef748f54bbef07a94e973645a3bda7ce9e5e9a83389257e9ce605d6333f6d799d690599ae3ee3add7f2d5fbec105960ecff35e4ad1419dc56e3b0defbf6626a4166ba6b0f71b89619b9c988fcaf40a71f518e771af0b5159c7a228205300ebc85f2edff62a0049b4913440911f3c096b5c013f7c982d9de973d62d90abf3d0167734495a685212a6cfd307b6a6491bb217945dc1fa0037d9354d325e79023c1411bfcfc210f1c6e2ac8cb638dbdb655c204e4687b51c9fed3818b2b0656a2d21bfbb803778440be415c86c793200eb89d0c069a73297a8d7e6a6150c0d88a2ffa58ebc5e7efac07325d2df194e0de1611415ff1730b1eaaf6ed84727cdc9c8e34672db29b58d4ba4d469777a7da297b05d04a432f2d4b8e5d68cfa187ac5420531f88f849da9272d4ac34da3d96d156b4f42009213924e45f444fdc22cae7467f46a60a2eedb212a04530382c24b36691d0b584eb9c68068cf2709966c12992f9e80e3bda2e5d9e6ae4cc8e9dbd687fe3c28991e468dafa7519d52f97e5103cb55e32eccfd8363f41079f5b25e1253c696de1dc4752773c758af173fdfdb102a268b97a95102b1c775bcf9cf31e9452002bb7e08656d5fb831a58b81cc37cf1f117bb33d4aeb2030562a34c8b58ad116b5814f77b9cdafad7b88048d6dd952630472f1bf6627147bf452cf4e19f93cd4b9006e026ceb5911a6b40d6c0a296cef5a75bacf6073fc81afef07391dfefb8f5069376c83610260a6b33f943abbc6ddd9faf0e01ecaca37a4dff4dd1801d5daa13acbdb5a33253ac8acc13f08af2f5721e545c6315331eacfa67147cf21c03d7d60d25b5b04d5e06c7814639d31e84a9d16ae9628050b3e61a10954ee59c36e417ecc5e19cf4322706a5b695c8c54bc8ebfb2ece723fdffd511182c83da81f5288ffcf329222ff4f66892a0bd94b12dcaa31fbc25f9987f1cb98c3a6940cc843f67740c63d36ad047774c28f5d0f5d8a6df839dcdaf621d5f11b7b9d469d76544447c75d794ccf4424e078e6a6c394629d71e2dba5add24b81e56a51c2af910e853213415f49f16fc5c3a30108ce043202df6ea2479d76c5efaa1f94fcb30626f6869bb8b7bd3ee1f7586bb5692e608dd6817c44ad9b8546f5a1094ee4801333f3a5bd7d046eab0bb43e0a565ffc0e6fbe6c60570a5fd39e208622616a8d313d7d66846dc9ba00f8ea70c3d735cf18cc9673fc7ae1073253d2f7093a606a898d532fd262a1744e3f2a0bfcc344105cbf3503dbf1463f2cd70502e3ef7c0a3ca99953e91ecca3506ed55184c62b176d8c712d37aff4a80d64c6c578787686299499841caae61eafa66bf38c99c28187e9f54b8b9546e8f0a4e9f6d307e1c62484629babf985a6b0f22f98af1231cbf1da8239ff350fb8e3156515b1e67186fc3c4639b7e29338028aedcad77b8e449d1e56b9e1ac10e103ce673ce54fc4027cebe34760c485791814838789ed7023eda295f176ed0e865d6404425148c9f4a825e60d1c438852f7c48e77e6ee03e7db6a3012dce00305792199000333f9231893baea981db5f92a59b55c555877f00273a5d7ac42fa3f40aa4365b0d42d35db5590b00dbe39401292f124702783d1a8a8bb98b4b383e1507f523374405a1791ef10fe4c5ca05354c6d3a514525c7785ac94b4172abdd5b12a8c10e64329e898ca62d5f5d1d43eef2f744c3ddc5207092a5493f2b4667c4823b49b004683c0ccb48bef5ff0d8a15d35cc1aff16ec2b063cd5bebcc09756a939fbcf0df8cd0835efe6313324095fd5b63d4a990f7ed0cb187817311e3edb8fe8fc7cd9037e8c886a9905b25e7e8b83da02453d6ce7db9c6914cc9827cd6ba9dde17071e3a743d77f455d1f2407f211f2093d0b28ed92f0f22328cc4bdeb4bdc25a1d3a498e679382f0fb54cadf046dcc36995ec6e3d782af8bf1c9e02b96db79b9e874f66ddb57dd1431af144e08f205fcf45319c9d064aa0a3b0e491b5aeb1845890e1fd3005fd09a91c709409fc00f085085a207748c0c52f6f2015472195f100ab1594f9ea7a812f99161590badaf24a5d2318900f1831c98c84747b1c806be7b8364ec244f15a7116296039fd8b4131c85b46cb38e58fa6461425bec6d0ec881ebc02d40f35c6d439a387b3e7a03848a1b7c3f1ae0d7c9000f99a0f82812d0486e87f34b0df639aa9fa7ad32e98f4de2af7a899d1647e771048ce432f9aa06aedecff49944c58ad33f62b3d5f57f2da6614e62550f9b1069431ae29f1a956a640b3c0895731f11fed77225d1b2906c757a952dba7453750cc9e8a5c65c01b647349986084283a2de18139abd9cd79a3b367db2af2164dae8f70fed0d07ba84d7d3e479c927868106e20377f4b15a44a863a3a808a1cf7c5590157b97645737dda078031e523b05771330ac0b02d42ba0897a543ae92df672942b92a483fc4c2f66caad1e2de0e808925364803d77cd6c24c4199dad220b1376f97e2f1198ca0c383ebca76f24bb39f8c384ddec1a9f5f4bd5c058c4d0f4e6c7af2556a26a6e25376965f257bfa1016ce62fe8494093a41fb366fbd410682d78ee74611d4af2a25aeecc373549bb8a35561c77cf3aabfe74fe5862c90e9fd8a7c3e6f8ce315b91505130f2ba3ac5094a01c818a0c3e3bcc67b9f5e78240a2dd28de6bcdd473292f63cf9f5bf19007bda63a6add6f0cb9ce506b601a5f14ef9a5211a6742c624d02b009c975ecea5df3e1cd84f1dbc048c093d5e08ad726faf0bc096295afccea41a39d220b6d9e7ffaabd2acdab9841bab63958ba952e46135399ad888189d010153d78b5adfa03e7505ca07284a1d1ac17a4965e3359d7bfafb96cbc70c6b12c53ac7c59af129f5d0eb16a340032fa33cbcecb208aac27966c8f671b013bfcc30b2f757a787ae40fa5be4926576e7b2b3940f5e9516dbfb6afd89baf9d6c3ff6cc11526295f9bb98e0770b712e31aaa86f04f5ac5eb772d367812755da1125732dc4a159f29d67e876d4413e101a20f00b387f2336704374b93bfa922cf7168bb0b1f0780163b0643f6667d6e644323ddef5104ea27c371a1f3a1e530877fa9cb56616987c831fdeebd2d52ff0bb3f5d9b1f040b40a1962f7a86f2fc450adc0516ddf5bac0a73fd041d46fa90887413026fe6a9ec5739a733e98b1157dff4027c87eeac834df77eaa8d181775abd1d49aa9c047b87593e07f1a124bcd87ea04c706efbf96d4be6c6640d6dec8fa19b3f7eba6040931fab7bb3cca508664b0115f6619a694be49be6064e064f6015f3c29b98426f609cda70ad36e30c2dcbe56379692f6c9c6b32bc03d6a147d6156e247573e04db426768d8d055cd1885520afccd814003ec88e924a1d0bddb3455dbe464a43f14533116f07ff93d99e6998e596c6962fb16256ee08fba7d56f859b3625aeb075a8a494d347a55cb432a7a17713982d48e27030f7df4de3431f16379f6ce11dd43ba14721b1524f3f5bd1310e08d1898ac86a81a5474b46fe84e74314b1d327c823f3dd705a92d2e9fd6b45161719de4f9f5653b143c6e52fcfe8de8bcfd31b0d4de1a44d32d510a47d09ccdbcb6cd6fcc05ec6349f369a9a3555db9b0d6ab19bd5baf7c871fe7c3385631a4496d75ec09608ce40bd1c86a627cb005d86f53ffbc8896d0db478761f326ee37888a784d2d3d5b4595dedb223c10635a26cd7f227b2b3342f16a534a5c8c86dd834dcfbdea372de20c5384e0bbfb5b6ba85e8d7a7b8047c62ecd72a318e50bf4d8f4a3b8658bbca46e89ddeb3e6ba637c8f94001c6e7230dd4b65546a02207ec3915973766e57b17ac387c8e42fef1a44be036765851678e24ee49051333308fdc8cabf8b9da68a4fe751991478c61bb41ece8e244576e5a1135ac3de30a49b157a2a8489b466e55e83ecdc15af5089282e43b3c06f7ff96fa204353d0d7e72bcfd42f3b44f7837591f323f1d6628e56208b23a4bd8e2bb186bbac99fc3840d5c8ca4ab99864f926bd33123565eb4ddc7992bf56880971b06e08cc74922d4589384b2d867a5f590b194d3b0d7e802193c17aadd4947ba98eca62f80e026b16a96ffaad40eb33d9ea18e1ba5f375fe4aca3a0ff1a8ce8fc8ff1a6a3e7a649238cd1b4ad983a041a8cc1f2247ebb530febc1ce198eee5b53af273da906c5b6ce54537deff9a750137fcb8ec91e73ea63fada29a82af903cc794133af43aa63cdb9b44ec7338140c9d9c42e6dfca45877edbd10099dd1af3063b21c4a032dca248d71bc366e9c00580295672c001db0694d198620ddf9664506cfbcbba37223566dbc1411ef0df440eadf53d3f8ea962f9b12dba3df25f456b8486090ce533aeb5a9bc9a7c59655b257f8084d2482999cdec75094801e63ee61cbcd4168fa0ce60617b976b3bd73a282e1ef8a83e5270cd49f3ef019b03922b06c27354b37ecfe4e121b3a3bf516eba2644c9422f4a009c015a4ed5c7aeaa424147ffeeeba1ac320ecd1265358fdf01b7476a290fb1f97d568475db8c47a84a3e57251c1767f1895556c8444a6ab639ce3d56234ad1a07225ca78ed4f2b14f67416de60866210b0f59229a31dd93dc846632660a19602ea8108b33da11c4258690c53dbb86ca80a97b8415011fe0bec555f46d6987ed8f33d9234297ad3ace98df585b536d64941be91135d0706a137697b55b318a7a7232f82820d4838596e22d6c8eff0c62229feb2b4959c1d497ae6535e37ccd96326d5a96abb72d5fc491ed5ce2f60e818ad1630cdb71b545e56aab7</script>
<div class="hbe hbe-content">
<div class="hbe hbe-input hbe-input-xray">
<input class="hbe hbe-input-field hbe-input-field-xray" type="password" id="hbePass">
<label class="hbe hbe-input-label hbe-input-label-xray" for="hbePass">
<span class="hbe hbe-input-label-content hbe-input-label-content-xray">您好, 这里需要密码.</span>
</label>
<svg class="hbe hbe-graphic hbe-graphic-xray" width="300%" height="100%" viewBox="0 0 1200 60" preserveAspectRatio="none">
<path d="M0,56.5c0,0,298.666,0,399.333,0C448.336,56.5,513.994,46,597,46c77.327,0,135,10.5,200.999,10.5c95.996,0,402.001,0,402.001,0"></path>
<path d="M0,2.5c0,0,298.666,0,399.333,0C448.336,2.5,513.994,13,597,13c77.327,0,135-10.5,200.999-10.5c95.996,0,402.001,0,402.001,0"></path>
</svg>
</div>
</div>
</div>
<script data-pjax src="/lib/hbe.js"></script><link href="/css/hbe.style.css" rel="stylesheet" type="text/css">]]></content>
<categories>
<category>哲学</category>
</categories>
<tags>
<tag>思维系统</tag>
<tag>认知与实践</tag>
</tags>
</entry>
<entry>
<title>朱厘米师傅的绉纱馄饨教程</title>
<url>/posts/56cc41e2/</url>
<content><![CDATA[<iframe src="//player.bilibili.com/player.html?aid=73257610&bvid=BV12E411y7tT&cid=125307944&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="600px"> </iframe>
<h2 id="【绉纱馄饨】史上最精致、讲究的小馄炖!"><a href="#【绉纱馄饨】史上最精致、讲究的小馄炖!" class="headerlink" title="【绉纱馄饨】史上最精致、讲究的小馄炖!"></a>【绉纱馄饨】史上最精致、讲究的小馄炖!</h2><p>江南人吃东西特讲究,比如皮薄透馅的小馄饨,到了江浙一带就获得了一个雅到骨子里的名字:绉纱馄饨。绉纱是细薄带皱的丝织物,一流的手工绉纱馄饨皮,可以薄到透字,堪称中式面点一绝!今天国家一级面点师朱厘米教大家手工做绉纱馄饨,这种手作的美味,更充满爱的温度哦!</p>
<h2 id="绉纱馄饨的用料"><a href="#绉纱馄饨的用料" class="headerlink" title="绉纱馄饨的用料"></a>绉纱馄饨的用料</h2><p><strong>皮胚:</strong><br>中筋面粉200克 、鸡蛋清50克、清水45克 、盐1克、小麦淀粉30克(撒手粉)</p>
<p><strong>馅心:</strong><br>南美对虾200克、夹心肉末150克、盐1克、白胡椒粉少许、麻油5克 、葱姜水20克</p>
<h2 id="绉纱馄饨的做法"><a href="#绉纱馄饨的做法" class="headerlink" title="绉纱馄饨的做法"></a>绉纱馄饨的做法</h2><table>
<thead>
<tr>
<th>示图</th>
<th>步骤</th>
</tr>
</thead>
<tbody><tr>
<td><img src="/posts/56cc41e2/200_1709cfa3657128973340242d80563ae0.jpeg" alt="【绉纱馄饨】史上最精致、讲究的小馄炖!的做法图解1"></td>
<td>①揉面:中筋面粉中加入盐、鸡蛋清,揉擦成团,盖好保鲜膜静置15分钟;</td>
</tr>
<tr>
<td><img src="/posts/56cc41e2/200_8cf3e9c7fc6435262e29c6aad8830a8e.png" alt="【绉纱馄饨】史上最精致、讲究的小馄炖!的做法图解2"></td>
<td>②拌馅:对虾仁改刀成小粒,肉末里加入盐、糖、白胡椒粉、葱姜水,搅打上劲,拌入虾仁粒,加芝麻油拌匀;</td>
</tr>
<tr>
<td><img src="/posts/56cc41e2/200_a62cce8cfab4f8e7cd976a5126ee48e6.jpeg" alt="【绉纱馄饨】史上最精致、讲究的小馄炖!的做法图解3"></td>
<td>③擀皮:桌面上撒小麦淀粉,将面团擀成长方形,卷起压开面团,反复多次,直到面团成为薄到透字;</td>
</tr>
<tr>
<td><img src="/posts/56cc41e2/200_e5d12ab6566f23f3046aa3f8465582e4.jpeg" alt="【绉纱馄饨】史上最精致、讲究的小馄炖!的做法图解4"></td>
<td>④切皮:将擀好的皮改刀成7乘7厘米的馄饨皮;</td>
</tr>
<tr>
<td><img src="/posts/56cc41e2/200_b3053b9e20dfa3a709c0619f4cae14e2.jpeg" alt="【绉纱馄饨】史上最精致、讲究的小馄炖!的做法图解5"></td>
<td>⑤包捏:手轻轻地打窝,加入7克左右的馅心,手指回拢包成小馄饨;</td>
</tr>
<tr>
<td><img src="/posts/56cc41e2/200_ad9bcad84721ad80d83830066cc332db.png" alt="【绉纱馄饨】史上最精致、讲究的小馄炖!的做法图解6"></td>
<td>⑥调汤:碗里放盐、糖、白胡椒粉、滚烫的鸡汤、猪油、小虾皮、紫菜搅拌均匀;</td>
</tr>
<tr>
<td><img src="/posts/56cc41e2/200_959f50ec08b059bfac6885681db6260e.png" alt="【绉纱馄饨】史上最精致、讲究的小馄炖!的做法图解7"></td>
<td>⑦煮制:小馄饨放在笊篱上,水开后放入笊篱,先烫熟底部,再放入水里煮至浮起捞出,加上蛋皮、葱花,淋麻油即可。</td>
</tr>
</tbody></table>
]]></content>
<categories>
<category>美食</category>
</categories>
<tags>
<tag>肉</tag>
</tags>
</entry>
<entry>
<title>查询字符串出现位置工具类</title>
<url>/posts/90c8aa59/</url>
<content><![CDATA[<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 查询字符串出现的位置</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> str 字符串</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> pat 查询的字符串</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> num 字符串位置</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">static</span> <span class="type">int</span> <span class="title function_">frequency</span><span class="params">(String str,String pat,<span class="type">int</span> num)</span>{</span><br><span class="line"> <span class="type">Pattern</span> <span class="variable">pattern</span> <span class="operator">=</span> Pattern.compile(pat);</span><br><span class="line"> <span class="type">Matcher</span> <span class="variable">findMatcher</span> <span class="operator">=</span> pattern.matcher(str);</span><br><span class="line"> <span class="type">int</span> <span class="variable">number</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">while</span>(findMatcher.find()) {</span><br><span class="line"> number++;</span><br><span class="line"> <span class="keyword">if</span>(number == num){</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> findMatcher.start();</span><br><span class="line"> <span class="keyword">return</span> i;</span><br><span class="line"> }</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>代码</category>
</categories>
<tags>
<tag>java</tag>
<tag>工具类</tag>
</tags>
</entry>
<entry>
<title>根据外网IP获取用户所在城市工具类</title>
<url>/posts/d6f28e22/</url>
<content><![CDATA[<p>maven</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="comment"><!--ip2region--></span></span><br><span class="line"><span class="tag"><<span class="name">dependency</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">groupId</span>></span>org.lionsoul<span class="tag"></<span class="name">groupId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">artifactId</span>></span>ip2region<span class="tag"></<span class="name">artifactId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">version</span>></span>1.7.2<span class="tag"></<span class="name">version</span>></span></span><br><span class="line"><span class="tag"></<span class="name">dependency</span>></span></span><br></pre></td></tr></table></figure>
<p>创建IPUtils工具类</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Log4j2</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">IPUtils</span> {</span><br><span class="line"> </span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 根据IP获取地址</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span> 国家|区域|省份|城市|ISP</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">static</span> String <span class="title function_">getAddress</span><span class="params">(String ip)</span> {</span><br><span class="line"> <span class="keyword">return</span> getAddress(ip, DbSearcher.BTREE_ALGORITHM);</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 根据IP获取地址</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> ip</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> algorithm 查询算法</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span> 国家|区域|省份|城市|ISP</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@see</span> DbSearcher</span></span><br><span class="line"><span class="comment"> * DbSearcher.BTREE_ALGORITHM; //B-tree</span></span><br><span class="line"><span class="comment"> * DbSearcher.BINARY_ALGORITHM //Binary</span></span><br><span class="line"><span class="comment"> * DbSearcher.MEMORY_ALGORITYM //Memory</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="meta">@SneakyThrows</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">static</span> String <span class="title function_">getAddress</span><span class="params">(String ip, <span class="type">int</span> algorithm)</span> {</span><br><span class="line"> <span class="keyword">if</span> (!Util.isIpAddress(ip)) {</span><br><span class="line"> log.error(<span class="string">"错误格式的ip地址: {}"</span>, ip);</span><br><span class="line"> <span class="keyword">return</span> <span class="string">""</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="type">String</span> <span class="variable">dbPath</span> <span class="operator">=</span> IPUtils.class.getResource(<span class="string">"/db/ip2region.db"</span>).getPath();</span><br><span class="line"> <span class="type">File</span> <span class="variable">file</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(dbPath);</span><br><span class="line"> <span class="keyword">if</span> (!file.exists()) {</span><br><span class="line"> log.error(<span class="string">"地址库文件不存在"</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="string">""</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="type">DbSearcher</span> <span class="variable">searcher</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">DbSearcher</span>(<span class="keyword">new</span> <span class="title class_">DbConfig</span>(), dbPath);</span><br><span class="line"> DataBlock dataBlock;</span><br><span class="line"> <span class="keyword">switch</span> (algorithm) {</span><br><span class="line"> <span class="keyword">case</span> DbSearcher.BTREE_ALGORITHM:</span><br><span class="line"> dataBlock = searcher.btreeSearch(ip);</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> DbSearcher.BINARY_ALGORITHM:</span><br><span class="line"> dataBlock = searcher.binarySearch(ip);</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> DbSearcher.MEMORY_ALGORITYM:</span><br><span class="line"> dataBlock = searcher.memorySearch(ip);</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">default</span>:</span><br><span class="line"> log.error(<span class="string">"未传入正确的查询算法"</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="string">""</span>;</span><br><span class="line"> }</span><br><span class="line"> searcher.close();</span><br><span class="line"> <span class="keyword">return</span> dataBlock.getRegion();</span><br><span class="line"> }</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category>代码</category>
</categories>
<tags>
<tag>java</tag>
<tag>工具类</tag>
<tag>ip</tag>
<tag>地理位置</tag>
</tags>
</entry>
<entry>
<title>潜意识编辑</title>
<url>/posts/9a21e95f/</url>
<content><![CDATA[<div class="hbe hbe-container" id="hexo-blog-encrypt" data-wpm="抱歉, 这个密码看着不太对, 请再试试." data-whm="抱歉, 这个文章不能被校验, 不过您还是能看看解密后的内容.">
<script id="hbeData" type="hbeData" data-hmacdigest="d8ccf7a4522e8216ee316591efbcfe7ffc24c580e0e6a43a1e25eba32b709027">601b7ad76f4fbd60ff466c34909923e912514f26a0c15bde20db246b4fed62511b087d3960571688a7aa28bf40dad4cefe57591854b3564793bbf3fc21eeff61acf7ac46b585b0173505948493344631ba535d86ac110512627babf006e23806b31e42681e2317505d04942c0dd3927d91381d6ec1c522fb6f280416149fdba92959cfe4244088f570a98bca3cf6f2d5f049150ccaa533a42abea0f40dc30523a4b77bd50653bc4d24588c2a87b81f13b0e31e5fe582a01a892f36972e3b6b0110596120be69ea3df5aa0303e123824ba831ddd52ce02b84edbaaf133a8336122f74863ad6962c227a85ce6e279f87037e9d72cf282d2ecf2cbc6acfc03392f5565f9ecb3acf616c97acda56ec52759d7e7c3a64edd3567f4c9bae0a35a59e936ac9a6cb8dbf72d4cf18854b0deac712141c530a86f671c0a839192aa2a94f7b7d89aff53919e44375ba6f5450fdd4ef4b7f0ee9ea5b0faf015d81dee46342c5f4113e689dc5532fa86e0c54540a3b9900e146f92c6a0870d34869709cdb0fd980a66aa7d69143b20b942c02fc002e79b1fa0edcea931fe25a996927d2c3e0648edccfcff8b8af771f79c921fac42be263d4c7265f7b00a0123287c60cc3df911f601c049cf8c5505342c1581f7602fcd508cd73d814e284a6e466daba388ce474891e16e88f518b772aeaaa995aba619d21810137b46221cb07cef5fb18642a78051b585e82baab247308c88f51349822425e6deb278f58db933e3629b193fd15481bfab30bc81821862925a42e28366aef86b3485cc03e4c65d80fcd55fa033caf21561fc09b8bee48125b771382399a325766da7c09ed3c76bcbdf3dc96248a919e9440f841cab6e238a33247b2e6a30d74522699b97c08b4adf816458c06d6aed9fa873dacc77ba3fc45cd1ed38219371c53248f0bf70d7eae024638e364b900a462dc95a303c6cb265ab4ba0b6de90313e1c391f7546e7996931058b42e91d646ea483a5ad602fd819f1a98a823893dd373b6db1144e8a6655fa7c44ed9f584b42b7f25a0bb7ed451f25d277814f78f4232cb6670c14019e121a771c562541ba6a02e1ca74ae89c1e672ededd2274fe28a8501a6dd8914002081af1aac3744d7206f6d4f4e72678827baccdfeb3fdc9f2bffbc08c8751593dd2f942c2cb3287116c87b9317ce1c52a97100828bd3195df9aa98572761d81e59ccfaa1cce5421b2ad6d81c66ff71e8048a4dd993657930a5fa1cda5aced4878eef4452385695720cf2672e73812890d045304ad0d50de9acb88a4c29d4f3e6793649f67fc6c303e0473e2efddf52cd448f164319ce20a0dbd30c0de842c6e2366f8e30687060b2626e915e85a16d90c47a84024bedc11cb4df415ced93372186c74e1de5e122c9523a1f669043291bc4fa3928accd44d6632ffa5676abb1fe231c8533b078707a1c8bbfd31ffe1fe4d33581ee2e1dd5dc95cf370a760528094a079f88cfe25de79ac24c87115713676944535e0e1abd395b0157fd6e27a275d749c5dc8b94e1173469a50a0533bace16e31382427a00ed1d678caf2e45477d45f8818a09eae05dd569e77669d610750e274e469c3effc50b15d45c74a601e817c8de63a31ab5a37917585b371e575c00056982efbeb7d80f8abc7912d6bf73def87dfce9816a878c515e02e920ae1634b1ab9c201fe716cc2c3dab067e94ff05562bc7bcda5b228b18b1fe0e9dea2c868a8bf000ec9e043e467f06ddc8ea8d76018ce0ab09aa5cfbadd137fc82ddb0c39fc133090e69cb3017f15d3805ed699f60c4e78508872c62fae5ea6c7d67324ba4e84bbe8a487e29cb5dcc9c4e2292c8fc77030ab65172f908df3c8f737f4168b88ddd24bbf530ffbadbf4a42612367cafb526f6d25cf402f4c775a29e921cd02a62f29b8ba55766f8c268c62865492e88c0ec7338cc91e538b67e653febbbfeb629cbd9f80c0117d2637a62b9d78f25925034e5c910cf902388a4b567d2f54d6055eda752fd50a250be1d54029852a9c807b4b72949ff2b1ce73d3d430a755cfabd1c042e8e2a55536ca0e0f1169fc2f678003fa7baefd0a4bdeebc9e723a9cd9df8e2069ba0d3a42a10f5ae4d6c8ae355b264d69dc1d1437e7593ece27cac1f9de649385e7654bb0739a8168ec133c3d673c3b7f22ddd3ba81f26654c47547fbcfb16cfa7b845d0dfdb91c020789093effe517c6cc2815c977ab1a1b0f16d5021bf7160eb54d016f064c802904fa8bccb343bbc05605aaf69eb2b847c5ece1f668a95d8d20d46cf82d336f33e8b1bcb89713dcc24be1ed364aa31a7a091b63bba04f02983a663a3c0e4956a81c6832496b06ee6f81f99cf33acbec1ae16cd381c414c4ce6edfdded2748f3e644d0f58a3a4136faacfeb7204d59ceadd3eb3bd8e8b007fc04cf7aa5c698480668a8afea7e2805d9c09ca2d49b069970215e0fa2cfab6743859e1e06a224f0214012a53100d2a2e1d5dc8169c20dd2f2a2a28fd1de91eec25907c4850baf4e3d308146035bd028d1a85a716f1be3bc0abe63cfdb9dd85c8c11c109038d43b691645df8ee5c36d84fa33c7a71de54ca445feb8ef8bff8131f84b8a330625d1de1b37f1e9ce8d21ae10dd40ff8dc83a3b6a0e90ab02d462a32c3b59b4b3817fb3f8103983d4e817df4f080d1f842bab71f3f351319eea845f294e90af7197fa2850d7f83f920dc806e9c5090eaea752d6e5ef8c3f77d0f4a141107e87716b6c120a36e6dc10aa4c5df6663b4690b9e975e1efcefc42fdcba655bef82554313f7173483558d1ebd9b8df69e395905d7445de435e1d28daed344ac8d6df82cf581cb1bf8650d72cf93007e07cea2f0692b1c00634ee3691806cc423052f9357128a289319ac11867aa09c1a5f4da29e99c3d2b41fa6e4d9767cf398b5b8c53fb95e1f5f0f79b049a4e8b9498c13abdda01be18545b1aa841fb623c2692441536c24b0252cd6f7858e29e382a54221667c0b9ad77bdab8135a6c21ed1167152234dd045f65a90e8a02601e2e85a203aa4c72d646311b190d683fbc0dd02795e6e6f5b4f4f11719ba20494ccafaad7053aec5bbaf704e39b490b6dd082a066cfeb3039ac4e3126d4ef147b7966533bdd2635c849660669908d0a8380cff226e8523c9e518bf513954ca103a292f63aafbe5ed720b19df70de887e470ef4651677f5217625795ac9b5acad9cc0148d510bc095fb12d7205a003e777b4fdbcd7e132c1f1f86655711643f044638184e8cef4d176a911f1340c1fbd6be9ecd774dad1c8c8c981b9c66e02373e9c4d7aae6fc40231b9b1531bd6b16442d8e0b31cc6ee50c5d595ba004c4097667c97729d19a5176b555b87efff165d135b59b42075f18f7e871f71b35185086babf625a173c45fa255616490cd307527cf49340e3f2891464f3eba971c13c37726b9cb6c47a12f32fd37dce4a48be625c332e31433329bed7437ea0e90a6808bff87a496791ae4e6cf5f112cd274e93fab0f3ba5d17717373bc0e142b09c07a5ffad51badfb11636940f66fe14091fcb2e89f27620709104e0064bf0662853f425198f281af56481f4397571fc37945e9bb9b45f8bdc0457ef64fa56ae46f7b968af1a738ad3a8f9854b04727c2b688451c86053e0bb5a8438fe7b44f84c7c8</script>
<div class="hbe hbe-content">
<div class="hbe hbe-input hbe-input-xray">
<input class="hbe hbe-input-field hbe-input-field-xray" type="password" id="hbePass">
<label class="hbe hbe-input-label hbe-input-label-xray" for="hbePass">
<span class="hbe hbe-input-label-content hbe-input-label-content-xray">您好, 这里需要密码.</span>
</label>
<svg class="hbe hbe-graphic hbe-graphic-xray" width="300%" height="100%" viewBox="0 0 1200 60" preserveAspectRatio="none">
<path d="M0,56.5c0,0,298.666,0,399.333,0C448.336,56.5,513.994,46,597,46c77.327,0,135,10.5,200.999,10.5c95.996,0,402.001,0,402.001,0"></path>
<path d="M0,2.5c0,0,298.666,0,399.333,0C448.336,2.5,513.994,13,597,13c77.327,0,135-10.5,200.999-10.5c95.996,0,402.001,0,402.001,0"></path>
</svg>
</div>
</div>
</div>
<script data-pjax src="/lib/hbe.js"></script><link href="/css/hbe.style.css" rel="stylesheet" type="text/css">]]></content>
<categories>
<category>哲学</category>
</categories>
<tags>
<tag>思维系统</tag>
<tag>认知与实践</tag>
</tags>
</entry>
<entry>
<title>用SpringBoot连接redis并处理数据</title>
<url>/posts/79be3dc6/</url>
<content><![CDATA[<h2 id="添加依赖"><a href="#添加依赖" class="headerlink" title="添加依赖"></a>添加依赖</h2><p>pom.xml</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag"><<span class="name">dependency</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">groupId</span>></span>org.springframework.boot<span class="tag"></<span class="name">groupId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">artifactId</span>></span>spring-boot-starter-data-redis<span class="tag"></<span class="name">artifactId</span>></span></span><br><span class="line"><span class="tag"></<span class="name">dependency</span>></span></span><br><span class="line"><span class="tag"><<span class="name">dependency</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">groupId</span>></span>org.apache.commons<span class="tag"></<span class="name">groupId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">artifactId</span>></span>commons-pool2<span class="tag"></<span class="name">artifactId</span>></span></span><br><span class="line"><span class="tag"></<span class="name">dependency</span>></span></span><br></pre></td></tr></table></figure>
<h2 id="连接redis"><a href="#连接redis" class="headerlink" title="连接redis"></a>连接redis</h2><figure class="highlight yml"><table><tr><td class="code"><pre><span class="line"><span class="attr">spring:</span></span><br><span class="line"> <span class="attr">redis:</span></span><br><span class="line"> <span class="attr">lettuce:</span></span><br><span class="line"> <span class="attr">pool:</span></span><br><span class="line"> <span class="comment">#连接池最大连接数 使用负值代表无限制 默认为8</span></span><br><span class="line"> <span class="attr">max-active:</span> <span class="number">10</span></span><br><span class="line"> <span class="comment">#最大空闲连接 默认8</span></span><br><span class="line"> <span class="attr">max-idle:</span> <span class="number">10</span></span><br><span class="line"> <span class="comment">#最小空闲连接 默认0</span></span><br><span class="line"> <span class="attr">min-idle:</span> <span class="number">1</span></span><br><span class="line"> <span class="attr">host:</span> <span class="number">172.29</span><span class="number">.239</span><span class="number">.101</span></span><br><span class="line"> <span class="attr">password:</span> <span class="string">ax7Qx28MGx</span></span><br><span class="line"> <span class="attr">port:</span> <span class="number">6379</span></span><br><span class="line"> <span class="comment">#db选择</span></span><br><span class="line"> <span class="attr">database:</span> <span class="number">1</span></span><br><span class="line"> <span class="attr">timeout:</span> <span class="string">2000ms</span></span><br></pre></td></tr></table></figure>
<h2 id="配置redis"><a href="#配置redis" class="headerlink" title="配置redis"></a>配置redis</h2><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">RedisConfig</span> {</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Bean</span></span><br><span class="line"> <span class="keyword">public</span> RedisTemplate<String, Object> <span class="title function_">redisTemplate</span><span class="params">(RedisConnectionFactory factory)</span> {</span><br><span class="line"> RedisTemplate<String, Object> template = <span class="keyword">new</span> <span class="title class_">RedisTemplate</span><String, Object>();</span><br><span class="line"> template.setConnectionFactory(factory);</span><br><span class="line"> <span class="comment">// key采用String的序列化方式</span></span><br><span class="line"> template.setKeySerializer(<span class="keyword">new</span> <span class="title class_">StringRedisSerializer</span>());</span><br><span class="line"> <span class="comment">// hash的key也采用String的序列化方式</span></span><br><span class="line"> template.setHashKeySerializer(<span class="keyword">new</span> <span class="title class_">StringRedisSerializer</span>());</span><br><span class="line"> <span class="comment">// value序列化方式采用jackson</span></span><br><span class="line"> template.setValueSerializer(<span class="keyword">new</span> <span class="title class_">GenericJackson2JsonRedisSerializer</span>());</span><br><span class="line"> <span class="comment">// hash的value序列化方式采用jackson</span></span><br><span class="line"> template.setHashValueSerializer(<span class="keyword">new</span> <span class="title class_">GenericJackson2JsonRedisSerializer</span>());</span><br><span class="line"> template.afterPropertiesSet();</span><br><span class="line"> <span class="keyword">return</span> template;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="测试"><a href="#测试" class="headerlink" title="测试"></a>测试</h2><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@RestController</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">test</span> {</span><br><span class="line"> <span class="meta">@Autowired</span></span><br><span class="line"> <span class="keyword">private</span> StringRedisTemplate redisTemplate;</span><br><span class="line"> </span><br><span class="line"> <span class="meta">@GetMapping(value="/setDataBase")</span></span><br><span class="line"> <span class="keyword">public</span> String <span class="title function_">setDataBase</span><span class="params">()</span> <span class="keyword">throws</span> IOException {</span><br><span class="line"> redisTemplate.opsForValue().set(<span class="string">"1"</span>, <span class="string">"1"</span>)</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>代码</category>
</categories>
<tags>
<tag>redis</tag>
<tag>SpringBoot</tag>
</tags>
</entry>
<entry>
<title>知行合一</title>
<url>/posts/3ad44071/</url>
<content><![CDATA[<div class="hbe hbe-container" id="hexo-blog-encrypt" data-wpm="抱歉, 这个密码看着不太对, 请再试试." data-whm="抱歉, 这个文章不能被校验, 不过您还是能看看解密后的内容.">
<script id="hbeData" type="hbeData" data-hmacdigest="3981d709bb5a353e074050433c0ba7361dd17582e16ff188cc8d881ed87317a2">601b7ad76f4fbd60ff466c34909923e950b1935d7fcde4a9120557883c05daf6f264e4945041476ce13509bfdd923a2685869a661c85b8617efdf799d966afcfd6d08ec45e679f9818d916d7c5b69c0e4b63e8cb355a8fc342f5e3128eba8fb29e15fb72c72be7e3a1fe928ae9988565be00f50158dd21d2eecbbc6dbd7d0043239fd55ade6870c78e26611fbc7622133d1f1a3729eaf1eeec115eef3d02226018420d40c59877c5f75d177a1e3466228fc6a85d68df2a0719c4d2c41b547a7131fb220c06763c9c21c144e6f9efe01496d235ce2ee0809e5ba8f9d1b5dd0a655c46085591719b8dc760296b94a81ea28da0fd79049f3c5aa34f87d35e3aa8c5fea7fdb8cdc896ff57736dc6f09828f3ad2bcaa79c2339ea3067a65f0b86e4f2e95f1e7c42cd6b755f95ea7ee9af38f731bb643ddb140d7b14a64c3b3f5a8d3db8ca98352ba09a53a99a97703e00a28eba901be2523b1dc094ee1e63b0cd3d2cbd7fa37f28a3d55058617a5ebed86d053318215580f364d104f300e3d3c2beb8dd50d9d26b6a59c854aff22cee5fed5336070256a63d0a0f92e6df0262e29189086966e6bcd0dceb93e3b51c49c5970a011747074a36475c4e6cb7968e30b289bd3d0210f0331f89f3ef3cf5a23e2502aa99fb9ac80c216926e9757907f897c2d477e9765c54a0907d2b0748ec45ff1e18210438b2bbaad269ae62402c778530d62d82bffc31f18f17d4ab71349348407ce40941b3fa41bdc73ffdb93c45082ab2e152fcd9c51532f3c0f0d0463e33990722b92cbc6858b0713b4386efe716286241a3d6f9eac3275ec1c04c80b00498e1a024ce55365c6e703be24bfc43bf23c25dc08094940c16c855bfb9f194328252a1112225fd00bae928f20fdcd04ac81d40f6fc2db4490170087ca851828f835173519e4ef233c2639756a6c5ac372942503e96dc0fdc393c6b3365decd5416ea7dd1b7d5b82379efb495c73772e84e8c78448700f9c3534bdd98a94cc651f1d6525d5b71f3acf693b139f5d4d88e920651089a822dc66723b53aa1e8fcac01af0f18d40f9d9a6102138b84dccf386532d5ee8f2446428c8aa4c07dea7515e18fa8d0c3663352231487a715033ffe051916e34c24fbc3edc649c1de8887439b17eb3f87cd078054130d1c7b94639a2740226e591e92c1d0d74171d8cfaf02daefbd02bb92871fdb130e7b52a8110dfe7037fd68e0ce5f84ee9fdaaba7394761fc0f20195177272675db643cfdf279bf6ef6b629c4cf1727d12c91568ac5923633aa027ab934d9d457d59bfb113b83f3a0254bca9c9a0926f3f30195f2f2ef47912291a75881840a5dc781be2d629b990a5d4637de857cff8b7e2f53dad5b35f83c8e507c7a3ec0ef2cada8e56bc401daa8100304bc26539a1721f2fe6d8d6f6d0080abc586357caf75c3304abca9a499ee3fd5435256c9b8aa34448af16f5100874698ba24ecc09377a88881407f066001be55db59fdb9e30624e3da8be7a1ad2393bb702bead4394ed991b5ca97245e0b75612db585fdabc45e6babc86c45bd440f35df7f1c90a401afa4a1a0ff050a7a87013adaf28f9aa29f3f28bab124b1b6fcbfb6c629815df5ed7948d443445ae29a4114571c453cbf5cf795d084e872bf01ad625a11fffe09d319718edcc6063ab0e2af3450b9f117b47044baf38e3565da9c0e6717f3c0dc80f425e065098fd9514e242de06eb8d1621e1df89f3c12ecc8e40026a1be92c9f42e51f091e0d46da70ea14231aa54e527decc7ea4d0d213dd92e19e8e3c22a470c92458218a686da17df8d165c117310aeb2cb39197f78c7fe9b49db7ab64b8292e176f88d83742de324d7561d2522f023e7fa0c339e419be65b011f2345fbe1b1b6e62b084f7a804bddb8505a2a83df736444f07addcd0be16d7ea5f916dcdbcede4743fd30c722127a964b9cc05986b500f689144a00a35ae32ac16025b55275b30f8ef80a8e0480396a812757258137c056fb89326309c600193002a07c03ef50628faa821f345978f1f379bd6202839b65bcad97ee7c8bd2ebc491452ecd287fdc994dab57fda42870d0c25a8a64ef18f3c711526509c7d06b2015272e850d3dd96aee481e296f26aea24e5f316048edd1512ce9acabc64a98d54e4213f253de7e02dbbe2fef829a0259758fcb7b71e18d6e66060f5ba3da182c7393e83268379ac95968bbc74526d9de4773fa5aa12e1ef494f5e25cd799fed5a28048b1b07da6cff573b138ea2c18c4484be1778482b73e97080f850deb54fd110eafc67ee9bb12f4c1dda792065e1b527642c5cc8220972e92d462391c90578551a1ef6a9c05a69524fdec2636def32af3f3a1836d64d0ca64df79e47dcfcfaa75667d2be4a5264b7b0be256aa9a0143759d2f134172a7c3c0a31c79c9bc909cb86589853494c99efa404f5ea76164b4ee4c32ecbdfe1d845b40aeccaba1490381fdef4d543666693933e6b26500ffd98c85a8b7ad5a41e4a94aec57c526b929c11a6f9abf3fd682b2d01e9c5ee850e4afde6dd38d43958139e424e8f9114cabfb73bd10f57e234c2f6e3f2c13696dfe400c1e3c00bfd653b880da1505c87d8a8afe04b7d44e91e0bee877d5d497a00c0cfc0d1f9fe3a9161171e89de1223c65291e38ec9dd04a9f75a56be4f356f21664fd9e303d6314b1c35bb67389d3f17c8bca172cfb0925b29a0be75b95309084ffd057e65f3e443eacfafec2117ac156d4c06548d647b9b9552a0abd9bf73119b72ddf88a08e1a834f97c9a05e22b151d482104c98910782e8062f79962436078aa7414f80683a583a4028b007cf5eb7c13d6552a058ff912f79b27175ff43bc30e9e04e7fd26bc78e83047886aa186d033d36a76cfe6f04aeb9f650601bbcc698d33c925709d6b6509486182744e4eec8f384985ba094a5dc41a888896907b40963dc6629b1a456bcd8e3ace774e10ca5bc954c5df0941948e952b9e4d1080f9d264b8c0e87cf6d75e9d74eb6e55a0481bcc1e6e5103efba1c1fda7fe8b7af422a18baba566576b18d10b4612f6d324e3f1282fc18a956eaa534a91ffc1547944cb1efc3fa29f2bfe1f9b579dbd1c9c2c0ed25d3044243d3411d51bf4e76df96a12f96a543655aba9817af907f37b9098e447e4b9f2e842dbee8cc5b09c1f790654dae8bb1f1f3781fb7d7c60ee6c759ad91b9bbbca4299ecb0173815aeaec847d09357035c6fb19f1df7fc4aa3446088c655bd4289e2b8cab4ec8365d632f5464166ed28b10afbedb31db301ee51ca1ea5a04f016a2a1238</script>
<div class="hbe hbe-content">
<div class="hbe hbe-input hbe-input-xray">
<input class="hbe hbe-input-field hbe-input-field-xray" type="password" id="hbePass">
<label class="hbe hbe-input-label hbe-input-label-xray" for="hbePass">
<span class="hbe hbe-input-label-content hbe-input-label-content-xray">您好, 这里需要密码.</span>
</label>
<svg class="hbe hbe-graphic hbe-graphic-xray" width="300%" height="100%" viewBox="0 0 1200 60" preserveAspectRatio="none">
<path d="M0,56.5c0,0,298.666,0,399.333,0C448.336,56.5,513.994,46,597,46c77.327,0,135,10.5,200.999,10.5c95.996,0,402.001,0,402.001,0"></path>
<path d="M0,2.5c0,0,298.666,0,399.333,0C448.336,2.5,513.994,13,597,13c77.327,0,135-10.5,200.999-10.5c95.996,0,402.001,0,402.001,0"></path>
</svg>
</div>
</div>
</div>
<script data-pjax src="/lib/hbe.js"></script><link href="/css/hbe.style.css" rel="stylesheet" type="text/css">]]></content>
<categories>
<category>哲学</category>
</categories>
<tags>
<tag>思维系统</tag>
<tag>认知与实践</tag>
</tags>
</entry>
<entry>
<title>获取客户端外网ip</title>
<url>/posts/cab7a692/</url>
<content><![CDATA[<h5 id="获取外网IP"><a href="#获取外网IP" class="headerlink" title="获取外网IP"></a>获取外网IP</h5><p>万网获取外网IP地址:<a href="http://www.net.cn/static/cust%E2%80%A6">www.net.cn/static/cust…</a></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>:获取客户端外网ip 此方法要接入互联网才行,内网不行</span></span><br><span class="line"><span class="comment"> **/</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> String <span class="title function_">getPublicIp</span><span class="params">()</span> {</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="type">String</span> <span class="variable">path</span> <span class="operator">=</span> <span class="string">"http://www.net.cn/static/customercare/yourip.asp"</span>;<span class="comment">// 要获得html页面内容的地址(万网)</span></span><br><span class="line"> </span><br><span class="line"> <span class="type">URL</span> <span class="variable">url</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">URL</span>(path);<span class="comment">// 创建url对象</span></span><br><span class="line"> </span><br><span class="line"> <span class="type">HttpURLConnection</span> <span class="variable">conn</span> <span class="operator">=</span> (HttpURLConnection) url.openConnection();<span class="comment">// 打开连接</span></span><br><span class="line"> </span><br><span class="line"> conn.setRequestProperty(<span class="string">"contentType"</span>, <span class="string">"GBK"</span>); <span class="comment">// 设置url中文参数编码</span></span><br><span class="line"> </span><br><span class="line"> conn.setConnectTimeout(<span class="number">5</span> * <span class="number">1000</span>);<span class="comment">// 请求的时间</span></span><br><span class="line"> </span><br><span class="line"> conn.setRequestMethod(<span class="string">"GET"</span>);<span class="comment">// 请求方式</span></span><br><span class="line"> </span><br><span class="line"> <span class="type">InputStream</span> <span class="variable">inStream</span> <span class="operator">=</span> conn.getInputStream();</span><br><span class="line"> <span class="comment">// readLesoSysXML(inStream);</span></span><br><span class="line"> </span><br><span class="line"> <span class="type">BufferedReader</span> <span class="variable">in</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">BufferedReader</span>(<span class="keyword">new</span> <span class="title class_">InputStreamReader</span>(</span><br><span class="line"> inStream, <span class="string">"GBK"</span>));</span><br><span class="line"> <span class="type">StringBuilder</span> <span class="variable">buffer</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StringBuilder</span>();</span><br><span class="line"> String line;</span><br><span class="line"> <span class="comment">// 读取获取到内容的最后一行,写入</span></span><br><span class="line"> <span class="keyword">while</span> ((line = in.readLine()) != <span class="literal">null</span>) {</span><br><span class="line"> buffer.append(line);</span><br><span class="line"> }</span><br><span class="line"> List<String> ips = <span class="keyword">new</span> <span class="title class_">ArrayList</span><>();</span><br><span class="line"> </span><br><span class="line"> <span class="comment">//用正则表达式提取String字符串中的IP地址</span></span><br><span class="line"> String regEx=<span class="string">"((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)"</span>;</span><br><span class="line"> <span class="type">String</span> <span class="variable">str</span> <span class="operator">=</span> buffer.toString();</span><br><span class="line"> <span class="type">Pattern</span> <span class="variable">p</span> <span class="operator">=</span> Pattern.compile(regEx);</span><br><span class="line"> <span class="type">Matcher</span> <span class="variable">m</span> <span class="operator">=</span> p.matcher(str);</span><br><span class="line"> <span class="keyword">while</span> (m.find()) {</span><br><span class="line"> <span class="type">String</span> <span class="variable">result</span> <span class="operator">=</span> m.group();</span><br><span class="line"> ips.add(result);</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="comment">// 返回公网IP值</span></span><br><span class="line"> <span class="keyword">return</span> ips.get(<span class="number">0</span>);</span><br><span class="line"> </span><br><span class="line"> } <span class="keyword">catch</span> (Exception e) {</span><br><span class="line"> System.out.println(<span class="string">"获取公网IP连接超时"</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="string">""</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>代码</category>
</categories>
<tags>
<tag>java</tag>
<tag>工具类</tag>
</tags>
</entry>
<entry>
<title>雪花算法生成ID工具类</title>
<url>/posts/2fa39047/</url>
<content><![CDATA[<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">package</span> com.rtsrt.usercenter.util;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * snowflake算法</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span> ZHAI</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@date</span> 2022/1/4 10:53</span></span><br><span class="line"><span class="comment"> **/</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">SnowflakeIdWorker</span> {</span><br><span class="line"></span><br><span class="line"> <span class="comment">// ==============================Fields===========================================</span></span><br><span class="line"> <span class="comment">/** 开始时间截 */</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">final</span> <span class="type">long</span> <span class="variable">twepoch</span> <span class="operator">=</span> <span class="number">1641225600000l</span>;</span><br><span class="line"></span><br><span class="line"> <span class="comment">/** 机器id所占的位数 */</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">final</span> <span class="type">long</span> <span class="variable">workerIdBits</span> <span class="operator">=</span> <span class="number">5L</span>;</span><br><span class="line"></span><br><span class="line"> <span class="comment">/** 数据标识id所占的位数 */</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">final</span> <span class="type">long</span> <span class="variable">datacenterIdBits</span> <span class="operator">=</span> <span class="number">5L</span>;</span><br><span class="line"></span><br><span class="line"> <span class="comment">/** 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) */</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">final</span> <span class="type">long</span> <span class="variable">maxWorkerId</span> <span class="operator">=</span> -<span class="number">1L</span> ^ (-<span class="number">1L</span> << workerIdBits);</span><br><span class="line"></span><br><span class="line"> <span class="comment">/** 支持的最大数据标识id,结果是31 */</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">final</span> <span class="type">long</span> <span class="variable">maxDatacenterId</span> <span class="operator">=</span> -<span class="number">1L</span> ^ (-<span class="number">1L</span> << datacenterIdBits);</span><br><span class="line"></span><br><span class="line"> <span class="comment">/** 序列在id中占的位数 */</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">final</span> <span class="type">long</span> <span class="variable">sequenceBits</span> <span class="operator">=</span> <span class="number">12L</span>;</span><br><span class="line"></span><br><span class="line"> <span class="comment">/** 机器ID向左移12位 */</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">final</span> <span class="type">long</span> <span class="variable">workerIdShift</span> <span class="operator">=</span> sequenceBits;</span><br><span class="line"></span><br><span class="line"> <span class="comment">/** 数据标识id向左移17位(12+5) */</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">final</span> <span class="type">long</span> <span class="variable">datacenterIdShift</span> <span class="operator">=</span> sequenceBits + workerIdBits;</span><br><span class="line"></span><br><span class="line"> <span class="comment">/** 时间截向左移22位(5+5+12) */</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">final</span> <span class="type">long</span> <span class="variable">timestampLeftShift</span> <span class="operator">=</span> sequenceBits + workerIdBits + datacenterIdBits;</span><br><span class="line"></span><br><span class="line"> <span class="comment">/** 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) */</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">final</span> <span class="type">long</span> <span class="variable">sequenceMask</span> <span class="operator">=</span> -<span class="number">1L</span> ^ (-<span class="number">1L</span> << sequenceBits);</span><br><span class="line"></span><br><span class="line"> <span class="comment">/** 工作机器ID(0~31) */</span></span><br><span class="line"> <span class="keyword">private</span> <span class="type">long</span> workerId;</span><br><span class="line"></span><br><span class="line"> <span class="comment">/** 数据中心ID(0~31) */</span></span><br><span class="line"> <span class="keyword">private</span> <span class="type">long</span> datacenterId;</span><br><span class="line"></span><br><span class="line"> <span class="comment">/** 毫秒内序列(0~4095) */</span></span><br><span class="line"> <span class="keyword">private</span> <span class="type">long</span> <span class="variable">sequence</span> <span class="operator">=</span> <span class="number">0L</span>;</span><br><span class="line"></span><br><span class="line"> <span class="comment">/** 上次生成ID的时间截 */</span></span><br><span class="line"> <span class="keyword">private</span> <span class="type">long</span> <span class="variable">lastTimestamp</span> <span class="operator">=</span> -<span class="number">1L</span>;</span><br><span class="line"></span><br><span class="line"> <span class="comment">//==============================Constructors=====================================</span></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 构造函数</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> workerId 工作ID (0~31)</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> datacenterId 数据中心ID (0~31)</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">public</span> <span class="title function_">SnowflakeIdWorker</span><span class="params">(<span class="type">long</span> workerId, <span class="type">long</span> datacenterId)</span> {</span><br><span class="line"> <span class="keyword">if</span> (workerId > maxWorkerId || workerId < <span class="number">0</span>) {</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">IllegalArgumentException</span>(String.format(<span class="string">"worker Id can't be greater than %d or less than 0"</span>, maxWorkerId));</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (datacenterId > maxDatacenterId || datacenterId < <span class="number">0</span>) {</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">IllegalArgumentException</span>(String.format(<span class="string">"datacenter Id can't be greater than %d or less than 0"</span>, maxDatacenterId));</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">this</span>.workerId = workerId;</span><br><span class="line"> <span class="built_in">this</span>.datacenterId = datacenterId;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// ==============================Methods==========================================</span></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 获得下一个ID (该方法是线程安全的)</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span> SnowflakeId</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">synchronized</span> <span class="type">long</span> <span class="title function_">nextId</span><span class="params">()</span> {</span><br><span class="line"> <span class="type">long</span> <span class="variable">timestamp</span> <span class="operator">=</span> timeGen();</span><br><span class="line"></span><br><span class="line"> <span class="comment">//如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常</span></span><br><span class="line"> <span class="keyword">if</span> (timestamp < lastTimestamp) {</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">RuntimeException</span>(</span><br><span class="line"> String.format(<span class="string">"Clock moved backwards. Refusing to generate id for %d milliseconds"</span>, lastTimestamp - timestamp));</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//如果是同一时间生成的,则进行毫秒内序列</span></span><br><span class="line"> <span class="keyword">if</span> (lastTimestamp == timestamp) {</span><br><span class="line"> sequence = (sequence + <span class="number">1</span>) & sequenceMask;</span><br><span class="line"> <span class="comment">//毫秒内序列溢出</span></span><br><span class="line"> <span class="keyword">if</span> (sequence == <span class="number">0</span>) {</span><br><span class="line"> <span class="comment">//阻塞到下一个毫秒,获得新的时间戳</span></span><br><span class="line"> timestamp = tilNextMillis(lastTimestamp);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//时间戳改变,毫秒内序列重置</span></span><br><span class="line"> <span class="keyword">else</span> {</span><br><span class="line"> sequence = <span class="number">0L</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//上次生成ID的时间截</span></span><br><span class="line"> lastTimestamp = timestamp;</span><br><span class="line"></span><br><span class="line"> <span class="comment">//移位并通过或运算拼到一起组成64位的ID</span></span><br><span class="line"> <span class="keyword">return</span> ((timestamp - twepoch) << timestampLeftShift) <span class="comment">//</span></span><br><span class="line"> | (datacenterId << datacenterIdShift) <span class="comment">//</span></span><br><span class="line"> | (workerId << workerIdShift) <span class="comment">//</span></span><br><span class="line"> | sequence;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 阻塞到下一个毫秒,直到获得新的时间戳</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> lastTimestamp 上次生成ID的时间截</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span> 当前时间戳</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">protected</span> <span class="type">long</span> <span class="title function_">tilNextMillis</span><span class="params">(<span class="type">long</span> lastTimestamp)</span> {</span><br><span class="line"> <span class="type">long</span> <span class="variable">timestamp</span> <span class="operator">=</span> timeGen();</span><br><span class="line"> <span class="keyword">while</span> (timestamp <= lastTimestamp) {</span><br><span class="line"> timestamp = timeGen();</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> timestamp;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 返回以毫秒为单位的当前时间</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span> 当前时间(毫秒)</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">protected</span> <span class="type">long</span> <span class="title function_">timeGen</span><span class="params">()</span> {</span><br><span class="line"> <span class="keyword">return</span> System.currentTimeMillis();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//==============================Test=============================================</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> {</span><br><span class="line"> <span class="type">SnowflakeIdWorker</span> <span class="variable">idWorker</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">SnowflakeIdWorker</span>(<span class="number">0</span>, <span class="number">0</span>);</span><br><span class="line"> <span class="type">long</span> <span class="variable">id</span> <span class="operator">=</span> idWorker.nextId();</span><br><span class="line"> System.out.println(id);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>使用</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="type">SnowflakeIdWorker</span> <span class="variable">idWorker</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">SnowflakeIdWorker</span>(<span class="number">0</span>, <span class="number">0</span>);</span><br><span class="line"><span class="type">long</span> id=idWorker.nextId();</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category>代码</category>
</categories>
<tags>
<tag>java</tag>
<tag>工具类</tag>
<tag>算法</tag>
</tags>
</entry>
<entry>
<title>互联网公司架构</title>
<url>/posts/47fc87c9/</url>
<content><![CDATA[<p>每个公司不同的成长历史、不同的业务架构和不同的管理风格,造就了不同的公司架构,互联网产品落地离不开团队各部门高效配合,所以深入理解各部门各岗位职责尤为重要,高效的业务流程建立在合理的组织架构上,下面分析一下目前比较常见的互联网公司架构及各岗位主要职能要求。</p>
<h2 id="一、互联网企业的组织架构"><a href="#一、互联网企业的组织架构" class="headerlink" title="一、互联网企业的组织架构"></a>一、<strong>互联网企业的组织架构</strong></h2><p>互联网公司常见组织架构如下:</p>
<p><img src="/posts/47fc87c9/webp-1713627438815-3.webp" alt="img"></p>
<h3 id="1-基础活动:"><a href="#1-基础活动:" class="headerlink" title="1.基础活动:"></a><strong>1.基础活动:</strong></h3><p>基础活动,就是一个企业得以存在和发展的基本的业务活动,相应的就需要配备支持业务发展的部门,一般在互联网企业中,<strong>产品部、技术部、运营部</strong>是三个最为基础的部门,这也是一个创业公司必须配置的基本部门,也是一个公司最关键的部门。</p>
<h4 id="(1)产品部:"><a href="#(1)产品部:" class="headerlink" title="(1)产品部:"></a>(1)产品部:</h4><p>在互联网企业中,产品部通常是<strong>业务的发动机</strong>,是一个公司得以存在<strong>发展的基础</strong>。产品部的典型产出不同于传统企业的实物,而是我们电脑上的一个个网页、软件,或者手机中的一个个app,甚至是一个微信公众号、或者一个微信小程序。</p>
<p>产品部门承担着产品的<strong>需求调研、产品设计、需求梳理、产品开发落地,以及产品上线后的迭代</strong>等工作,部门要为产品的核心业务指标负责,比如<strong>收入、用户量、ROI</strong>等。</p>
<p>一般产品部的主要岗位有产品总监、产品经理、产品专员、产品助理等。但是,不是每一个互联网公司的产品部都需要设置齐备这些岗位。不同规模的公司,可能只有其中几个岗位,比如对于创业型的公司,可能只有产品总监和2-3个产品经理,甚至只有一个产品经理。随着公司规模的扩大,人员增多,为员工预留未来的职业发展空间,会设置一个完整的升迁路径。</p>
<h4 id="(2)设计部:"><a href="#(2)设计部:" class="headerlink" title="(2)设计部:"></a>(2)设计部:</h4><p>设计部的主要目的是,承接产品的<strong>视觉设计</strong>和<strong>交互设计</strong>等关键工作,包括app各种页面框架和元素的设计,页面交互流程的设计等——即某一个页面之后,应该去向哪个页面,这种页面的流转是否合理流畅。</p>
<p>一般初创公司可能不会设置设计部,但是,一定会招聘设计师,因为如今的app,产品美观和页面流畅已经成为必备的基本要素,所以,一个没有经过设计参与的app是不可能上线的,尤其是C端产品(针对大众用户)更是如此。</p>
<p>在互联网公司中,设计师之间的分工差异性并不大,不同的人直接的差异,就是体现在业务模块的不同,比如A负责其中一个模块的设计,B负责另外一个模块的设计。所以,设计部的岗位,主要是设计负责人,和级别不同的设计师。</p>
<p>在这里我把设计人员放在了产品部中,有两个原因,一是创业团队中设计人员通常就是1-2个UI设计师,甚至没有交互设计师,不足以成立一个部门,另外设计的工作更像是辅助产品,将产品进一步可视化和美化。</p>
<h4 id="(3)技术部:"><a href="#(3)技术部:" class="headerlink" title="(3)技术部:"></a>(3)技术部:</h4><p>技术部是一个互联网公司的<strong>核心支撑</strong>,如果没有技术部,即使有再好的产品创意理念,无法开发落地,只会是一个概念而已。甚至,在互联网发展的早期,一个小型创业公司,没有产品经理,只有技术开发人员,由技术开发来设计产品。</p>
<p>技术部主要负责产品的技术开发工作。在传统企业,对标互联网企业该部门的,叫IT部,规模一般不大,主要管理公司的网络事物,人员配备不多。但是<strong>,在互联网公司,技术部相对来说都是大部门,互联网公司往往都是技术驱动的,技术人员是公司最主要的员工群体。</strong></p>
<p>技术部主要负责产品的技术开发工作。在传统企业,对标互联网企业该部门的,叫IT部,规模一般不大,主要管理公司的网络事物,人员配备不多。但是,在互联网公司,技术部相对来说都是大部门,互联网公司往往都是技术驱动的,技术人员是公司最主要的员工群体。</p>
<h4 id="(4)运营部"><a href="#(4)运营部" class="headerlink" title="(4)运营部:"></a>(4)运营部:</h4><p>运营部设置的主要目的,是通过对业务流中的各个环节进行优化,促进业务的精细化深耕,从而提高资源和流量利用的效率,从而促进总体业务目标的实现。</p>
<p>运营部主要负责产品上线后,运行过程中的各种链接用户和商家相关的工作,所以就会产生<strong>用户运营、商家运营、产品运营</strong>等相关的工作岗位。这些岗位之间的工作属性差异很较大,比如<a href="https://links.jianshu.com/go?to=https://www.zhihu.com/search?q=%E7%94%A8%E6%88%B7%E8%BF%90%E8%90%A5&search_source=Entity&hybrid_search_source=Entity&hybrid_search_extra=%7B:,:708439059%7D"><strong>用户运营</strong></a>,主要负责与<strong>用户拉新、留存、活跃、转化</strong>相关的各种工作。商家运营是平台型产品,或者B端产品才会有的岗位,主要负责与合作商家的各种工作职责。</p>
<p>在一个创业型的公司中,运营的岗位相对来说会比较少,因为产品还不成熟,没有那么多优化的工作可做,而且,运营的工作职责不会很明晰,基本上产品无法顾及的事情,都会放到运营部门,比如客服。不过,随着产品业务量和用户量的增加,运营部门的工作职责会逐渐清晰起来,岗位的设置也会逐步走向专门化。</p>
<h4 id="(5)市场部"><a href="#(5)市场部" class="headerlink" title="(5)市场部"></a>(5)市场部</h4><p><strong>在传统企业里面,市场部是一个关键的支撑部门</strong>,主要的目的是帮助销售人员做市场推支持,以促进企业对外部资源的使效率。在这一点上,市场部是传统企业和互联网企业里面职能最为相似的一个部。</p>
<p>在互联网企业中,市场部的主要职责是负责流量的获取,一款app上线后,除了自然流量的获取,企业还需要通过市场部主动做很多的动作,来获取流量,增加产品的用户量。如今主要是在各大应用商店、搜索引擎、各种垂直的渠道、以及类似于今日头条这样的信息流媒体上进行广告投放以此来获取用户。</p>
<p>市场部的岗位主要包括<strong>市场总监、推广经理、媒介购买经理、市场主管、市场专员</strong>等岗位。</p>
<p>其实,在中小型公司中,市场部、商务部和品牌公关部,可能是多部门合一的。因为公司的规模无法支撑如此多的人员,而且,部门增加,也增加了高层人员管理的管理幅度,增加了负担。但是,在大型企业中,这些部门是会划分开来的,当然,也不排除有的公司,设置统一的大市场部,然后把这些部门作为二级部门放置在大市场部中。</p>
<h4 id="(6)销售部:"><a href="#(6)销售部:" class="headerlink" title="(6)销售部:"></a>(6)销售部:</h4><p><strong>对于互联网企业来说,销售部是一个偏重、偏传统的部门</strong>,在互联网企业中,<strong>如果业务方向侧重于C端,一般情况不会设立这个部门</strong>,所以,在典型的以C端用户为主要服务对象的企业中,几乎很少听到销售这个说法。</p>
<p>但是,如果业务方向侧重于B端(针对企业用户),则一定会设立销售部,或者叫商务合作部,针对企业的产品或者服务开展对外销售,会招聘专职的销售人员,而且规模还比较大,目的也很明确,就是要销售公司的产品或者服务,所以,销售的业务职责非常清楚、单一。考核指标也非常明确,就是销量。</p>
<p>销售部的岗位一般层级比较少,主要是销售总监、销售经理和职级不同的销售人员。另外,根据接触用户的手段的不同,销售部会有行销、电销、在线销售的职能划分。</p>
<h4 id="(7)品牌公关部:"><a href="#(7)品牌公关部:" class="headerlink" title="(7)品牌公关部:"></a>(7)品牌公关部:</h4><p>对于一个小型的企业,一般不会设置专门的品牌公关部,因为规模小,公司面临的更紧迫的问题是生存发展,对于品牌建设这样花费巨大的事情,没有人力财力来支持。而且,因为规模小,产生危机事件,媒体关注低,对于企业的冲击也比较小,所以,这是不设立的原因。</p>
<p>当一个企业发展到一定规模,逐步在市场上有一定的知名度后,就需要设立品牌部或者公关部,来应对政府监管、公众沟通、品牌建设、公关危机等事务。</p>
<p>品牌公关部,在不同的企业叫法是不一样的,有的叫品牌部,有的叫公关部,有的是合在一起的。不同的叫法,也代表着公司对于部门职能方向的看法是不同的。</p>
<p>如果是品牌部,相对来说代表了一种更加积极的品牌形象管理的思维,会更多的做基于品牌建设、品牌形象维护相关的工作;如果是公关部,更多代表的是一种被动管理的思维,主要的工作方向倾向于监控和规避品牌危机事件,出现危机后的危机处理;品牌公关部,相对来说,是一种更加均衡的思维,两个方向的工作都会有所兼顾。</p>
<p>不过,实际在企业中,每个企业的情况千差万别,可能存在部门名称和工作方向不一致,甚至是偏离的情况。</p>
<h4 id="(8)客服部:"><a href="#(8)客服部:" class="headerlink" title="(8)客服部:"></a>(8)客服部:</h4><p>客服部,可能是对于我们每个人来说最为熟悉的一个部门。因为我们在日常生活中,也和各种各样的客服打过交道。客服部无论对于传统企业,还是互联网企业都是必不可少的一个部门,因为任何的产品,背后都是人在使用,用户使用产品的过程中,总会出现这样那样的问题,这些问题,可能是一些相对简单,但是极为驳杂、繁琐,所以需要有专人来处理。这就是客服部的价值意义所在。</p>
<p>虽然客服部做的很多事情,可能不会有明显的收益,但是,如果没有客服部来做这些事情,用户或(客户)流失,对于企业的发展也是有害的。因为一个满意的用户,往往不会和别人分享满意的地方。但是一个不满意的用户,极大概率是会向周边人传播企业或产品的负面信息的。日积月累,就会给企业造成不可忽视的影响。</p>
<p>而且,在互联网企业中,客服部做得好的话,可能成为问题的第一发现源头,能帮助产品迭代给出很多有价值会的信息。所以,客服部也是互联网企业中不可少的一个部门。</p>
<p><strong>在小型的创业公司早期,可能会招聘客服人员,但是可能不会设置客服部,很多时候时候放在运营部的</strong>。但是,随着公司规模的扩大,也会设置专门的部门。</p>
<h3 id="2-辅助活动"><a href="#2-辅助活动" class="headerlink" title="2.辅助活动:"></a><strong>2.辅助活动:</strong></h3><p>一个公司的发展,除了需要业务部门为主体来开展基础业务活动,还需要支持部门来支持公司的正常运转,这就需要为业务活动解决人、财、物的部门,主要有行政部、财务部、人力资源部、法务部。</p>
<h4 id="(1)行政部:"><a href="#(1)行政部:" class="headerlink" title="(1)行政部:"></a>(1)行政部:</h4><p>行政部一般主要负责公司的日常行政性工作,比如公司的资产管理、公司注册、办公场所管理、来宾接待、公司年会组织实施等相关的工作。</p>
<h4 id="(2)人力资源部:"><a href="#(2)人力资源部:" class="headerlink" title="(2)人力资源部:"></a>(2)人力资源部:</h4><p>人力资源部一般主要负责人员的招聘、培训、激励、考核等相关工作,包括考勤。一般情况下,有的小公司会将行政部和人力部合并在一起,称为人力行政部。但是,公司稍具规模后,这两个部门就需要分开,因为工作属性和专业化的要求还是有所差别的。</p>
<h4 id="(3)财务部:"><a href="#(3)财务部:" class="headerlink" title="(3)财务部:"></a>(3)财务部:</h4><p>财务部作为一个公司的大管家,其实是一个非常重要的部门,负责各种财务往来结算、财务开支管理、员工工资发放等事项。财务部也是在支撑部门中,与业务团队联系最为紧密的部门,他们会密切关注企业的业务状态和财务状态。因为,如果公司的财务状况不佳,影响到的是所有的人。所以,财务必须做好业务团队的眼睛。</p>
<h4 id="(4)法务部"><a href="#(4)法务部" class="headerlink" title="(4)法务部"></a>(4)法务部</h4><p>法务部一般负责为企业各部门提供法律咨询,审核对外合作合同、防范法律风险等法律事务相关的工作。一般的小型公司,往往没有这个部门,遇到法律相关的问题时,往往诉诸于律师事务所等专业机构。但是,一个中型公司,就有必要设置自己的法务部了。因为,内部的专职部门,相对来说,更容易与业务团队形成紧密的合作,起到为企业保驾护航的作用。</p>
<p>这里需要提醒,并不是说辅助活动部门不重要,恰恰相反,这几个部门是一个公司设立之后必须具备的部门,没有这些部门,公司的日常运作就无法进行。</p>
<p>另外,从职业选择方面,尽可能选择业务部门,而不要选择辅助活动部门,因为辅助活动部门不为业务的成长负责,所以,从薪资收入方面,也就比基础活动的业务部门相对较低。不过,这要取决于不同的人的价值选择,有的人就喜欢相对稳定的部门,这是无可厚非的事情。</p>
<h2 id="二、互联网企业各部门职责分工与协作关系—从一个APP诞生说起"><a href="#二、互联网企业各部门职责分工与协作关系—从一个APP诞生说起" class="headerlink" title="二、互联网企业各部门职责分工与协作关系—从一个APP诞生说起"></a><strong>二、互联网企业各部门职责分工与协作关系—从一个APP诞生说起</strong></h2><p>APP诞生的业务流程概览:</p>
<p><img src="/posts/47fc87c9/webp-1713627450431-6.webp" alt="img"></p>
<p>详细业务流程如下:</p>
<p><img src="/posts/47fc87c9/webp-1713627462705-9.webp" alt="img"></p>
<h3 id="1-产品需求调研与产品设计规划:"><a href="#1-产品需求调研与产品设计规划:" class="headerlink" title="1.产品需求调研与产品设计规划:"></a>1.<strong>产品需求调研与产品设计规划:</strong></h3><p>主要涉及部门和人员:<strong>产品部-产品经理</strong></p>
<p>当一个创业公司要启动一款产品,或者一个成熟公司要打算进入一个新市场,计划开发一款新产品(App)的时候,首先由产品经理开展<strong>产品、用户、竞品</strong>相关的调研工作,以此来确定产品的目标用户群体、产品初期的基本形态等重要的事项。</p>
<p>这些工作基本上都是由<strong>产品部门驱动</strong>的,此时还很少涉及其他部门。产品经理在各种调研的基础上,形成关于产品的基本规划,并进行内部的评审,在此基础上,形成<strong>产品的需求文档</strong>。</p>
<p>一般情况下,在这个阶段,产品经理需要产出的工作成果包括:<strong>用户画像及调研报告、竞品调研报告、产品需求文档。</strong></p>
<p>不过,在实际的企业运行中,迫于时间压力,用户调研和竞品调研等实际花费的时间比较少,基本形成一些初步的结论,就立即形成产品开发方向,产出需求文档了。</p>
<h3 id="2-产品需求评审"><a href="#2-产品需求评审" class="headerlink" title="2.产品需求评审"></a><strong>2.产品需求评审</strong></h3><p>主要涉及部门和人员:<strong>几乎所有的部门和各个部门所有的参与人</strong></p>
<p>当产品经理产出需求文档之后,意味着产品的开发就要提上议程了。产品经理会召集设计、开发、测试、运营以及财务、法务等几乎所有的部门,来开展需求评审。</p>
<p>需求评审会议,主要包括两个部分:<strong>对需求的合理性进行评估,和项目排期</strong>。在第一次<strong>需求评审</strong>中,各个部门的参会人员会从各自的角度提出对于产品开发的合理质疑和建议,目的是帮助产品经理更进一步确定需求的合理性和可行性,以便确定最的开发需求。比如,技术开发人员会评估开发的技术难度,并提出相应的修改建议;设计师会评估产品的交互流程;<strong>法务人员</strong>会针对出产品可能的出现的法律风险,提出规避的措施和建议,其他部门的人员也会提出相应的建议。</p>
<p>在完成第一轮需求评审之后,产品经理会根据评审的意见,对需求文档进行优化迭代,并进行需求的优先级排序,砍掉不合理的需求,并启动第二轮需求评审。</p>
<p>在第二轮需求评审会上,主要回顾第一轮评审意见的修改情况,确认产品经理和开发人员对需求修改意见的理解是否出现偏差,对于修改部分确认后,就进入项目开发的初步排期。</p>
<h3 id="3-产品交互设计"><a href="#3-产品交互设计" class="headerlink" title="3.产品交互设计"></a><strong>3.产品交互设计</strong></h3><p>主要涉及部门:<strong>设计部—设计师</strong></p>
<p>在开发人员进行项目排期,并准备相应前期工作的过程中,设计部就开始着手产品的视觉设计和交互设计部分,在交互设计和视觉设计完成之前,开发人员还无法进入全面的开发进程中,尤其是前端开发,在没有拿到视觉设计稿之前,前端开发是无法进行正式的开发工作的,因为设计稿最终会是什么样子,前端所评估出来的开发周期都会是有差别的。</p>
<p>所以,设计部完成视觉设计和交互设计之后,还需要召集产品经理、前后端的开发人员,进行<strong>交互设计评审</strong>。在完成此项工作会后,所有的开发工作才能给出确切的排期。</p>
<h3 id="4-产品开发"><a href="#4-产品开发" class="headerlink" title="4. 产品开发"></a><strong>4. 产品开发</strong></h3><p>主要涉及部门和人员:<strong>前端、后端、客户端开发——各类开发人员</strong></p>
<p>当设计人员完成交互和视觉设计之后,前端开发人员就可以根据设计稿来对这些页面进行开发,通常,设计师设计出的页面只是静态的,而前端开发人员要做就是,把这些静态的页面开发成在网络中真实运行的动态页面。</p>
<p>与此同时,后端开发人员也早已进入相应的开发工作,甚至在设计部进行视觉设计的过程中,有些工作就已经启动了,比如<strong>接口的开发</strong>,数据库的开发。</p>
<p>在开发人员所做的工作中,前端的工作更容易直观的看到,比如有哪些页面。但是,后端开发的工作成果不那么容易观察到。比如<a href="https://links.jianshu.com/go?to=https://www.zhihu.com/search?q=%E7%94%A8%E6%88%B7%E5%B8%90%E5%8F%B7%E4%BD%93%E7%B3%BB%E5%BB%BA%E8%AE%BE&search_source=Entity&hybrid_search_source=Entity&hybrid_search_extra=%7B:,:708439059%7D">用户帐号体系建设</a>,数据库开发,这些都是后端人员自己可见的,其他部门的人员一般难窥其果。但是,后端的工作又是极其重要的。</p>
<p>举一个例子,绝大部分app产品都要有<a href="https://links.jianshu.com/go?to=https://www.zhihu.com/search?q=%E7%94%A8%E6%88%B7%E8%B4%A6%E6%88%B7%E4%BD%93%E7%B3%BB&search_source=Entity&hybrid_search_source=Entity&hybrid_search_extra=%7B:,:708439059%7D">用户账户体系</a>,有了用户账户体系,当用户登陆之后,后台系统就会把用户的注册信息记录下来,下次该用户登陆后,才能把这个用户与这个app的数据库中的信息对应起来。这就是后端开发人员要完成的工作。</p>
<h3 id="5-产品测试与上线"><a href="#5-产品测试与上线" class="headerlink" title="5.产品测试与上线"></a><strong>5.产品测试与上线</strong></h3><p>主要涉及部门和人员:<strong>技术部—前后端开发人员、客户端人员、测试人员、运维人员</strong></p>
<p>当前端和后端开发人员的开发工作完成时,测试人员就要启动测试工作了,测试的目的,是检测开发人员实现的功能,与产品经理定义的功能是否一致;产品功能细节是否有缺陷,不同的网络环境下,在不同的手机型号上,app是否能够正常工作等等。总之,测试人员要进行的测试工作非常全面细致。</p>
<p>之所以要进行测试,一方面因为开发人员的工作量较大,出错往往是在所难免;另一方面,用户使用app的行为、环境千差万别,测试人员要尽可能确保99%以上的用户使用的时候都不会出现问题,至少不能出现重大的问题。</p>
<p>测试人员测试通过后,这个产品就可以上线发布了,这时候还需要客户端的人员把产品发布到各个应用商店,这样终端的用户才能看到这些app,才可能去下载。</p>
<p>当然这个过程中,还有运维人员的参与,他们要保证网络环境的正常,主要考虑的是服务器的负载等问题,比如,一个产品如果用户下载量比较大,要确保公司的网络带宽能够承载这么多用户的下载而服务器不会出问题。打个简单的比方,产品上线过程中,运维要做的工作,就如同春运的时候,保障车辆供应和线路的正常运行。</p>
<h3 id="6-运营推广和产品迭代"><a href="#6-运营推广和产品迭代" class="headerlink" title="6.运营推广和产品迭代"></a><strong>6.运营推广和产品迭代</strong></h3><p>主要涉及部门和人员:<strong>产品部、运营部、市场部—产品经理、运营人员和市场人员</strong></p>
<p>当产品上线之后,这时对于一个产品来说,工作才刚刚开始。我们知道一个社会的资源总是稀缺,竞争总是非常激烈的,一个app上线后虽然会有自然的增长,但是,一般的增长速度对于企业来说都太慢了,企业总是希望增长要快速。</p>
<p>所以,下载量、激活数、活跃用户量、收入这些指标就是产品上线后的整个业务团队面临的主要课题,这就需要市场人员花钱去应用商店或者其他各种渠道进行广告投放,以便更多的用户知道这个产品,去使用、去付费。</p>
<p>运营人员也要做相应的工作,确保下载app的用户不是看一眼就跑掉、把产品卸载掉,而是吸引用户把这个产品使用起来,让这个用户成为一个活跃的用户。对于运营人员来说,主要的工作包括拉新(用户)、留存、活跃、转化(付费)。为此就需要充分运用内容运营、活动运营、新媒体运营等各种手段来达成这些目标。</p>
<p>当然,在这个时候,产品经理、技术开发人员的工作并没有结束,因为产品总是需要优化的,产品经理需要根据收集的用户反馈,不断优化迭代产品的功能,或者修复一些产品的bug。总之围绕着产品还有很多工作要做,并且要持久的迭代下去。</p>
<p>以上就是一个app产品从开始开发到上线后运营过程中,各个部门的参与情况,通过这样一个完整app开发运行的流程介绍,就可以帮你大致的了解一下互联网企业中各个部门的职责分工和协作关系,有了这样的整体性的认识,你在进行职业规划的时候,对于工作职位就考虑的更加全面了。</p>
<h3 id="7、关于产品经理"><a href="#7、关于产品经理" class="headerlink" title="7、关于产品经理"></a>7、<strong>关于产品经理</strong></h3><p>简单的概括产品经理的职责主要是两项:<strong>评估产品机会(产出MRD)</strong>,<strong>定义要开发的产品(产出原型和PRD)</strong>。一个优秀的产品经理,需要具备<strong>产品思维、产品技能和行业经验</strong>。不仅如此,产品经理还要具备优秀的<strong>沟通能力</strong>和<strong>协调能力</strong>,因为产品和任何岗位的人都有交流,通常我们把产品经理的上游的人叫做<strong>业务方</strong>,比如:老板、运营、客服,甚至是程序员。对下游的沟通场景,包括了:交互设计师、UI设计师、开发人员、测试人员等等。另外,产品经理虽然被叫“经理”,但他并<strong>不是管理岗</strong>,这么做是要让产品经理从繁杂的管理事务中解放出来,专注于定于产品的工作。在很多创业公司,产品经理同时管理项目进度,而在成熟的互联网公司里,项目管理的工作也是由专业的项目经理负责。</p>
<p>尽管如此,产品经理不是神,随着移动互联网红利消失,细分方向越来越窄,尤其是在大公司,产品经理没有太多自由发挥的空间,更不会拥有战略主导权,同时具备产品思维和商业思维的人还是占少数,很多想法都是抄袭竞品,或是沦为需求翻译机,也就是胶水型岗位。</p>
<h4 id="招聘建议:"><a href="#招聘建议:" class="headerlink" title="招聘建议:"></a><strong>招聘建议:</strong></h4><p>1、从事网络货运的产品经理(好伙伴、阿帕、达牛、满货达等等)<br> 2、在竞品公司工作的产品经理(货车帮、货拉拉、快狗、滴滴)<br> 3、行业经验欠缺,产品经验丰富的产品经理(正在/曾在其他互联网公司,准备/已经回赤峰发展,人大概率不在赤峰)<br> 4、内部培养,很多优秀的产品经理就是藏身公司内部,思维灵活善于沟通</p>
<blockquote>
<p>作者:UncleFool<br>链接:<a href="https://www.jianshu.com/p/2f122dab8726">https://www.jianshu.com/p/2f122dab8726</a><br>来源:简书</p>
</blockquote>
]]></content>
<categories>
<category>互联网公司</category>
</categories>
<tags>
<tag>互联网</tag>
</tags>
</entry>
<entry>
<title>如何在竞争对手强大繁多的困境突出重围?且看Insta360如何做到</title>
<url>/posts/cd2752f2/</url>
<content><![CDATA[<div class="hbe hbe-container" id="hexo-blog-encrypt" data-wpm="抱歉, 这个密码看着不太对, 请再试试." data-whm="抱歉, 这个文章不能被校验, 不过您还是能看看解密后的内容.">
<script id="hbeData" type="hbeData" data-hmacdigest="17206b906d20c4c7f15dd98ec1833e28f0cb53a5ab0f2b89dc2661c0fe3fbb83">601b7ad76f4fbd60ff466c34909923e9c8f637ce8db723aeeebafec606bc5c1227dfb1f88714f33fd513c7611c97f3f72b1f02a58bc4f85c62cbaf83e563823a8af4d6fe76644869ccecbdcceaa19a1d7b91762398677edcef5454d0667e88e57b160a93d70086ddc47b44eb9b5acd136af0ace4dc1c7d3182ab73a876998d3c0e092f5ce382fb1f22fdf73d20e7243ce4f2b9eddf91e3fc632184829990a1985ff6a7f5d971f2543bd3dd9085fba06e64adcf47c8b4e57575c384c172b0916c67d8f461831f8bb33874d21ed64ea2c3fbe9dce478acf6eab56bb2379d00c8176dd5a1cad34370a5e74da095c9be7353bd02f2d47c04c8ee129bb7805c4263ae40050e1b9b4a08cf8107eb866e86872d9f98a88c38de1c7a54d14fe6aec15ab42dd556bed27a764c24328a1610e34e43b0b8a79d740c5d8a690076a40c4bc332f81ef23a4fd1adab3595cb5244b3535f3b8ca0a490846e6dcedabc05e3a728057343a93324fb8e94d37cef70c850d0c3cc8f842dae0b737d1f92435deed997236656079dcf8e3d7c4d1fa82b36151e4014bc7cdb18af2294783881c926f2a73a41fdaa809d8f4c0e645a0c6d1d0379d832ab460805d3516145e0b3ba8ffc39461cc51fd370d50cbda3bde267833b86b05a68edf9404ae98dddc53e376d530bbfd75537741aff8442382f4a3feb20a4623970a63acd9ded662ebe56d7786a724d12701fce407b0b6bccb3cb083ad5f8597d1f67afc0084703d403f5032679c67130fe94ee59ac55f2a45acd1890417d82b920364fcc4a4c52d2f68c584db55c7cbcdb5913577c48fc44d82fd111e49db7c244282c38520c115b3e2335190d7d95154bf0f84ca5c5d147d1929895239d9c6a49cbbc3b4fa141029559ca9171adeff0529a187d304fdf0b6d677c97526e8f624da5877a9f8c6c025f751473bf6a3099f61a87d95b3f43f54f81c7ba50e790fe730e698098fb18be086d5c5c2ce5308d409ecbbe916ba42925e594b08a87f22354d1eec9d6bd176add70824f0560266c2a56fba4e8daac98eedf17139586f90c013248c7ed44b132e65685cd1dc5065911a211481f328c37e6cabd97c05891fd9c6a5adaf41fb0dd08aba6ac5b9be3cbdbd9991f678c86b38e55c7d0bc36853336f215c9501064766ce6121545975e19a118369da0c522ee14d3462ea8212240f6b31562837d65bfa081354d8465a7c98d84b0d39b75e3f76c37b9f4f5f005a993e590a568daedd2d5c2c7feef77c51144fab886bd5779f6129724fbf71874132be9a1f7e98498c19d76b2eb7a845b9384aae89bc59755adfead0dde238e16a895f633347310853e3bca74fca81feb856c3f10dd965b244be54052f3e08290aba0580da126ea4a887ecb456f4b689a43f942b4de0417adca4e0964cf9235705ccb20d3aaf7798e294dd1e7fbecaa2f5f83b17c5920c888b839ec2fe2517d37710bd9d30b1ae7bdd1a38a11771bb6397bed15838fe3843d55fd48f43ac248062ff4b4579035b3d8f8972dc77d48715d1d76fd403957a5b5ad3888d5e54c37a2a88e057e3a4adebf9b3756ef8c960549684e3af2c8e088a3a5cee4b1ef12614edc8b2612a3e28b8ff8e74255ab605cc48ce2afb590f239d41e10d8efa689db84ea106bde62cff98c3e934c768c40a33da4a686206b5962d227ae0e7fc91d3ecb1fb8dcf8384e0930bac448b2fce9452a27f36311c9c3f7be4fda20c0a00630fa6f7295672fbb9428137cd31ee0a1a83a9b627aac37e24610713da2c455ece5b2b59c9f093167649cd94f110c29de4e2f5dd122a6b276bcaae196f2fc8ea64c7063a79e8198b057d3e530ad1d12330806e1402826aa18acdd433898a120a6533358c2e5ba99679a6e4caa1d27bdc4777a97e2f1994806bad27c13c8ea8e17a5ca871f6b93ac8a486b012e26088ba32ddd870fdda413c85ae3642445e09ae552cc5b264938ebb41308f4ed18ac712a76f3599c6d60e6b85219abb2aac3338d6872a9332b6c351fe1d8eb1eead1e20bac23df178284c80402d469844fb045136768fbcad1373f43f158753e382b46f7063d792711055f69c45719c45e97c06cf4b782619cfc57da2113ebcbf9cfd7eb384e74fe76e96fa3f3b616d9d115f762150aecd9219b44cc2d600b90bbd64bbbf8d2089d203a06d86e2f1fe5a25484f04d016a3b16eda00303759d4fc1854faaea8d286c335071b309a4faad974fc19f2c30ba6bb36af6ada10a0fc5d7b356c9dfeecbabcefe82e4ece4c78adfdcc8249a4fd243b1cb223525858b8ce431daf8bf508ffce9e2107b5ae4934eb6be1e306b62abfe65db3ae3cbef8c33f22f62f1a9cb7f67ba7e871166ef15e2c662f53ce74bd9c66df7294959495f6cdae7b0a5504636bae2ebe53644c06b4eeb685c2a9ae12718a3a4aca1b0535a8044f0c6cdf411fe9483504e83c9ef449488849db4647cb1a34810e00e32cb54fbab0771218eb7c7423cef77c90f4411f2ede302b5c6d0df1e6434c3f169dba45d331841012452c826e7727eee0294b77f87b4420ec7ed55de7553ac9926b79533fd7074a583bcee712bc3ce47111dcea99a14a52233572b6ddbef38c5b795dce6b56198b2bdb4ad6cb1493837575cbb2b3b72a637318f83e07ef4f5840b69ba27ece172134bbda210df98bb25de5724d0c1f48e1d8fbc8d51a627795891b90dfff2e19318f87b064d0de723d0de17094ca2c7979add54e70541ca8cabb8caaa3f5f8baeed71debe27f63d7f6af3e9bc8f32c2c18c2708d17aa1883bd74dc3dd6c6f0c19adc9ab50dc90d8ee957b8bd51a25e4f89a4bf7341de3970919d1f8aa20309cad3b3041724fa6c56a6c18ff41974489fec05ba4aaa48208a3e11f5ddf5b8f337b4a2f09a3a9267bf44dcafcb0660ad3c46bfe99c846188cac330bda8bdd7c4604a900a633d1aee550af53a3e182e8a8dafdd220121763d77cff7ad6472f42a4474491d1e062dad291c29a605df4c0880ced439906b4eaa5830e152854ae9003dc83eb3d254625ae450711ddb986326582972bd6aa46e943b6f10b6dc65aedb8d8b959c1504bac35a13d4d5311cf985f00ee000b05e0d0e744ea512ad71e3f3d9315b9ce2b1243af0a23d4ee85a09fcccf4f020fbe17d6ebf94b8685a3120085468df0e963b7b5626e8e40b4a0be66b34f37e1f24297aba3d0da5aa858a22b6ef64ffc41e5b541884bb039d52ae3fc4c0a3f48e1de5ebedaa5ff075125bb1d056c00987adda087150137a7d27da32615b6fce9ca8b04f373f56d6415e367ba1154e796121368381701846790a91d4d99660eb55216b7a0a8d1c4698bb4ee84e0d3557f20f31a38dd39cdf7889f989f753679cdce6cdbc23a546609e7d3f8ba3814d1dab71262576552edb8e0d0bc646c91661713998bf15db11363f739f43f68bf03a43070b52b573d48df4328356bd3209f4f95da3f436e10bffb66f22d99909ef470132e87f0e7940711c18073800e5e2a4b7f7ff84d18e2ffdecddc1ed72ce1db440f570c5165eafcd1a0f8ff353341a45725cb20e31359bf44b10be846111dd433fa6d1cad82f0a71876467c7003cf088fdc27461aa832acf06abb2dc62de54b808c730f604793465d07fb13cce15b231d2e373cfeacc25bf34cd07b3395e92e8d824c1f90fc56c1ef637f20e8e5b213d6449c1960318f5cc0848e29281063bf6c4d46a9da5445908fb32dc2a05f6182b2b08da23897e86aac133cbf9984e81f2c80f3e691e57592f94e35b98b2936a020f161865abca6bb0021af8542e99bd06bc995f83b54f0c24bc78b7d6f00ad8bc8db4386e31a6aaf15f84879fe9dbe2905dd2595167ffcad78041d06d7de8e3d8d155bda8fb0c96f423c699464b1629d32328fa5568c054e7f2700cd1452904302fbc4d90ac5a8d3814691c6fa2fd8ed1781db07c8ce94ef9a618ba44f03950b5eb84554c8d40d28bf8a2cae99ebb6cd5f3902620bb2208776413df43001c8739c923913f292615b41762650448627cd313a3f5cf47d9b8afbabff157da801364b41141aa1451cb5d31de7a1eeb597e70c14a366e95390a82550cbef98a0dff91fb244cd65f00d6ac111989c4f41675de85ca2861207fa90dd22344280e2e6656b63ef6ad9d970ec9826ea4a1032ecd5074c320cea11067b5c8dbdafeab765479989103f8387d54cef1c7d88ddd60ed6d1c682b4603f3b12f8c65f3f265e5f8869f9e529abc5316133a534ddaeae63fcb6d9ad34742b1bb941d347d85689ae780478bb7a443b5ce3b486a1c0dbe9aba2af17f7bbf05db3f53a680fc9d4d31e0630a25da842a133a5c9fee7fb92a92d3861e3883f846dc0efa957a37c88300ac783edcca96decdf85326b7f649cdb8db69693afb01f09346ac51fbf57fb4166368d4024044fa5245ef6a7dc98d62419d017ee950dd80659372a776c2608a1db0a66060ac0234304a8ba5aad6f24f1c325288a55f660a97a0964e19f9a84c5cd6ab839260932ac98233f748511604cc4b565e01dd29e2f547a38a829eb15188b4809dc9f852c372e7cc889bb7a03f019dedeff3bbca2c70d27d5b3db2f0ad213f0912d03d996726a35bbd32592d4bde14ce11a20ceb3647a43977b74ee20f166d17333082c5a9ecbb8357dc8b1892398c7d1f6f01200af14da0f0ac771c7d76c55f72be710136304c2a3e3b8169a799bbdb7b5634bba0a011673e6ce1142cce5c84c3dea8383e7db1c0f52d1de04789114ec570f68aafc430e6a2df10248a912aee525c54257b40c653de6d718dbf8a6260b5207548bdb43f04d9b6ce660791c2a5af1366334ed6bf96e6afc15f7984d2d6ae33ce649c9f44db1d37472bc3451bf17707a47c1ff607eea38a17f161859639759e0c318469f369adca425b67017deb6a2e59b61225065f2134fa27c1b4498a50a8be826fc048026c118789af470e25e263dc9ffbcc0aa01519509da99459b49618fea7f02823eff05f77fe7e1cf166d789bbb728aa4b017d92fe7cfed0197d32f5be3cd0c799842c1cc418eb7cfdc92b1f2dbf4cce7b8ee7063611fb2a3859af79857f14abf7238ff3af822eb173605604a26fe891836acb60ca103bb7dd3a2e5b8e4031a00d913417cc6a97276586e4d56b0430aba4c411ac0cb70cc3e86f733e4c12667196a6c1b25fdd8dbaec6dd2cc125c9ee03e089cb579981b2746c69df5f0fa230ab8f1c865eb32ba10d0f0f2b9fc51f706ed7d7511605b8ce8411d2f28ccf448e0684ce67b3a4aaf6853047a3e6f8b1d533dc86a046d3f28cdf22427fce5a6f415753bbef87ec7021fe0f481ae1685554981f17c082c939320d9e4a4ca1ed984009edb78423b7f827a1357218df28045084f82764cf4518daf19fe8aeed348db4d38c0d7cfa7875b5bf72800aecafc619f03204655973354d39b8d0ecb26c869566141260a3f4a6be04298bebc8837485940e5ec68e7702847ca3cfbc1843b2fa7f920f6923d83ccaf5adad2883e6a743271688625e524aed8c397028da0192cf3178ad1ac27cf092e13d0db3b7260cd9667a6adc3f84ae69d2884c9a07046660bf13e3ab370bdbaf89a26a4789f8c2ae4350201b00f158d0c3d81d8a53d22ad7178e73e0963850411f53540aba640112e4b6084e2d233577b2aa6dbd9fbdf49df307637c48c5479a23701519d83a83f6e1301e28ebc5d5abeec455fcac24ad4850f5325951ee26d5b28c707b2eec714408d89baf25f7353a8874c7010ef621e22945d0337af9ea56d4c2951add3cd7436074c7bcda57a89b2a54074b8a40afaf0371593a3e8277fc81a9ec8767ed1ad78ced0dc60bc0cbd503d6577460714a6657ef84a015afcefc7baece8a7d7b607c508d18b844c4a2e213dd5e194f9b8931ba40422d6c1de4416fba295af3fb0cc70c301602f701550fe226b3a67845dcd41a0abc2eb22a3030a105c531cf914c569d6cdea8b3976f78a4ea8760b7d27df272c5cd6b417c65c0f11f4de86c74fc610d849ea4dcc54aae0eb9631a800e06634e6441fe18301485e9307508bdc9ae76e174a79c0dc64d358523834ad1cc82957980bec6b589afb5cfbdfdb34d376060963811602f09bcd53a3ec5c442fc1496420ef8cced77efebbca89c75104f5da48e3f298d4aeb585b21958cd722db681a3ab94164c183b420785fb695c0b0aee70c6b590ebfb44dfb9849721e4b47e166d2ea912368d706549c50a3a3b8d736e2e4f8959e55a1eb89b3b5272a959d7348aacb202dc019681c303f946308bc24c574cd3712d1dda833d2806c8b80e1e9a0128cadb8d22f601a70b6b4303f15630d56a3e13aa792e665447175b2e30d331ba72ad739b98d8353840fc12a5ffa61e4f689c32d2dfd2ed9dedaf70bce905fa16f3d97e62ef86e45c626e1e454a4aaa13563710d0aaaad65b19307c322b2d42be4fbc5ddfadab48c13c79a9370ba0beef25d2312da2a816f98f7af295e92c75f924b1e92b051ca23217b6bfe88c48d05026970de1b612dde7d3d7da60718875433ac782fcda93bf35de0d61aa21ee8f73d0395c2403f291d8f9389f1685232c7ae007b8b630c27b248e0f34257f632c7fdd97a8729619aae80ba630b4c18b57a621881f7ac0c1d60348d1a663304ae5be84f00c49a572201c2ad6e8cb029a0519ff17e890ff7acde5c2148cd967457c3a7aa96d8942f21a484ceb770680d1b644ab862329260084c03061c39c46b2f2c5fdfe6dcf0d91392588904358fea171c5fa48c6d3ea04a362d76122ee2d6a399ecf67b8b19f3b6815b7b3641a571b861a9c82a1886d364e43fd52448a0eb84e246a602907c810e274ec32020efebfb9aef55c21d3a8246e6163e3b1e4fe4855b9bae42416985047caa9df9a0405e4d1672b2867d5696a07932444fdf8917108fab46ab10f03b8d99237ad35cd5e959e1d24cab28d61530ad5d7d2e6442a980baa94b07871b26d17698ce2343171a6aa8080fc407a9a6abee6f1ec0607e691d4133ebd0c7f3f8691649160002b4f36d997d19fea905783831d8c8437e938f03b96d29ea21a7152e3f857f16cfb56f3bc7d72d93d23f5e4226e88a85a82a8a99a28684c1345ad1d9388adbdadaf81e166dd479165641e9cc001e2614b1a1568523b4c1bdc2487ad3deedfc49e968fd92f536e95dd8555e483a5ca3ae180cac4de20481a4b0b8a23f2851afa12f61b35f30f8e6e6ac5212658741a76765e81aa524272c20f5ce34a9cf83910010dd62dbc24a9b6f3fbd2c3b848316168e92dc97a430610020b47b10432fc0672444f4a1458538a720a7cf1396c9a784df22cef5969c9c2fa2e026ba2a9d4c6f33abcd3fcc9da74b99ffd9410b5c1b391ac6f4e02d643ea1fc90f12b36292b2e34c8121a6f8a82b52ccfd653b612ea36c7ed4923e6d741f50c632c24da936c187a812d0757e6773f1be1b542f06b498314671e2032ff384d31798adfad9c9c6c54b1fc1134f6fe41435a29ac50f401e456212d7cb5144846b5305388538ea03c479c18e5b80ea7b8f2000e8d418f9dda711e9743cda21894267f8337a4d3e47ea058632cae852ab5e323e1668a2498fb15cb513276f03a550717a28824b9e76afd59e401685ed74570a3aab347957c2eebda2c2a36d0a33361f6aa9d9ac9eb9e093a666dd2f826cce6ce07d4ed88a014022203879130457025ade09fcc40d1587366681f4721d355ea60bd3ee73b7ee2407147716e4da19a2fffbe317d05fefc08da419deb7cd7fb53ee3c00336a51757bcb0334b5a7b426f8ae338733122b611e20a0b91cd1ffc89834353df22e9cc9f5de1691c724e9802f7c08bab4227a6f4747bef5e2f599c43de30e799d5198ffbaa9753ba339aa54da1d8836d826dad2333e054013e7717216f38d192144e1b97c2f70ac5b8eca0b8026bcf1ffea3434c3f29abebb8a22c12374ce0568cbbfad34df1d3ee678c9a3df5f0659a08d6596216b7285c1279c5d40b13299910cdf6eecff4af6d2d80d31e267a0b7eaed73370fa78f18b50abadf3b1b23c00b17b4994d91dd05e95398de94b9c4adf7863569fa668e18a57b56762b658b456ea8a4ebc8e202ec9197ee4098d57ceb7bbe9a4582952fc6ffad1f686ab10767e2d64fc3dc2db412741acbd90f6334081aacb3e11fa078e8f801798b5d2b39bb845804163dd204701934c5121b944dfa78264858790d0849be97b20b55b8089d5a51e155dc378a3960405774f0eec86b0f348a751d6c4f1a510066b1aee7de92c7a7e30d9f338f500df4c7ee85d54cd20e181f31fad925de411dc7a8a4df8e39f30594085a6c7e5590955d612e9a8463335e3deff281c159207335a140060e5ebd46c941d9b8ba43394e9fa85f8f69fc577f919592a73ee26ebb377e01f9eab7f38b9715173cc543904e0949cee3c7ee1b8dfad9be02de1d66c3476e6024244257c70bd0b01b66f13f75b8037b45acd22cf22bc9058fc8cbf4081215e2c5a81362e1d50ce5143ef488529c68e3c306a1ccb44baa2ea01d124e2adcf088fd88b77b7544d429a95dc045c0c8299bd0400c16ca00c1009e790a952d017c3b01b613197341a2a617c456a93913001b7d7d792526e3648e524dadc2a01e04fc6f199e7b8cf3b378fc4824dffb625b65ad1bb9309b1ffe7155cfc4a488c91e1cbb3376f5c0126122a2c5df93990b886f84116892f040cb8dacd9bde48432fe126bc1460516deca56a1d782332c00a5119fbac0f3f2679212e8d1e5856ddc4cd9af5038a87f9d0d02b1452a4238528d7aa21ef1b5090ec5500151bfa2c1215b5cb166097bf1a4b2b530e9cfd861359ba2f3072e7d661133a964bb20a2dcf6378924bd79923cf11b68ca2ca9825bc591fdd482979cf79024ac006ea8d425a8fc12af6c02459e5a7c1a9d2fce61db1443b00b05e42463632eda1104b2b70dfd431ee9345069086e398c4fbe564c7d248e812ff2e4729f52c262d4f7160da82917e65d1204ba001d034f45c9782a3da250b5e12a8a84ec6d128e33cb9209bec9c5fb91d704c65f036bf33cecfc29f9efb76cde80f9223c081a379f49d7ebd4126c1d7ed6634b072b8f5307b543a6511697a41a00b8581ecaedc14fb6de4a437eb8e44539252eafc264f205ac4e95ddddb406f467ab5a57794c37f47d021df31d637508f7ebad0d91ca39de1f984bd6203d28c25fa76543f6c321b692fa3220dd757e43a90d260e12358468ba462117c0aeb714225d2c5507b1b5e14649a488947b43e7ac773d33077f67cf009d1237024e912f0e33b8a0708e5d1f171ab6d8c25f3d5253f6dd5f9cbe6fea2a85b895102e729a40070145fd9b8363ffe16805f1e579c55cb0ebd1ba44dd8dcdc3fd5e2425a4514509774a5ec27157afcbd0628ed3c6a19e9b43dc3f6938b6f0e27b358e215bc34201ed52a80b31fc226316393b2bd504829296fa700bd19af1f4ba0824ac3aef6e4bf33b444d2dd53b78f76768b0c709510d0c0326c549b1d68b9a78877cde7c5213037dc254d690c909b61130b9fdb527d0dcab170f220f50ec60c80e42d67d04dcb9fe5d1ffc18a76a3c40f7938bf7666d91ca8db6dfa31a3dd2811ecbe46a0d249027b95e0c57aabb8b08ffe54f62c4691904d17ec21d5d5225b797ba5fd112a40e81b3fce55382d46b519b8c8de949925833ea33bead8fb875e382ca587c26062bbf7506c9e4edcd5a0b4cc370c8a7c48ab11093b5c408c7c980357fe6b6ff079cd59fa2fe1573d39cba2c8d2fb061e11ab77f53468977c15503a2b57ec2c778708597ab7b17e63480977b3ea8c46d7cdf119fdb1fb6761f80f1cb227a6d48f57bc1b50d66240c07fb913f40ae015943bd241cbd749c787f4cee6592cdb101d0e8b666219ed3bf9c372f3f20a1ebf7e3460da3b0e30da7de68eec29b7838b7565e870f460fa6bbdf7fbe32849c8f74179b01142d613656b828372f12c77274a062d6af3481d3d544aae2025ce2b87243ba2ebf3bfd8b49392805f4ef9bc621f0ab7f490881196429049890c18d6970b1e19a2cc340436721fece33ebed8b4852a73c5b3eb095126f1701ac4dceb9f1ea9abc6939f547da9b8c651d4f53f4a8b3dc78dbd058b3445bd3354c1d29144759eda92e54b0ff3d6b51399b4498cd0b12f49365bd696f2ccec334be22c475085cda57b7e07d2c87c474ed26241a9cd945d69890b2237f4bac625a3fdcdf8f18335b25b4762c635310a2d0415d3576d935444fc0970dd3b61f79d106d3543feac4966a6f0f117f84b68c442893570832a784ed71312f4688f2fc2788309c9692d20c10283d5a8383383aa402d65ff54a7efda0da3a9720674424ebcb349d58e5626f4a3ac8979d2a63d2fe29050a03b8f81766bd8a5bd79dc5da71c2844f260c7a9ee34f04d3fb10b1cf536e21112e684f409db8f4729f79ec048ffa695fc21660e2af8d5ce4d1eb4ffe131daac7da488dfad0c0db91f1638eaf4abd0c67aa2f2f9ec5927e2795bb73192ff7defe5026cf84c25a7231900f2cf17c82f1c22735b89ecd7e9660c6306ccbd5815339f0447c52af1b47aef7829580f12afd37773f1351bfe1b089b3b0d9ec7ef12e22e34ebe87d8b32a5be04bc0983b4f01c0229c12f67b9b8fe2eac1659391aecc4c978f1b76cef3131f9fb1993f3e328adf1b1bb1efa565954ee437c7223b6f62b8dc31f47de2160e7a6f637bcd1de5a0708a7f95002ebcbbe1bb378d98e7d6e199df61ba33399358bd7fb614e7d417d1341ea616ee0d1c4bbe2910df4f53eb1c3565e388dfbfcb9dce8e75b292df0118978dd7968a7fde1867cd6cb35c2b9fa225f3d382ef55f0e68af02af3103e790080e3a655cfc87b2c2747ea301c789844f5052acb5b6c08fe687d2c4fd4c273b827a13996c2cab10fa861c8018e0d08a0218ae3a7cb6e32591b563c5865c683cb373c3f0f3bb8c2f1d4990931ada282d29c27eb85286955767231c01a96fcbbd0bc53ed89d086091c641496c33703d9d0d4f95564725af0c6e0f16e163c6a129b3dffc7368151dbbfa6519b7ed9e8837be23410231f6f360e0527f10be645b91393e9a6e9d1e9dfb0f7d7c1d4e97eb721f26ef86e0b030f178375d3ddd29e61cf0be1f18f955e900ec4d4d2a2436145f6f63afaf0963b4cb507e3b828eb74876a8ca7f8eb05c804c90917f3f8282f24895927b6f3ec1a490cef8fe9436b2a0d2b82b6575244ac2b264ffd2edd66d10ab0e6e4e9406ae86f6e486143b811b3006e8f98ac9d2805cc31aa13834459a16dce2e1fcd437cf1150c609f72719ea0b2bdf5eaae33967e3423cb63540b2c2280dd7e558892a7af91a62a5bd4d3ad1c5545ab37bffdc4f65b5cc10c55d6285ea72f6f18ad3b01246998916365ad71b8188496f11c1f33843a78b1f34ef94e862e0f24ea1daa5d3d6b1e344af9da5f18b89a405a4ab8fb771a95509d93cfb72531b8c257e51bff074ee47e3dbedf7e60393f48db40b787481fb939294e4e6016a2a48cb04076149bea82254002a89aea6d570dc5e1e7b8bc0a55a3e1f557d67ceed9a4265f3985ad15f3b1663c2985b7eecc44ba7f82453d3bf883493e6824120a4be21cec346512ac09727be1141be1a9afc6d3f7500f26ded44e35cb1a3616d364d001204bb14b9f1a7bbbaeea27c4662f88d7dedbe09860e4c093176fcf4c29d03e8dd0383712419fa591186642e122ad935fa405c89148b9cd5235ad0c8de96df377b4036a0dcb1278635a83b80232904e10e5a6ed213496544d18be210c1c084ed214b08849e49057ab7255efe0c021987f3a2cf4a5b6e2aa03d91696d59f15d64edc58a5f2066c725e1f5df2dd187709358bbf8184c8095c632f61eaaed33c4d50cb5165495bb185828f46e7d245b76c887e7ddd6d01e26e20e80e6cfa768e2e5a1fd4a6021d365f2e019dd381fcd0b6a084db50f9bd1b519bdcbd9ea7a4024b75cbef1afb3c1ee9114b8dce27a41ec4e53aa8043f8a12556def899432ef9b19ceba8bd3989c0e5fae53862c55c5b8b892512925d05375e79565cf5122812d7441720966659f729fadd577d3b6fa5ae3498b452b7eab7ef2c83f606dede07662e7402a064539e383176541b1ba0d897ff577202f7cbf67d599b02ad5f911e2fa574010ccf8db3b7a3a3327b8bd0e10879c90fb03b38d432270ea6532c5d35202cb1055900bf6c5116dda19ca4e442abdcfee47434251784615f1aabf47b796620a1058a71623256df0d88bd995e1c3f6746e34d00bfcffb7dc862a70306e02d38d2bf4dfddfa7a09e279f409b223637915f87187fd349bb5afecaf1b6ddf4290c6e06b8067bedde504cbae87154a351cc568b6f9c8e15cd9e7ccaf15b1c4a73c70e7463649455cd6126db299645ebeebeda3cbf2d3c6760ab48c67716f5b38b92c97587bfadd1b80935ba68ea364e3b0ccfa99b425f7b534717ea8f71906ae03b774bf73061e100b46e0dfcde135fbeaed4fd7327c856ddcd9b9c49b6109b60ce1b348f6b69c62adb835baa1245c3202adf51d3ea01ab7c1717a2db1113f448fe08470f71c70c808f0cc4c3e32a011690f17903e6a07d991259901c77e6b9f52c7ece4786ddb60825cc000724847f2432bee298ac719d4bff63e43ec85e849422f24b69b407f19a139e59611b81ba850096586385a7617203c14e4680aa07bf757bede08e89fde57722fa56bd03bebd43fdf6ae09b2bc76f1b27a775a310bd042de6cc494440aa20b8ca862402fc21f85a931657b1bd334968cb95e3d91670530df41accaeba561f0a6d1201c27cca8355fc4b3c257d01cf12f4beb9228027223fe5be18d52850905c6b7765685263240a0827fed7bcfef746d231b7049e3c8ca1180212fe641b0c881ce82e6d1be2a7c6299698dc4fdcecbc0f2ee399a3aafd3498eb242e0aa3df379fe08567baf8e3f7b032edad54f1ef794f603cee487d1146fdb43af9fad832fc491f247103dc6770d020c42f1833aed7adc028423f096836a17ed7ddcf9937c89a4b8aef6d1992d710db0a776d45b57b2b7fa2310d2f7afd113d2c82f2b4762767c1977c85b958886ddcc1948a70cd65a92b1659dca1f0a1eb6375314e463e7dfbc6e34120145b5d9829f5a5a51c6e446e216674d4a3b4e91fb0a15f003c865d2f5c7689e6a6ea38494835d76e63ba16025d1272bc23869d7bcb97b3b39e5f2463a3415bbe10b30d8c69f24099605ffac13fcf1b2d0cf52a0226de363a09afb735be7b6f7a798f8b5d41c9876cee4d85b56bdf2b2586a9b842662245f1df90322d3ff4007fbdfd1b8a651d496a7882e4d11af8f989b715bda9578abbc8233a354fd7ed20aee23b20e21b8307e0d71b42471ee676acd2a2f1681dd6838732a453a82d072f05ba8cd1c4fd9de55d85e439c9ef7011f6b3db7df2b4ef2298c17dcaf49913a321f0af0f2e0ce7f1c7c61c1be5e4d14cf81dd4655255e7c45e2802851f1e0d59a3691b626e7aa1c44d9eca7fb0285db6a152e64fd5e09c91d5f6240b3e4d1740b31b3b9a2eda4aa9a70b61b435252f7c1a1049e9489c0486fd93dd711976a2c9ef8f6ae804bc364bfd66bf1678c615a0effe1c524cceb877f38ce5f5de48aba4816223350a95ac8fb090bd486623bb99deef512ad4499d61e082bd351ccd6848f61d4be8c748a12a60728b148758a6cc15f19112e305206ec4fe6ecdda58deaf0929dbed5dcc5966925ffe879a90317fbb4acd3f775d3ae5894378ef9ba92050969d69eb39cc03de08bd2cdf4813ccbb3d42cf29d40cd9cc7dc931e7fb76c8acd8b756885339cb1e583961f465741e62a2b11d1e56068b5f8342628ffd3bf030ea2b0d9b535dd2fc757f7d72f625e9c099a3daba56431e527e431555f52a762c0a27e8a41a41cc4eee698f7a7b04f76a54c5475d5c6488c3b83418489ac3ab08e3947ff7544fbb50004f3b49af4771bcdedbce96c3c2fe6e5c8a4724a44f572fe84dbac9566cade8556ba22b597a74cbb896faaebc9ebd44607d51a049b46606bf601b0ea0ff5e3f7b369da460be668b636b609e9992405b9a86c5670e7dfcb1a11353fd3b332788a2fc53da1773a30b5c7f6600aed261f02ab978e7e4cbd6dff06f4853fead72ff30b0c3cc735274ddbcba708d6664243487292e76720aeca45ef7183fc7a61cb656922ef6a163f9dcf770dc2010199d2031a503bb6cede26d81ae89e9051beef57fe88a24db1f0a7b4e87f0443a38cb0a92b4f731293cf2ece6d2d1ef604ec1ae1c92859b5f4a57ded2d3703394e2e103911291264bf5a0a2ff05dc69b64a99f038e927918d2294a348c65f8c824218a2face06fbde22ae2c6b00954af4cc9ce39163c39d8e4bf9c16bd9ee36e938ccc6fbb956be440708f7b5e81d85f3b306c69f56937836d0b6d015740d322ba77597fc81fcd3f8a73ff331d563ab6ae2831355a927c3512908ff61a0bc26ee91606f48952644b5c715fcdfd54ec286bef589a6e52b4d192eb71421b4698d8315d134e7674790ca2088ed9da4286f06ff0e2539040c4f0424218c9f6121f228f8b99d1f7e641462f93852acd6faf4bf2092b01b5df0fdc62bd17605f87f497aa851e5f657dce700e4ec12358f7aacf4a466154979f461830db417a2b2d18c81e06082c6653d48ebba08045bd6156e91b133eeda1b85fbdd9ac3323839e2ec8e18e310b0854bc519aaad5a42ed42e5dd1841c7b38b1b551509d6c1c25c6a34eddfa7ede0473a5ec7409a4333384632d52a3b92f7d233cb23f701545a20995a5dcc3c095cc68ecbfdcdab51eda78bd2bdfcd9cec1be95042bc8d9546fdeaad9601352bf1fad122c22a75a2340a24f6adb0521456e07d5af9aafce471de2886c07c80eb1147bc4d98ad21b1eb07ba25c1a402700c3842bbfe0bcd6de8a69b343be9d7d07916b6343a9dac86a4911604ef862bffb110fa12cd5ecd5de31b2d6b489441dae1ebaceb5f9b0f171841eebd25eb9bfe13ccd57c3cf80aff18687351a446a7d7e0343b4894e70a539e5ae0972a9079757701b50bd012ac0d997dfb68970313fa846d93e929d2bfd8a2d418ea20a5ccc66dee1595bab9894786c929f03ca5ceeba2dd67ae010bad1f1cc7e62a2ec23a89c7ef1106d46a3c060cc88f3c8f31a57357b2c7f72597a74383745bb4953fd8fad0a504bb126d084a303ef40aa238471d2baffe10b73498e4c6d658680bcaf20c43f877e10c107974d0691539e1ea6683adca9bea99495e0c93affff3a19faa54c0d0f8fe92dc9afb98ba90eda2c67406fc23711d9319938be5d839295d4bb8e0c99cb6de88c3ecf1e83f58f8c8773311852ed73e003cf15338cdce5b892f7ae4a66a6912813facfa63f8fc53dbf0a5a70463a6719d29c298423a80808ccb91e932d7bff7b998187eae5d5f182ff4e6d36d639611f094e63f8ff3806457ee6b3e76261e306b5242e629a0bd102e0231b276020ca652a79180c868f162a0647f8ee6155132960ac84a170c287209c829314b2c73cefac11732638d9d3974f721033a7f88e659eeff2feb31f3813d0fadd6340121b879f8a124f40e17d9fc37f66cba55b7fd8b128004b967eabe5347f3c9454e517937665cfd901232d189f04bb6e57b78c9699c1711aaf73aecbc169fc5ba898cd7182eee1542f0d18800241b3a3de0dec30396690fab2c18ad8de38a35a932089528b57c4f9d90778685beeaa9551f15287eb64ce8700613a2a36de1b0ea0458e243f8b5e4cdf7ff90b5e139b9fad0903ec34967ed13c87b85adefd70caa656cba6513b1c7441add85ae778936d0d07a93c26e3a0417cd45f46e21a7adef9549fb531e8642a8fdf74fc510d25742a2cb193c26cc2d26da57b3776ffc239583dec78efa60baf9cf7df73ea7ebf919e50591ccc78d518021726850779292bad676c71dc60affcfdd62a2af385148dbcac915ac1acb867256385994a876c7a530f7898a72a1bdaf855c210695c34288db0478dcce2eba56afd710df101e590c630a327a170d35c9244416e61afb8bd9cef9374bd2c9f07d9a130b2cc27c4dc274cb368f28fb00a73eaef9ad414bf371d093affc480283121d4f7a51ca2ae293b6a492e3a85d13a7be038b67e6e4cd88aead6138c45c8eb171fc215ac8b53ae7435e827e25e942e17e59fefcd2b9b309c945d4abfbd0bf66e568110168c92d424f445d018f960e659f7796da356b82e7a16dc3480ba94660daa1b2908d6f63bc5cb7ea0020a767968ce9238914012e0180c1c7fd1d78edf7ce193dcd13fd856b64b90a764d611dca0baf939933d19723d4b8827052c0a72400933eb73f5ed91b9a2595ec91e736844121fffab6c6730beb3d5049d9e513dd416edeafcc061d3639756bf855863557e1880dae55b1dca4d508fa3860664ee393944b8734453fec91ceaf4a22f2f7cc6a2bb2ac13c2aa086649752c903dc2d9acaa3a12a306a9646dcc0e616db8411380ccbd928bbd69e9eefd844cb0ae4cfb9da30fe33998e248ba66b907d766845e728754575df428f385cc220c02b85974d2a5c1812e37d475693f3693e66703a059d819748366c3753d857b593c5445628c1b7613d0345d516af73688b1fce8e736539ab5397b30e27720d1bb3cab253fe0376eb7d7ea15a435dfae886563dba47fce51447b8de4618161173745ed6374c8ed606b7cf58db22922884ad26dbb3f79d6734cb73379970c5324371363c29c89b4494b43cb3567bb5b08c03c45115a99ed5c752647163ff0a6f94444fd31a2c5bb07a413bde0ea98feb9a83078870f1a7f0b72e31b65c51fc95ac2e88c9480de5240cd6a309ea0df28be125f8879a991ded0eea8a9e7657706958eda005bb97676c767310c0cde1568639db9a217319c9deed0c66b4d4e7ac96e4c911d7f0aa7b524948ca70957d50aba16e30adcedcc32339a1b47a7ca50243cff6566f61288378e3ff70adcac554923ab37a3c8e491d48deb6b4fc14091eb7181bad0ba0f1998c2adea7aba4b3e97ffe1c15967fd851aec1a82339e07a8f1986c28c2f6b49a5b36a891af8ca1c4356d8392d086762beb20da162663e159452dc2dc1dc3aea4aa36fe09119b7589c2fc7ba1a6180571cf7e0e0c14cac95b6d0734be00e4669f152d38f30d7a4916e5ad23f31a16419659f06ba8a633f6af2f7bab89df124c29f439efa0d4eda71e3a467d8366594189472fb1c88f99d918221029dd53caf1f1015f4f173538910b0fba3d00d938fcc36c1e03185adcf8626b6f32e6c83f684ca673d91b7a2a398909293b1345c65c191521e83bfc0628ad9036d705ecd9100ccde3b4bdc31bf67b28eb83b8a61e3820b0879b99b087da3f867bed5cbb98be6fc353bd5c7d21523fc4de547886f4552c5daa70714a9f87f59caa1c0c565d162b352692f1d7a033c660fc2e9a68591b4361a4da433f8a896695eae68331713452ffc66e631693619fc6b537b809093dc10d1e17b9fb14f58a428421b02a338b33937cc8af3f85f52bd319ac6257b5f67e1fd85b1ff4f5af48986a0e98776a02b8d517bce38a51be2e3e451217fa92875ebcc5c9807ba08b88ee5f091f2fd540962baef8c22454c5bdfe27e801d85c0736c280150f99d024caeaee8b6814341d9921da8b6d7c5802fac781fd7053ee53fd10d7fcaf095a981d93e1df9ffebfaf1a353dd91fc353b5596e79c63016069e0652100afa96be6c128da2e1778518572bb4751f443db0c05de2a7d25cc5d0c446a8855418ecb4d502d0db01fef56c71c3f567a20b64cadc18669bab06f3a1ec32479ac1d37aaecf8f634395e7972fa543e7d3061a111a728e679c488167e407c9f1b1051464542a7ea0ebbba040009223c79324db683632914954dbc625b2014be469eaf744645377c4d89f93a1baf2348187badf3d4f8ca3c20997adaae05648491f09c3f4a4cf1a77ec42a3a765418fe0b698694ca7fe888ebf0a4fae7e3df1f45edb0c3955b50d485e363da3f7ebcd48d9b840d0438cbf94a6837163cadd5eecb9503832306630072163d9d5bd0e23d859fd613764d436af00e15487071693a6851c97e7a3b381f370122692a79f1c258e7d7cd49a34eb397f973eaedb6a6798edd03fc3ce4f8a06d5d615889c6e5cf8d9da4029002903fa7492ac1bda3a5fcf2faebe60ab5f31a6ca518e008696a4825a413fca9259421c4d24c44e928d88b2c717b4d25f44aa337e3a76a95d4053ace457955080ec3c1cb81cc518842e676a506ec5f1dca847a159f28dddd0ec789e9cf246df1c8c75e5086e7d24e42339ca395cc3c2177b0844c1e9473633c2a40312a70fead71d4422803b007ecc6e85b97a4b23d636d13e22f6bc70059b1c50dc71bdd448773942626bfd00f432499e4bdcdf40c31597d6dcd41d8f4dc6f382a4ff4aa574677f32a7fc413bba77e4b929facd8f54084c03fe081827ef20ad55ec8f7f009c32d8a2bf84a1f0fee43e63ee45045bcfba73b8390be3b6b738524d9661b3dc1c48ef5c8ea4a3286aa4ba378791ce66228e1b1c75bd9570918df59bcb27383bc3cfbfd12529ab2be33f95b8a865a55decff31b7eb4ae1b1ab58f45c8f02c743872f7c8b50262c01a6c740feb2db6c2b6392a21fc80cface49c626edbd1a01def1d1191f1bf448eb2783f0e2eacc44aff9fbcce770ec745f2f1f68dc10eccbf2eb91aecb7fb41689ee18ba2cefc180b8c6b5080f2de06d63823320c8891fc69d27505cf7acac48a0fedec5879bb14ec685004a86dedeccf482f645162bbef60f2fc7532bb2bd34512d1bab35d266e8549245877fae7530b4c5b507f7f5485394f3576f30014ac5bb2603508cf81b04a3d33ac76f94a50275408a175cd35284eab61b39e188b6a2f2d53c81f710f7b7250eeff4835ea5e8ef012f2efce107776006604d227c7e21e4a6077d21e37fef16918dd83ff50e99896f7886d7608214fa93ae011aebba7bff714d200b039b4b27947fd530d3019c9e91a2275598baa87f6f1a6c8bd961db0342de7667ddbd2ad94a8a6d225966990bcaadd0a4c4f57f4f190325ddd8b7a6973719ae85953c5359fb7eaf1313822b72b1c4e019074587a59c0b6775d30514ab091fd2c1abe79e25a607a9d9cfd1bd1cfd63057f844b812b020315d8ee4760697adab56f20f8c8342b5166ed4a6c021ebb2114c937fd13cfbfdd773d0d93e38d1d020c7eba1541f43601c027e1fb6a16c94130b919041273271454b975e65cd47105f480b32212f247a79734324c5edd40ec9390bb671ae74696e97fce58bbc934ade16e3d4ceab78636ce35de40195038ca186a5cd8b183ee4bcb419527dd3222b0943a3d64d38237a139c1b3cce929d974bfae5d13abfdb9bf3fb9fa490d9ba970048571b944a6edc5150bfc684ee05c3360f20c70eac03947c0d40c79d2af4b00657b2f63fd6757120e93436aef13a5c8bd54a8052295bc76ba5798cb2aab8c697c6e415e237ed98341cf5c72e9d8949312240be7f4adcd77594687385fe94f6ded46701e2b2eebd6064e9aa6dbb870d9efba9ca8c27320eb8160f49afcab2af77794e06f501b4d61e0b4b9c4341b4592e14a9e40226b12bd64aed84f42a7fdb9a9c6b62ac2a308ce7acf596fc0e9339275fce1b5c8f211968403fc7b8eee3c1d49148300e598e1562eba0378651a84b3aa7bf27ee6131467978b419965c419a1087facc4af887a508bda955b044c9b60fd399ef756dae91be572bfa56272836b762ecfe0620c155eab1a532b4f833be65b2776a808c7ded98a681bb048138cd661d9b28af2ecaa8a05361657f410c8b69f22fecff6d7adc5733cd0e30021642b1d46731b479dc4ddcca2f2a2f8b2cd8db0aafeffc4a7c3a99de32502d2b8bf4c0ad03ff7a492c97f38d9de6f7fefab28e21f082d0b7751104048da3c221faf812710031d67f1dbe1c41e80c2d9223d7ab6898f2f006c9a1e2468d23c55e1d1bc9e666a29b1cca6a6914f6da31cf9adfe244790617f6f72b31645d8c29076d40aa73bbb38dbfb9a1cf1a998d3215cb3cf60174ebdcbc7983fec5d444c4013a3dec7191b90fa08a4e6e28d2d3102cf185d3bcede5718c84d9b4cc33ffe25fd8da036221ea704ec162cea02cbff2043ba8c34c4d9f76cb32c5d0bce7ccaa1dc25031fefb718944b2959d512d7ce0662e9946a3a312e4c839334dc80e0117d0fef6d6e0f8e0b6003e41671489261c7d7c6a974cc70cf3e1c59120a0e6a6d0b24d2bd95e70d696da6b7dbcaef7259d89a7c059f1f98d78ddb767f027304dbe39cc3ac59737067cbde9ba08ce3044069f6cbf657e2596cf184ce9f47b95cacfe56fece9bcac80faee1bdf55d845fd7301491ae3d4da6477c7eb60d64d955f66ddd1804adf265825761a36f3dd345feae09ccdf4641f7fe9affb6b13983d5fe30de5a83edd71a07aa59d0d838cda188a7a777e2c55f17290da8ed6acfac223a75e25321c8a64f45fbe90624b3e7e54dcbb263f2e99a41503982b853e9a83aea1a7665bbfe6a0a0aaf77126513cb5cbc9f5ba5e20e8416f8754444b058b2699d8a4018165c1cc06c9b0e555b0274d5a808e0900c0ad56a87a6a849ccc5194cb810252875f626f0683fc0e03343ccb01a1298780310abbd49f9e7561ec0761395ffdcbbeef047ba803107fbf8ea568e9bda908c531b88c5efced264fd1151eefd419a954c5a5d44533b9ef1c3d46b511acc85664ea2b9e736075000c995d4ff172a800d8abb8e040413d9181c737018a931fd4f224017bad19f28132d01d8525b8b4b3a5fce3e3d1755a2f7777579209562122de6c0c9bed671acfae89b6b82dbd415296e3155175a1f04e8ece201bcbc42233e10719169b8f22978d395a4b3d20047e79b1d0e3f0b97d3e4f0d5680e233b3fc5106e96e5b16112241f3960e2e043db7299f62f2b2cbc7db473297fcc21ccd9f0c797cddbf9cc28945728f0fad491a0fe24cbaf0a9d74f65ef7326e6a5a26ca28a10e36f610299a2e241ed9983948ea09c15f8e2c9fe31a86ad1b11b89daaaa7973f30c831c89b9bfc94f07bcaa9b53acf18684d2ff6075f38c06d32e5106fede8c64452366b15fb2bc285fc2fb3d958c0da3d54abe3d2b1876ec409722239f4317769e099c675867bee260d4d3bee01a42cf6d2129a5d779957b9a01bf30bde43fa16c0d5ca3b143cfe5a1d7f62933049f568e0913f063c7dff8a55afb7e94f4a8019ef1184e5f60e6f976038519f209f4f59e8f7acb4b00ac477e8874eadfdbc1c179ce25fa75d8c215b4f1a504af43a5988c86bf1b07d8108a139092d954bad8246b480dc6d29725b62bd42745d268beaa59180f9bbad8f679d298f8a5e49c79c64cd4f786e5028dd9a3ea4796ef112c34051c1a64f781fccef64efcb417f6dfe37bfcde5c74cdbd5f526d76d693fd51db4252d5fbc5f467aa05be96b83c520590ff9491f404f11300c2abff13e7bb82b96951ec6d5c26bd248b3ccf612deb5a35eac83de361774f739a5a4185b8c74c9a05dac76256f4936f2a22d6417facfdf8a019b29653908ae5f6d1de145cfdafab9a38eaee69bf36aed2e36f61ac42b958a7ff3c829ad145081a27477738598c8084c31ddc354861837742359eaaca71990deee594d47fd2552fc50e216a1a8ea0bf143dc7c23cc6186f8b08bc0965eeef8e4b3e3cb9d6490d8fe9b1b45704fb0db7eb7a4e491c87162f710ad2a112f9ca30b06ea5e39807251353f6dd78d24c4295ab388aa189f96e618ebead1057810efcc0537bd31965be946625e2e7a53080623325806367cf1ebd0c230fa5c9bd4367328a0f7009bbe79ec7df0f92272eae4a4acb82bc6180dba3ec170ffbcf5da9f867f9403e182e412bf6662eea7011b2eb47c7622461aec8f247a3f18fc9c50a1ff41969ed37f77630568d5cf646f8d5c64a9174a5b776c9420b631ae2462b4b27876e4ccb6a3c5c120db0aea2251399b7f46caaad942f20e3503bf5983ae8b0e00f7dff2b1238e45097821fd6fc87eadfac8caacbfb281beae35bd66879cf472dd057aa4d599718f39ecd85286c8bfb38220c402cc94ae8827509154deeea14fabb489c96d9a465471fd582eade621b3e166a22a78ad638e287b2a4466bc95b3855c153efe629c09b49f12f06c77b8b7c568dbb9eb7885feab41e006ce91f3a3568a320f164f5cea36737eeac547ea0e9c877911ea7710f591324dfac0233b11ff69398f191a25b0d4826c6b5d3e572c94f38f83bb454730adfe37a58efec47c8959a17127c011828812c4abc5bb83433cf71b5872c5998f54d78c2d19f52c4885e8559171f92adc972bb58392ba916fe910daced57321b1b368f2bbbfb2623c064546cda58bd637830c572addc2019d74831a51ac5e6d71d08dacd36c5f52909df74ffff27d0829d2940b168b16dfaac5d9db67a93f335a94d822396989caa08a80aa11bf35f3e232f6d7e60f57b2bc763c61ca906d40ba969fcd9eb7e69b6ace209216ba546550eb03429623c088bd9c641155573d8fbb5079bb204f42d621fd3213d0fb055dd3fc63d43bdeac545444d1f5aec5dde66a6800572a9ca0488cf0c64ea21d53fa31ac34d0f614ba813447c5be678abb5961b0ae89cbce873c7b8859dfe8b2d795bb3ec77602eedecc3427374c2552a97f7b0a2badd948b0ab53844821373f097f4851293afc3979777a129d96a7158a231ed01e81193587d262cf7a9a4b2d7cd16d31b9db113c3c618ae70118db890cfb10f7d01e9b0950ba8bf9f5ab9cd3da2efbaba0c2021315cee2b8441989774aad4d1197aa041b4ef59f4653e47a0d45f33172e779bcd954a7d77e8175caa340a8e271f6beac20973f7e9297d1c4d35d0f39f7600acf9387927bd9b7cce48f5be90e76f9145e116be44f7358113431710e97fca95d4f409989f88b3b651cfc762e7942fa9dfec549c1afd620b8bbbe63975cf60658712f6d85c446ea88780b93e47f98b0d8ef5955a0e7b5ea833079e928ddd96c4479f557ce9e2cbc23e0f187ad80479b07df28d932471b4e0a8c069bad5015a00759f49d2ed9cae6ee044b429e24c89314463cd7784ede9e07cda79df6321f4bd5bf0019f59ae39ce469dd6fc282fe2e813b75da860432fcf1fe4d6d5ff6bdeeaea9aeb7a5afab7640efb8d24d2f3be4bd29d03aba7b1e155ddca597edf9315b3683b9b1458f8b2bfd30bdae7b5f6207995c6d5d3a9078a66f7f276d452fc3872bec1f512a117c9105bdf21b6286b60eca8eebf42f1bb084d116be85daaa467f520aef7013edba22c2f4cc8b2cf1a68999fbbf97f4236c8a89dd91524b2546f4095f59035feb9c4d21a6b86e6be0edf70b16fcdfa3096d5ab892137d5748b3e846cbe9edb4d6b860d31e3d947916449d6ecca5d0e3c702012fa66391cc84c4a4d4a51d29ae958d5d3a7be170e94ba48ed8a22c258c25ad32db6333e692193c6341da87d3837bf7d2e8d714afda542fc2cf92d2cce661defbbaf6032efd4d60459a753e85e646c8ae1cb5257ca56eab5012e61bd6de02b5e9f3d0e89980d9c5558dae5fd4f011ba9476e818c2f3441e0a024bf9bc59732d2e84022027a2286b78f79462d9cdc1412fb8a5f10492361a13193cb33bd5de60bf828eb116322991ccd6605c22c391e286901f8eacfcb53b603bff955c8f35fd0d13dd1f29b04ed166c0c74831fecb13388f0ae87b72070b49e029e6f13093a391235c4cb5af36ec95775211dc70016dd36dbc3eb1498e609b27878f2c9c633e121983083bf88b0f7ff0aeec9142cfe254c32dfa9f1fe31888169e069f4aeae7d5e0d594d4e160fd98842b7847fd62ec8b09ab8da0008ec0a15a73c94601cb23e1bf0096c859e370975ddee6b6b52d0bb9021dcfd7f575d104d4e588b918f82c2432faa8a6b4843deeb3c13e3f955592d07f5c2c4f77e314b7553bfb45686b0186d76db420e0707e498f12600e7f7236e6e04006628a5358c8a4356dcef64eefe9fa5f77b01defe52afb1ac09687b1cd5f2fb560a07bd14da7d75b8ea9a4cb270ca9956a872dec53cd1bc6b9cbf23bde210c07342bdaf263b1e69f50eb6e636a6f9d14485638e51c97d0b08c7d0ced86a042042a9b5b9f18b4ee6bcb4a5e508c57b80e441c29a4ae265c0a2d63ccb430e808e27a66123a8d7c8d1c613c70ab2ead68158a8cef40ce4cb05d5f957ed259dbe37664d8c730c83f562d7e67aad25b8cb5036e57d90ae45b20c696d89419a007fae2924c2161146dc75345b0898b1e97c7333399a61e5086f4fe4af57a0624e48d1b1f828116237d9455f57bc52bb90bdeaed994b071ae8eb613ca3b880e7aef16a8a9607e2682afa2d644881ba840f0046a6c6771ec931e9a370cfcd6204ab590a10f42317b63bb175f67cf55a728e81209c89369d95d54d14b9f826650473c75a5261c03dc9bc03961a2306f8b676f3ca031d360a15dfef0b7d802afdbcce2f4baf20beeee9762338b909772ec80671597e657300638181732f665f9a7c712838be6b4e00d48d360407199424977c545e55825f05035c926b2d76691a17f513164357562483abdceb6e7ab6faf54089be79a3a9573e66402f5a0eaabb2da189f0235a199f70ecfffa51bf49974553d0f8d743e658769700ac831b091bbdb75017974b54e0aa2f9f7bc3bd6854658f1dfdc46a9a41624ea291ebb8fd60790a38970587e13e52b0f3d5980f405410dfd6e2b3f9fc0d06cb7004ee86e9905ba0a956c7e12ec85ed6adcd37b54dd92a09ec9df60923de7507b4c39ba68c839c2ccb80b5ddcae1330716e7c3f1da1b96bb79e0e2048fc7005264996156df84eee97982f5ed845e4a2162cd0fcbe10147ec84805684e31e7b31cbb2b1fe6ee859b2cfe51be5582a4b5c7d2a131cf3b250d3fc6275115b7c52f2a573d55dc02b075f7e74d821712ba4be8933f50e7aaec0fa3a459066f1c6866a15f54b523cd4e021676b59765b6efd1a0cdbe0cd93ad9e9ec1ca02bfb1c28090213566df5c7505b02429605b7f97df52cd90d0d590530af2458faace6f6f233262c22f48fc852f15f79dbfc7254b9425cf71d025b97dd8d599468e44b2b1c57501a74010c52cbf52f0c163acb22a52342e5fb961743da5b2f001b7033d25e341826ba4568df0a31b50e853acdcdc48f086d80ce330e15ab1ce8536a8186c18e94b397296c1a78e9f29544d39ad0f14592f81debf2beff3dcef4c979262bcfc691cebdd905d14d0f84c0b8c864e81e8c0914888da1f33b91275d06a9eb075add2b9a95d040ec5ec67ac4316a1864e4ec43c3f21a1a6f2c3bc754c3638be5c67d6e7863ebd12b966e61ec8d50393ef07a37094ee3a930af54acda3154be9b4e1a79849af993f8a0780551f487a81a0277c5</script>
<div class="hbe hbe-content">
<div class="hbe hbe-input hbe-input-xray">
<input class="hbe hbe-input-field hbe-input-field-xray" type="password" id="hbePass">
<label class="hbe hbe-input-label hbe-input-label-xray" for="hbePass">
<span class="hbe hbe-input-label-content hbe-input-label-content-xray">您好, 这里需要密码.</span>
</label>
<svg class="hbe hbe-graphic hbe-graphic-xray" width="300%" height="100%" viewBox="0 0 1200 60" preserveAspectRatio="none">
<path d="M0,56.5c0,0,298.666,0,399.333,0C448.336,56.5,513.994,46,597,46c77.327,0,135,10.5,200.999,10.5c95.996,0,402.001,0,402.001,0"></path>
<path d="M0,2.5c0,0,298.666,0,399.333,0C448.336,2.5,513.994,13,597,13c77.327,0,135-10.5,200.999-10.5c95.996,0,402.001,0,402.001,0"></path>
</svg>
</div>
</div>
</div>
<script data-pjax src="/lib/hbe.js"></script><link href="/css/hbe.style.css" rel="stylesheet" type="text/css">]]></content>
<categories>
<category>哲学</category>
</categories>
<tags>
<tag>思维系统</tag>
<tag>互联网</tag>
<tag>站在巨人肩膀上</tag>
<tag>突围</tag>
<tag>创新</tag>
<tag>创业</tag>
</tags>
</entry>
<entry>
<title>5个ChatGPT搞钱成功案例</title>
<url>/posts/e4931d34/</url>
<content><![CDATA[<iframe src="//player.bilibili.com/player.html?aid=653341225&bvid=BV1pY4y197qQ&cid=1048468540&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="600px"> </iframe>
<h1 id="案例一:金融"><a href="#案例一:金融" class="headerlink" title="案例一:金融"></a>案例一:金融</h1><p><img src="/posts/e4931d34/image-20240424202921615.png" alt="image-20240424202921615"></p>
<blockquote>
<p><a href="https://www.youtube.com/watch?v=SmMziYwEIAs">https://www.youtube.com/watch?v=SmMziYwEIAs</a> </p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">写购买比特币的移动交叉点交易策略</span><br><span class="line">当20日均上穿至到50日均线上方则买入</span><br><span class="line">当20日均下穿至到50日均线下方则买出</span><br><span class="line">每次交易5000股</span><br><span class="line">有不错盈利的时候管理</span><br><span class="line">按照指定的编码规则写出</span><br></pre></td></tr></table></figure>
<p>ChatGPT则会返回给一段代码,当然执行的时候是会报错的,只需要把报错发给ChatGPT让他自己改,这样的操做进行大概两三次,程序居然真的可以跑起来,小哥把策略贴到tradingview里面之后,整个买入和卖出的点,都展示的非常清晰,tradingview用这个策略回测了两年,交易了130多笔,整个策略有43%回报率</p>
<p>很多类似的视频,这些博主其实是从30%-90%,甚至更多都不等,基本取决于不同的量化策略,和交易品类,还有个人能力吗,其实跟ChatGPT关系并不是太大,不过这里是普通人通过ChatGPT的辅助,那你写量化策略的效率会高很多</p>
<h1 id="案例二:NBA赛事套利(博彩)"><a href="#案例二:NBA赛事套利(博彩)" class="headerlink" title="案例二:NBA赛事套利(博彩)"></a>案例二:NBA赛事套利(博彩)</h1><blockquote>
<p><a href="https://www.sportingpedia.com/nba-betting/calculate-nba-arbitrage-bets/">https://www.sportingpedia.com/nba-betting/calculate-nba-arbitrage-bets/</a> </p>
</blockquote>
<p>什么是博彩:著名的赛事比如说NBA,自然会有博彩公司会开盘口,但是不同盘口之间,会因为各种各样的原因开出不同的赔率,所以其实利用程序化交易,就可以利用同一场比赛,不同博彩之间的赔率,进行套利,比如按照下图这个假设:</p>
<p><img src="/posts/e4931d34/image-20240424212213250.png" alt="image-20240424212213250"></p>
<p>如果在A公司买B赢,在B公司买A赢,最终通过计算可以获得一个双赢的结果,无论A或者B谁赢,你都会有一个非常小的盈利,不过要实现这个小的盈利,需要做到两件事,第一你需要发现不同盘口之间实时的套利机会,并且迅速下发一个套利指令,第二需要迅速计算出合理的本金分配,确保无论哪一方赢,都能获得一个正收益</p>
<p>这两件事,都需要机器的辅助和下达指令,博主其实通过github的多,理论上这样的交易,应该是风险非常小,接近于0的,但实际操作起来可能要复杂得多,所谓无风险套利存在非常多的风险如下图:</p>
<p><img src="/posts/e4931d34/image-20240424220519303.png" alt="image-20240424220519303"></p>
<p>ChatGPT在这件事上拒绝写自动套利程序,所以这个大神只是用ChatGPT提供实时赔率数据的api接口,以及统计twitter上面关于本场比赛舆情数据的一个工具,这套程序化交易所需的代码,最终都是通过这个小哥手搜github开源代码来实现的,他验证了盘口确实存在5%左右的套利的空间,不过大神并不满足于5%,他选择单边下单了,所以他做的并不是一个无风险交易,最后他选择了web3的一个在线博彩网站投注,因为限制最少,他用USDT大概投了2000刀的注,24小时后他赚到了9000多刀,净利7000刀左右,在这个场景下ChatGPT其实也没起到多少作用,只能说辅助分析。</p>
<p><img src="/posts/e4931d34/image-20240424225740648.png" alt="image-20240424225740648"></p>
<h1 id="案例三:电商"><a href="#案例三:电商" class="headerlink" title="案例三:电商"></a>案例三:电商</h1><p>首先用ChatGPT找到你目标客群的一个爱好,比如定位18-30岁的男性,可以锁定游戏相关的衍生品,用AI绘图找到衍生品的网站,一般来说没太多成本,也不需要囤货,只需要把AI绘图上传到网站,定制相应的商品,然后把商品连接上不同的电商接口,比如挂画。</p>
<p>进阶的就是推广,可以用ChatGPT做商品介绍,还可以做出包含目标人群和目标商品配图,除了投入广告费用,7天能有个1000多刀利润。</p>
<p>用ChatGPT做文案,和AI作图可以提升电商效率,可以省下客观的运营费用和运营时间,所以电商是非常主流的一个商用和变现方向。</p>
<h1 id="案例4-5:600-chagtgpt创业demo"><a href="#案例4-5:600-chagtgpt创业demo" class="headerlink" title="案例4-5:600+ chagtgpt创业demo"></a>案例4-5:600+ chagtgpt创业demo</h1><blockquote>
<p><a href="https://gpt3demo.com/map">https://gpt3demo.com/map</a></p>
</blockquote>
<p>ChatGPT热门方向</p>
<ol>
<li>聊天机器人</li>
<li>代码辅助</li>
<li>写作</li>
<li>游戏(文字游戏、聊天机器人)</li>
</ol>
]]></content>
<categories>
<category>ChatGPT</category>
</categories>
<tags>
<tag>工具</tag>
<tag>搞钱</tag>
</tags>
</entry>
<entry>
<title>pua</title>
<url>/posts/c34d6d3f/</url>
<content><![CDATA[<h2 id="pua是什么"><a href="#pua是什么" class="headerlink" title="pua是什么"></a>pua是什么</h2><p>PUA是一种通过操纵和利用他人的感情来达到自己目的的行为,体现在不尊重别人。它的特点是在短时间内操控对方情绪和行为,长期的后果是造成心理创伤、信任破裂、关系失衡。</p>
<h2 id="pua是如何影响他人"><a href="#pua是如何影响他人" class="headerlink" title="pua是如何影响他人"></a>pua是如何影响他人</h2><h3 id="打造人设"><a href="#打造人设" class="headerlink" title="打造人设"></a>打造人设</h3><p>通过语言、穿着、编造虚假信息伪装自己,给对方错觉。</p>
<h3 id="情感操控"><a href="#情感操控" class="headerlink" title="情感操控"></a>情感操控</h3><p> PUA者强调付出,自己的好,通过贬低对方,让其孤独、不安或自我怀疑等,通过言语和行为来强化这些感受,从而增强对受害者的情感控制。</p>
<h3 id="剥夺个人边界"><a href="#剥夺个人边界" class="headerlink" title="剥夺个人边界"></a>剥夺个人边界</h3><p>PUA者控制受害者的生活和决策,包括限制他们的社交圈子、控制他们的日程安排以及与家人和朋友的关系等。对个人自由的限制会导致受害者逐渐失去独立思考和自主行动的能力。</p>
<h3 id="心理虐待"><a href="#心理虐待" class="headerlink" title="心理虐待"></a>心理虐待</h3><p>PUA者经常使用各种方式进行心理虐待,如侮辱、贬低、恐吓或无视受害者的感受和需求。这种虐待会导致受害者出现焦虑、抑郁、自卑和自我怀疑等心理问题。</p>
<h3 id="破坏亲密关系"><a href="#破坏亲密关系" class="headerlink" title="破坏亲密关系"></a>破坏亲密关系</h3><p>PUA者会试图破坏受害者与其他人的亲密关系,如家庭、朋友或伴侣等。他们可能会通过挑拨离间、散布谣言或其他方式来破坏这些关系,从而使受害者更加孤立和无助。</p>
<h2 id="如果身边的人被PUA怎么劝说"><a href="#如果身边的人被PUA怎么劝说" class="headerlink" title="如果身边的人被PUA怎么劝说"></a>如果身边的人被PUA怎么劝说</h2><ul>
<li>首先,表达你的关心和支持,让他们知道你站在他们这一边。</li>
<li>其次,简单解释PUA是操纵和欺骗行为,会损害自尊和信任,导致社交障碍。</li>
<li>鼓励他们保持自信和独立思考,不要轻易被PUA者的言辞所左右。</li>
<li>建议他们与PUA者保持距离,减少接触。</li>
<li>如果情况严重,建议寻求专业心理咨询师或相关机构的帮助。</li>
<li>保持耐心和理解,尊重他们的感受和选择。</li>
</ul>
<h2 id="劝说的本质"><a href="#劝说的本质" class="headerlink" title="劝说的本质"></a>劝说的本质</h2><p>劝说的本质是通过逻辑、事实和情理的阐述,影响他人的思考和行为,使其理解并接受某种观点或行为方式。它强调<strong>尊重、理性和有效沟通</strong>,旨在<strong>建立共识和解决问题</strong>。</p>
<h2 id="如何避免被PUA"><a href="#如何避免被PUA" class="headerlink" title="如何避免被PUA"></a>如何避免被PUA</h2><p>怎么去避免,其实很好解决,保持警惕保护自己、自信且独立、善于分析评估批判对方、见多识广、心理健康稳定。</p>
<h2 id="思考"><a href="#思考" class="headerlink" title="思考"></a>思考</h2><p>我觉得这不就是毁别人道心的东西吗,在别人心理还没有成熟的时候,通过各种手段迷惑别人,如果对多个人这样做,就能短期迷惑心智不成熟的群体,从而带来巨大利益。这一想跟邪教有一点相似,不过他们的目的和手段各不相同。</p>
<p>这里要说一下道心,道心是一个复杂而多维度的概念,在不同的文化和信仰中有不同的理解和解释。但无论如何,道心都是人类精神发展的重要方向和目标之一,也是我们追求更高层次的精神境界的重要动力和指导。</p>
<p>讲一下我认为比较重要的危害,被pua后被人迷惑,让人精神紧张无法思考问题,导致很难去客观的看待问题;会为了讨好对方去做侵害自己利益的事情;会自卑并且感受不到自己的价值。长期的后果是造成心理创伤、信任破裂、关系失衡。不过只要多加注意pua还是很容易分辨的。</p>
]]></content>
<categories>
<category>人际交往</category>
</categories>
<tags>
<tag>沟通</tag>
</tags>
</entry>
<entry>
<title>白斌-谈判技巧</title>
<url>/posts/f61093aa/</url>
<content><![CDATA[<p>本文主要是【白斌】10种谈判方式,原视频</p>
<iframe src="//player.bilibili.com/player.html?aid=73017903&bvid=BV1pE41127zs&cid=127956401&p=10" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="600px"> </iframe>
<h1 id="面对难以接受的请求-移花接木"><a href="#面对难以接受的请求-移花接木" class="headerlink" title="面对难以接受的请求-移花接木"></a>面对难以接受的请求-移花接木</h1><p>如果不好直接拒绝,就先答应,附加一个对方难以接受的条件。</p>
<p>例如:假设你是一名项目经理,同事向你提出一个建议,你并不想直接答应。你就可以说:你的想法很有创意,不过要实现这个功能要额外增加两名开发人员,项目周期要延长一个月。</p>
<h1 id="出现分歧缓解气氛-引入第三人"><a href="#出现分歧缓解气氛-引入第三人" class="headerlink" title="出现分歧缓解气氛-引入第三人"></a>出现分歧缓解气氛-引入第三人</h1><p>找权威的人寻求意见,双方也都尊重才成立。</p>
<p>例如:假设你是一名项目经理,当团队成员对某个决策或方案产生严重分歧,一方想要更快地推进项目;而另一方则想要项目的长期利益,导致项目进展受阻。通过引入第三人来协助,通常具备相关经验和专业知识,对分歧进行分析和评估。</p>
<h1 id="想象与实际不符-降低期待值"><a href="#想象与实际不符-降低期待值" class="headerlink" title="想象与实际不符-降低期待值"></a>想象与实际不符-降低期待值</h1><p>用鲁迅的话就是:你想开天窗,众人拒绝,但是你说想把屋顶拆了,众人就能接受你开天窗的请求。</p>
<p>例如:假设你是一名销售经理,客户觉得你公司的新产品能带来显著的业绩提升。可以和客户沟通产品的实际情况和潜在风险,并且提一些建议,减少客户因期望过高导致的失望,维护良好的关系,为长期合作打基础。</p>
<h1 id="对有利可图的人-尊重对方"><a href="#对有利可图的人-尊重对方" class="headerlink" title="对有利可图的人-尊重对方"></a>对有利可图的人-尊重对方</h1><p>表面表达出来就可以了,心里面要拎得清。对任何人保持礼貌、谦逊,建立良好的人际关系和口碑,还能够促进长期合作和共赢。始终保持一颗平等、开放和包容的心,珍惜每一次合作机会。</p>
<h1 id="掌握主动权-立法者游戏"><a href="#掌握主动权-立法者游戏" class="headerlink" title="掌握主动权-立法者游戏"></a>掌握主动权-立法者游戏</h1><p>对方提供的选择都不是最优选,不要局限在对方给出的规则/选择,要主动当”立法者”,给出自己的规则,不要落入对方得规则中。无论发成什么都保持礼貌和冷静。<strong>接受对方规则,你取得胜利,这是不可能的</strong>,历史上没有将来也不会有。</p>
<p>例如:饭桌上让你喝酒你不想喝,等于他制定了一个规则,你喝了就相当于遵守它的规则,如果你拒绝了,现场很尴尬。</p>
<p>同地位:明确表达自己的立场,立法者的身份,是他自己赋予自己的,让别人知道这是荒谬的,从而说明这对你是无效的,但是不能直白的说;</p>
<p>领导:强调个人价值观,并私下沟通,表明自己的担忧和立场,让对方知道你不是在挑战他的权威。</p>
<h1 id="增强合作关系与合作进度-让对方付出成本-沉没成本"><a href="#增强合作关系与合作进度-让对方付出成本-沉没成本" class="headerlink" title="增强合作关系与合作进度-让对方付出成本(沉没成本)"></a>增强合作关系与合作进度-让对方付出成本(沉没成本)</h1><p>当对方为某件事或某个关系付出了沉没成本(如时间、金钱、精力等),他们通常会更倾向于<strong>继续投入</strong>,因为他们不想看到自己的努力付诸东流,他们会更倾向于<strong>维护关系的稳定</strong>,<strong>减少背叛</strong>或损害关系的行为。也是一种<strong>筛选真心合作的机制</strong>,帮助识别那些真正愿意投入和合作的伙伴,不愿意付出任何成本的人可能缺乏诚意或长期合作的意愿。对方在付出沉没成本的过程中,往往会对所涉及的事物或关系产生更深的<strong>提高认同感和价值感知</strong>。这种心理效应有助于稳固关系或推动项目持续进行。</p>
<p>这么一分析也可以反方向去做,就是多去投入成本,让对方认为你是真心的是可以稳定和长期合作的人</p>
<h1 id="知己知彼百战不殆-做好的聆听者"><a href="#知己知彼百战不殆-做好的聆听者" class="headerlink" title="知己知彼百战不殆-做好的聆听者"></a>知己知彼百战不殆-做好的聆听者</h1><p>绝大部分人,更注重自己说了什么,而不注重聆听,只关心自己不关心对方,就会出现我喜欢这样,那么我认为别人也喜欢,这样是不对的。其实<strong>做好聆听</strong>就能越了解对方,谈判越有利。了解对方的需求,提高信任建立良好关系。</p>
<h1 id="避免因小失大-抓住根本问题"><a href="#避免因小失大-抓住根本问题" class="headerlink" title="避免因小失大-抓住根本问题"></a>避免因小失大-抓住根本问题</h1><p>快刀斩乱麻,只要根本利益得到了,细节也容易迎刃而解。而纠结于细节再解决核心问题就容易陷入细节,抓不住重心。 </p>
<h1 id="避免服务贬值-在对方后悔之前把钱收了"><a href="#避免服务贬值-在对方后悔之前把钱收了" class="headerlink" title="避免服务贬值-在对方后悔之前把钱收了"></a>避免服务贬值-在对方后悔之前把钱收了</h1><p>服务业常常会在服务完成后,甲方后悔,认为服务不值这个价钱,因此应在服务完成前,尽量把钱收到口袋里。</p>
<h1 id="让对方不拒绝-给甲方”选择”"><a href="#让对方不拒绝-给甲方”选择”" class="headerlink" title="让对方不拒绝-给甲方”选择”"></a>让对方不拒绝-给甲方”选择”</h1><p>让对方感觉是选择主体,有控制权。比如饭店问顾客”需要茶还是咖啡?”而不是”需要茶吗?”。</p>
<p>总结:应该给对方一种虚幻的”尽在把握”的感觉。要保持自己在主动位置。要给自己留足余地。</p>
]]></content>
<categories>
<category>沟通</category>
</categories>
<tags>
<tag>谈判</tag>
</tags>
</entry>
</search>
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。