我的java开发测试 - 怪使
type: channel
link: https://www.ownsyou.cn/author/1/
description: 怪使
items: OpenResty、Tengine、Nginx使用
items: 数据库访问五大核心技术
items: SpringBoot Jar包冲突在线检测
items: 高性能短链构建
items: 后端性能优化
items: GraalVM替代JVM的方式方法和不足
items: 怀化之旅-2025.5.5
items: 怀化之旅-2025.5.4
items: 怀化之旅-2025.5.3
items: 怀化之旅-2025.5.2

OpenResty、Tengine、Nginx使用
type: item
date: 2025-09-18T11:33:13+08:00
description: OpenResty、Tengine、NginxOpenResty官网地址：https://openresty.org/cn/OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台，其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。OpenResty® 通过汇聚各种设计精良的 Nginx 模块（主要由 OpenResty 团队自主开发），从而将 Nginx 有效地变成一个强大的通用 Web 应用平台。这样，Web 开发人员和系统工程师可以使用 Lua 脚本语言调动 Nginx 支持的各种 C 以及 Lua 模块，快速构造出足以胜任 10K 乃至 1000K 以上单机并发连接的高性能 Web 应用系统。OpenResty® 的目标是让你的Web服务直接跑在 Nginx 服务内部，充分利用 Nginx 的非阻塞 I/O 模型，不仅仅对 HTTP 客户端请求,甚至于对远程后端诸如 MySQL、PostgreSQL、Memcached 以及 Redis 等都进行一致的高性能响应OpenResty其实就是一个基于Nginx的Web平台，但它最牛的地方在于集成了LuaJIT和很多精心编写的Lua库。简单来说，就是让你可以在Nginx里面写Lua代码，这听起来可能没什么，但用过的人都知道这有多香。比如，你产品经理突然要求在用户访问某个页面时，根据用户的地理位置显示不同的内容。如果用传统的方式，要么改后端代码重新发布，要么搭建一套复杂的CDN规则。但用OpenResty，我直接在nginx.conf里写了几行Lua代码就搞定了：location /api/content { access_by_lua_block { local ip = ngx.var.remote_addr local geo = require "resty.geoip" local country = geo.lookup(ip) if country == "CN" then ngx.var.backend = "china_backend" else ngx.var.backend = "global_backend" end } proxy_pass http://$backend; }这种灵活性是原生Nginx根本做不到的。你想想，如果每次这种小需求都要动用整个开发流程，那得多麻烦。OpenResty的安装也很简单，在Rocky Linux release 8.10上直接用yum就行：sudo yum install yum-utils sudo yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo sudo yum install openresty装完之后，你会发现它的目录结构和Nginx差不多，配置文件还是在/usr/local/openresty/nginx/conf/nginx.conf。但是多了很多Lua相关的模块，比如lua-resty-redis、lua-resty-mysql这些，基本上常用的都给你准备好了。#这是我修改后的文件 [root@webtest ~]# cat /usr/local/openresty/nginx/conf/nginx.conf worker_processes 1; error_log logs/error.log; events { worker_connections 1024; } http { server { listen 8080; location / { default_type text/html; content_by_lua_block { ngx.say(" hello, world ") } } } }Tengine官网：https://tengine.taobao.org/Tengine是阿里巴巴开源的Web服务器，基于Nginx开发。说到阿里的技术，那肯定是在高并发场景下被虐过千百遍才开源出来的，所以在性能和稳定性方面确实有两把刷子。安装官网下载编译安装包，上传到服务器[root@webtest ~]# tar -xf tengine-3.1.0.tar.gz [root@webtest ~]# cd tengine-3.1.0 [root@webtest ~]# ./configure [root@webtest ~]# make [root@webtest ~]# make installTengine最让我印象深刻的是它的动态模块加载功能。以前…

数据库访问五大核心技术
type: item
date: 2025-09-16T16:19:26+08:00
description: 数据库访问五大核心技术简介在项目开发时，数据库访问技术是必不可少的，它直接决定了数据持久化的效率、开发维护的便捷性以及系统整体的性能表现。本文对比五种主流数据库访问技术：JOOQ 以类型安全的 SQL 和数据库优先设计著称，适合复杂查询与性能敏感场景，但需接受代码生成和商业授权限制；MyBatis 通过轻量级框架平衡了 SQL 控制与开发效率，支持动态 SQL 和多数据库适配，但需手动管理 SQL 与事务，类型安全较弱。此外，其他常见技术如 JDBC（原生但冗余）、Hibernate/JPA（全自动化 ORM 但学习曲线陡峭）、Spring Data JDBC/JPA（简化 CRUD 但灵活性受限）也各有适用场景。JDBC技术JDBC（Java数据库连接）是Java中为数据库连接提供基础支持的核心API。它是一个底层API，可对SQL执行和结果处理提供直接控制。可以把JDBC看作是Java数据库编程领域的“汇编语言”——功能强大，但需要更多手动操作。如下示例：private final DataSource dataSource ; public User queryByJdbc(Long id) { String sql = "SELECT * FROM a_user WHERE id = ?"; try (Connection conn = this.dataSource.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql)) { stmt.setLong(1, id); try (ResultSet rs = stmt.executeQuery()) { if (rs.next()) { return mapRowToUser(rs); } } } return null; } private User mapRowToUser(ResultSet rs) throws SQLException { User user = new User(); user.setId(rs.getLong("id")); user.setName(rs.getString("name")); // ... return user; }JDBC 适用场景性能关键型应用：需要最大程度控制 SQL 执行，以优化性能复杂查询：ORM 框架难以表达的复杂 SQL 查询遗留系统集成：需要与现有存储过程（Stored Procedures）交互简单数据访问的微服务：数据访问模式简单，无需 ORM 框架的额外开销。学习目的：理解数据库底层原理和 JDBC 核心机制JDBC 优势最大性能控制：直接执行 SQL，避免 ORM 框架的额外开销完整 SQL 功能支持：可使用数据库特有的优化和功能（如特定语法、索引提示）轻量级：内存占用小，启动速度快行为可预测：编写的 SQL 会被精确执行，无 ORM 的隐式行为通用兼容性：适用于所有支持 JDBC 的数据库（MySQL、Oracle、PostgreSQL 等）JDBC 劣势冗余代码多：需要手动处理连接、语句（Statement）和结果集（ResultSet）的创建与关闭手动对象映射：需自行将数据库行（Row）转换为 Java 对象（POJO）SQL 注入风险：若未正确使用参数化查询（PreparedStatement），易受攻击数据库移植性问题：原生 SQL 可能在不同数据库间不兼容（如分页语法差异）无内置缓存：需自行实现缓存策略（如使用 Redis 或本地缓存）注：Spring中，JdbcTemplate与JdbcClient（Spring 6+）通过模板化设计，将原生JDBC的冗余代码量降低70%，实现高效数据库访问。Hibernate技术Hibernate 是一个成熟的对象关系映射（ORM）框架，它通过面向对象编程的方式抽象化数据库操作。该框架能够自动处理 Java 对象与数据库表之间的映射关系，为面向对象开发者提供了一种更符合自然编程习惯的模型。private final SessionFactory sessionFactory ; public User queryByHibernate(Long id) { try(Session session = sessionFactory.openSession()) { User user = session.find(User.class, id) ; return user ; } }我们还可以使用HQL语句进行查询User user = session.createQuery("FROM User WHERE id = ?1", User.class) .setPa…

SpringBoot Jar包冲突在线检测
type: item
date: 2025-09-16T15:49:00+08:00
description: SpringBoot Jar包冲突在线检测1. 痛点背景在 Spring Boot 项目开发和运维中，Jar 包冲突是让开发者最头疼的问题之一：常见冲突场景类重复：不同依赖引入了相同的类，启动时报 ClassCastException 或 NoSuchMethodError版本冲突：同一个库的不同版本混用，行为不一致，线上才暴露问题日志混乱：SLF4J + Logback + Log4j 多个实现共存，日志输出异常驱动重复：MySQL 5.x 和 8.x 驱动同时存在，连接异常现有方案的局限性• mvn dependency:tree：只能编译期分析，无法反映运行时 classpath• IDE 插件：需要人工操作，无法自动化集成• 第三方工具：过重，难以嵌入 Spring Boot 应用考虑引入一个轻量、可嵌入、运行时可见的 Jar 包冲突检测工具。2. 技术方案设计核心架构运行时扫描 → 冲突检测 → 配置化建议 → Web 可视化 ↓ ↓ ↓ ClassLoader 规则引擎 模板系统 适配器 智能分析 变量替换 关键技术点1. 多环境 ClassLoader 适配public List<URL> getClasspathUrls() { ClassLoaderclassLoader= Thread.currentThread().getContextClassLoader(); List<URL> urls = newArrayList<>(); // 遍历所有 ClassLoader 层级 ClassLoadercurrent= classLoader; while (current != null) { if (current instanceof URLClassLoader urlClassLoader) { urls.addAll(Arrays.asList(urlClassLoader.getURLs())); } current = current.getParent(); } // Spring Boot LaunchedURLClassLoader 特殊处理 if (classLoader.getClass().getName().contains("LaunchedURLClassLoader")) { urls.addAll(extractFromLaunchedClassLoader(classLoader)); } return urls.stream().distinct().toList(); }2. 三维冲突检测算法// 类重复检测 Map<String, List<JarInfo>> classToJarsMap = newHashMap<>(); for (JarInfo jar : jars) { for (String className : jar.getClasses()) { classToJarsMap.computeIfAbsent(className, k -> newArrayList<>()).add(jar); } } // 版本冲突检测 Map<String, List<JarInfo>> nameToJarsMap = jars.stream() .collect(Collectors.groupingBy(JarInfo::getName)); // JAR 重复检测（基于签名） Map<String, List<JarInfo>> signatureMap = jars.stream() .collect(Collectors.groupingBy(this::generateJarSignature));3. 配置化规则引擎完全摒弃硬编码，通过 YAML 配置定义所有规则：conflict: advisor: rules: slf4j-logging: patterns: [".*slf4j.*", ".*logback.*", ".*log4j.*"] severity:HIGH advice:|3. 核心实现Jar包扫描器支持开发环境和生产环境的智能扫描：@Component publicclassJarScanner { public List<JarInfo> scanJars() { List<JarInfo> jars = newArrayList<>(); List<URL> urls = classLoaderAdapter.getClasspathUrls(); for (URL url : urls) { Stringpath= url.getPath(); if (shouldExclude(path)) continue; if…

高性能短链构建
type: item
date: 2025-09-10T08:43:57+08:00
description: 高性能短链构建短链必须性这里列举3个原因来讲一下短链存在的必要性。相对安全短链不容易暴露访问参数，生成方式可以完全迎合短信平台的规则，能够有效地规避关键词、域名屏蔽等风险，而原始 URL地址，很可能因为包含特殊字符被短信系统误判，导致链接无法跳转。平台限制短信发送平台有字数限制，在整条短信字数不变的前提下，把链接缩短，其他部分的文字描述就能增加，这样似乎更能达到该短信的实际目的（比如，营销）。短链构成短链的组成通常包含两个部分：域名 + 随机码https://www.ownsyou.com/s2TYdWd短链的域名最好和其他业务域名分开，而且要尽量简短，可以不具备业务含义（比如：xyz.com），因为短链大部分是用于营销，可能会被三方平台屏蔽。(非营销无需考虑这个问题)短链的随机码需要全局唯一，建议10位以下。短链跳转原理首先，我们先看一个短链跳转的简单例子，如下代码，定义了一个 302重定向的代码示例：import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.servlet.view.RedirectView; @Controller publicclass RedirectController { @GetMapping("/{shortCode}") public RedirectView redirect(@PathVariable String shortCode) { String destUrl = "https://yuanjava.com"; // destUrl = getDestUrlByShortCode(shortCode); //真实的业务逻辑 returnnew RedirectView(destUrl); }接着，在浏览器访问短链”http://127.0.0.1:8080/s2TYdWd” 后，请求会被重定向到 https://yuanjava.com 从ws抓包可以看到 302状态码并且请求被 Location到另外一个 URL，整个交互流程图如下：用户通过短链访问到短链系统，然后通过302重定向到目标系统最后，总结下短链跳转的核心思想：生成随机码，将随机码和目标 URL（长链）的映射关系存入数据库；用域名+随机码生成短链，并推送给目标用户；当用户点击短链后，请求会先到达短链系统，短链系统根据随机码查找出对应的目标 URL，接着将请求 302重定向到目标 URL（长链）；关于重定向有 301 和 302两种，如何选择？302，代表临时重定向：每次请求短链，请求都会先到达短链系统，然后重定向到目标 URL（长链），这样，方便短链系统做一些统计点击数等操作；通常采用 302301，代表永久重定向：第一次请求拿到目标长链接后，下次再次请求短链，请求不会到达短链系统，而是直接跳转到浏览器缓存的目标 URL（长链），短链系统只能统计到第一次访问的数据；一般不采用 301。短链生成从短链组成章节可知：短链=域名+随机码，因此，如何生成短链的问题变成了如何生成一个全局唯一的随机码，通常会有 3种做法：Base62Base62 表示法是一种基数为62的数制系统，包含26个英文大写字母（A-Z），26个英文小写字母（a-z）和10个数字（0-9）。这样，共有62个字符可以用来表示数值。如下代码：import java.security.SecureRandom; publicclass RandomCodeGenerator { privatestaticfinal String CHAR_62 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; privatestaticfinal SecureRandom random = new SecureRandom(); public static String generateRandomCode(int length) { StringBuilder sb = new StringBuilder(length); for (int i = 0; i < length; i++) { int rndCharAt = random.nextInt(CHAR_62.length()); char rndChar = CHAR_62.charAt(…

后端性能优化
type: item
date: 2025-09-05T17:03:34+08:00
description: 后端性能优化MySQL主要针对索引，对于MySQL优化的博文已经很多了，可以参阅，这里主要讲关于索引的几个点。索引：MySQL的所有C端查询我们要尽量保证必须用到索引，尤其是那种数据量增长快的表。所以不要在索引字段进行函数运算，不要使用取反等等。联合索引：联合索引使用可能是最多的了，sql没写对可能就导致了全表扫描，记住最左匹配原则，将区分度高的字段放在前面。分页查询：C端经常展示一些列表，比如文章列表，作品列表等，基本都用到了分页查询，这里需要注意的是order by fieldName。要保证fieldName在索引中，不然就可能会出现filesort了，这是个外排序，在数据量大的时候是很致命的。在我们这个项目中，我没说的时候，所有的分页查询都有这个问题。养成个好习惯：创建表的时候就设计好索引，不要到最后出事了再去加，那会数据量很大再加就迟了。分库分表一般预估年增量记录在500W以内都不需要分，我们之前是1000W以内就不分。如果只是临时做活动使用的就更不需要分了，除非活动期间量真的达到了几亿。简单介绍下分的原则数据量大就分表，否则单表的查询性能肯定是下降很多并发高就分库，因为单库的资源就那么多，支持的连接数不会太高。大多数情况下分库分表是一起的，因为量大和并发高经常是同时出现。一开始分就给足资源，二次分表成本太大，在快手一般上来就是10个库和1000张表。需要特别注意的是shardKey，围绕用户展开的就用userId来做shardKey，这在绝大多数情况下没问题的。如何分，见仁见智，可以使用shardingjdbc，优点很明显是减少开发成本。也可以自己手动分，优点也很明显，便于定制化和制定规则。如果你犹豫不决就shardingjdbc吧，尤其是小团队的时候。注意事项1、减少操作数据库次数比如我要批量更新用户的奖励，有人会写这样的代码for (UserReward r : rewardList) { rewardDao.update(r); }如果rewardList的size=10,那会操作数据库10次，也就是10次IO，而明显我们可以一次批量更新解决：rewardDao.batchUpdate(rewardList);虽然看着是那么理所当然，我们的项目甚至不少地方有下面类似的代码User user = userService.getById(userId); // doSomething userService.updateById(user); // doSomething2 userService.updateById(user); // doSomething3 userService.updateById(user);明明可以一次update就解决的为什么要update多次？引申一下，有的时候甚至都不需要操作数据库，这种情况很多时候不容易发现。举个例子，之前活动的时候在活动页面会展示任务信息和用户获得的奖励。// 查询用户任务 UserTask userTask = userTaskService.getById(id, userId); // 构建外显响应 UserTaskResp userTaskVo = buildVo(userTask); // 从结算表查询结算信息，从而得知获得的奖励 UserTaskSettlement s = userTaskSettlementService.getByTaskId(userTaskId, userId); // 填充奖励信息 fillReward(userTaskVo, s);活动页的流量是很大的，平白无故增大了结算表的流量。因为大部分用户是完不成任务的，所以根本没有获得奖励，所以可以判断用户是否完成了任务，只有完成了任务才去查询结算表即可。使用迭代器查询如果我们要查询的数据量很多，比如瓜分活动需要查出来所有参与并完成活动的用户，假设就一张表，有2000W数据，满足要求的用户可能有百万。如何做？直接一个批量查询的sql？肯定是不行的会出现包溢出异常一次查询大量数据到内存，会占用大量内存甚至full gc。正确的做法是分批查询，比如每次查询200条，然后进行处理。当然，不介意写while这种循环，一来不优雅，二来容易写出死循环的代码，最后也没法复用。可以参考下面的迭代器写法import com.google.common.collect.AbstractIterator; import org.apache.commons.collections.CollectionUtils; import java.util.Iterator; import java.util.List; import java.util.function.BiFunction; impo…

GraalVM替代JVM的方式方法和不足
type: item
date: 2025-06-03T16:03:26+08:00
description: GraalVM替代JVM的方式方法和不足GraalVM 基本上可以看成是Oracle大力发展的新一代JVM，但是目前的使用情况还不大乐观，而且逐渐发现大家都有往GO语言转的趋势，本文具体分析一下替代方案和不足之处，为什么大家还是更希望使用GO。GraalVM与JVM关系JVM 全称 Java 虚拟机，我们都知道，Java 程序是运行在虚拟机上的，虚拟机提供 Java 运行时，支持解释执行和部分的（JIT）即时编译器，并且负责分配和管理 Java 运行所需的内存，我们所说的各种垃圾收集器都工作在 JVM 中。比如 Oracle JDK、OpenJDK ，默认的 JVM 是 HotSpot 虚拟机。GraalVM 可以完全取代上面提到的那几种虚拟机，比如 HotSpot。把你之前运行在 HotSpot 上的代码直接平移到 GraalVM 上，不用做任何的改变，甚至都感知不到，项目可以完美的运行。GraalVM主要想搭建一个Framework，最终目的是实现支持任何一种语言，可以共同跑在 GraalVM 上，不存在跨语言调用的壁垒。GraalVM 和JDK关系Java 虚拟机都是内置在 JDK 中的，比如Orcale JDK、OpenJDK，默认内置的都是 HotSpot 虚拟机。GraalVM 也是一种 JDK，一种高性能的 JDK。完全可以用它替代 OpenJDK、Orcale JDK。GraalVM 如何运行 Java 程序GraalVM - 还包含 Graal （JIT）即时编译器，可以结合 HotSpot 使用GraalVM – 是一种高性能 JDK，旨在加速 Java 应用程序性能，同时消耗更少的资源。GraalVM - 是一种支持多语言混编的虚拟机程序，不仅可以运行 JVM 系列的语言，也可支持其他语言。GraalVM 提供了两种方式来运行 Java 程序。第一种：结合 HotSpot 使用GraalVM 包含 Graal （JIT）即时编译器，自从 JDK 9u 版本之后，Orcale JDK 和 OpenJDK 就集成了 Graal 即时编译器。这样Java 既有解释运行也有即时编译。当程序运行时，解释器首先发挥作用，代码可以直接执行。随着时间推移，即时编译器逐渐发挥作用，把越来越多的代码编译优化成本地代码，来获取更高的执行效率。即时编译器可以选择性地编译热点代码，省去了很多编译时间，也节省很多的空间。比如多次执行的方法或者循环、递归等。JDK 默认使用的是 C2 即时编译器，C2是用C++编写的。而使用下面的参数可以用 Graal 替换 C2。-XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompilerGraal 编译器是用 Java 实现的，用 Java 实现自己的编译器。Graal 基于一些假设的条件，采取更加激进的方式进行优化。采用 Graal 编译器之后，对性能有会有一定的提升。但是Graal，VM不支持JDK8第二种：AOT 编译本地可执行程序AOT 提前编译，是相对于即时编译而言的。AOT在运行过程中耗费 CPU 资源来进行即时编译，而程序也能够在启动的瞬间就达到理想的性能。例如 C 和 C++语言采用的是AOT静态编译，直接将代码转换成机器码执行。而 Java 一直采用的是解释 + 即时编译技术，大多数情况下 Java 即时编译的性能并不比静态编译差，但是还是一直朝着 AOT 编译的方向努力。但是 Java 对于 AOT 来说有一些难点，比如类的动态加载和反射调用。GraalVM 的 AOT 编译实际上是借助了 SubstrateVM 编译框架，可以将 SubstrateVM 理解为一个内嵌精简版的 JVM，包含异常处理，同步，线程管理，内存管理（垃圾回收）和 JNI 等组件。SubstrateVM 的启动时间非常短，内存开销非常少。除了运行时占用的内存少之外，用这种方式最终生成的可执行文件也非常小。这对于云端部署非常友好。目前很多场景下都使用 Docker容器的方式部署，打一个 Java 程序的镜像包要包含完整的 JVM 环境和编译好的 Jar 包。而AOT 方式可以最大限度的缩小 Docker 镜像的体积。缺点对于反射这种纯粹在运行时才能确定的部分，不可能完全通过优化编译器解决，只能通过增加配置的方式解决。多语言支持GraalVM 中的另一个核心组件 Truffle是一个用 Java 写就的语言实现框架。基于 Truffle 的语言实现仅需用 Java 实现词法分析、语法分析以及针对语法分析所生成的抽象语法树（Abstract Syntax Tree，AST）的解释执行器，便可以享用由 Truffle 提供的各项运行时优化。就一个完整的 Truff…

怀化之旅-2025.5.5
type: item
date: 2025-05-09T09:25:00+08:00
description: 怀化之旅-2025.5.5今天的路线是玉皇宫——人民公园——市政府——市民广场——回家。起床！今天的早餐时白糖包和香菇干笋包（好吧，这个也放了辣椒哈哈哈）玉皇宫早上来参拜一下玉皇宫，据说这是这边最大的道教宫殿，还蛮有名气，其实这个确实挺好看的，当然师傅们可能就是香火比较少，所以遇到每个人都会问是不是来拜拜的。我碰到了一对情侣也是来参观的，他们不好意思，我就和师傅说了，我们仨都是来参观的，师傅作了作揖，也很愉快地让我们进去了，只是特地要求按照规矩来，不要走中间，左右两侧进入。山大门在修缮，有很多神像都在修：玉灵官、哼哈二将、青龙、白虎、朱雀、玄武、龙王、武陵山神、城隍爷。这里就不给大家放神像的图片了，因为还在修复中，他们估计也不太愿意让人见到这个模样。踏着阶梯上来可以在这里拍到很不错的一个整体景色可以看到对面的小区，也可以看到怀化市的风景。这里你要说百家姓呢，倒也不一定，主要还是怀化这边的姓氏，类似于祠堂一样的感觉吧，不过确实供奉了一些神像例如女娲、炎帝、黄帝，所以也算是比较有意思的宫殿。财神殿的话也是肯定会有的了。如果你去佛教的话一般就是地藏王在右侧，然后左侧珈蓝关公，所以怀化的玉皇宫是比较纯粹的道教了。走，去市政府如果开电动可能更快，但是我不急，在这里和一个老奶奶聊起了天。对方捡到了一张身份证，还问我能不能帮忙送给他，因为是沅陵县的实在太远了，而且我要返程了，我看了下失主年龄不算很大，估计会补办的，就让她别再担心了。老奶奶问我哪里人，我说广东的，她说她有个佛山亲戚清明节带他们一起去佛山玩了。但是由于熟悉这里的环境，觉得还是回来比较舒服。她还问我来这里干嘛，是来出差吗？哈哈哈，我看起来很像来出差的吗？我记得我搭高铁来的时候，隔壁坐的怀化阿姨也问我是不是来出差，可能怀化这座城市还是更偏向做生意吧。离市政府最近的地方其实是妇幼保健院，所以就在这里下车了。老大爷们富有生活气息地在这里唱歌，搞艺术创作。说实话，我觉得古城还不如人民公园，这里跑跑步放松放松，看看山水也是很不错的。整个怀化地政务都在这一圈了，有不同的业务局，例如住建局啊等等。因为想去法院看看，所以得去以前的市民广场，就在这里等公交，当然实际上要去的是“市委”站。法院怀化蛮神奇的，真的有很多广东肠粉，粤菜也不少，有很多早茶，虽然正宗不正宗我没试过，但是总归可能和广东的情谊也蛮深。怀化最近都在宣传这个，其实你在哪里都能看到。茶颜悦色要离开怀化回广州了，离开前再来尝试喝一杯茶颜悦色吧，这次我要喝声声乌龙了。谢谢某人推荐，很好喝。在这里打车回酒店收拾东西，打车正好遇到了拼车的，遇到了个带小孩的母亲。我也不是很急，所以我就跟司机说可以的，没问题。我觉得母亲带小孩还蛮幸苦，司机还一直跟我说现在的年轻人比较自私自我，我觉得吧应该要分情况考虑吧，也希望大家能多给这个社会一些包容的机会。候车厅好多人啊！回到广州了。

怀化之旅-2025.5.4
type: item
date: 2025-05-09T08:46:00+08:00
description: 怀化之旅-2025.5.4今天带大家去凤凰古镇，说实话不知道为啥要去，反正就是去了。凤凰古镇确实很商业化，很多女生去那边拍照，在高铁上就已经在我旁边化妆。凤凰古镇可能夜景才是最好看的，但是我是白天去的，我个人觉得比前面两个古城要好玩一些，可能是因为有沈从文的一个印象加成，也可能是因为这地方是确实有山山水水的。早餐一大早起床，今天是坐高铁过去凤凰古城！早上起床先去吃二合一，对，也是某人推荐的。因为这家店做外卖，然后离的也不是很远，所以就慢慢走过去了。这家店应该还可以，如果不要辣椒记得提前和老板说，我是没说，因为想感受一下到底有多辣。可以选择不同的臊子，我选了血鸭。面食其实更偏向北方，因为面有韧性而且还带有淀粉的感觉，这种是我在广州接触不到的，老家捞面倒是有这种类型的（要不说潮汕人也很多北方的习性）。说实话，这个比怀化名堂要辣，如果不带水真的是有点撑不住。出发我没想到还有免费充电区，这个比我去过的很多车站真的要好很多了！上车！对了，之前不是说有个陆港？出怀化到凤凰古城的路上就可以看到。出站了，有点羡慕别人。由于去的时间比较早，我打算回来再搭磁悬浮，去直接接驳车。说是接驳车，实际上就是一辆公交车，但是可以开的很快，在郊外和市内飞驰！我选择了奇峰广场，没有选择南华里，大多数人是去南华里的。当然我觉得奇峰广场广场挺好，可以从下游开始看完，然后回到市区。要了个苗饼，其实就是蔬菜做的底子，类似于青稞之类的，里面夹着鸡蛋和一些小料。其实这里有个小插曲，我说了不想要辣的（二合一后遗症太严重），但是阿姨还是加上去了，她说很香，好吧，确实没那么辣哈哈哈！苗寨要收门票，我是没有上去，一方面确实有点害怕苗族的蛊虫（虽然不信，但是虫子还是有点担心）逛古城古城很多山水很好看！臭美一下！忘了凤求凰的典故了，可能也是爱而不得吧，不知道，想到这突然有点小难过。喝杯奶茶吧还蛮好喝的，点了翠兰，招牌可能没什么问题。小哥跟我说要等一会儿，因为店里就他一个人招呼我，但是还要做很多杯。旁边就是非遗馆，可以稍微歇歇脚，也可以看看。这里还有民族英雄郑国鸿。沈从文旁边是沈从文墓，可以过来稍微感受一下文学大家的氛围。沈从文书屋这里有个沈从文书屋，可以买书，也可以借阅，可以感受沉淀，整个书屋的装扮很不错。如果可以作弊，我会想你念你，到最后的荼蘼——《沉醉的青丝》，写到这里突然想起这首歌。继续逛古城感觉夜景应该会很好看吧，这个水上集市。河虾是活蹦乱跳的，虾饼趁热吃。作为潮汕人，怎么能不来天后宫看看呢？哈哈哈，这里面有两个女生，说什么都可以不拜，财神殿一定要拜。年轻人的精神状态如此可见一斑。旁边的阿嫲说，到了这里都要拜，怎么可以这么说。哈哈哈，又是新老观念的冲击。逛着逛着都到南华里来了，看到这个突然想起和某人讨论过提字的人。我没进去，因为估计没啥好看的，门票卖的有点贵。这是军事文化好像，反正我不感兴趣，不过门口可以猜拳赢取门票。说实话后面没啥能看的了，整个古城也就这样，准备跑路去吃午饭，想吃那间亲妈牛肉！去吃午饭啦！跑路去吃饭的路上发现一件事情，首先是南华里其实可以吃饭，然后也可以从这里坐接驳车回去。但是我想去的亲妈牛肉其实在客运站那边，就是有个5km左右的距离，然后呢！！！！！这边其实是打不到车的！顶，整个凤凰古城打车居然要用自己的APP，所有的高德、美团、滴滴全都打不到的。而且不知道是不是因为节假日的原因，公交也完全不上班，于是乎！！！我不得已带上了头盔，选择了年轻人最喜欢的方式——共享电动。好！经过一番波折总算是来到这家店了！点了份小炒黄牛和一份蒜炒油麦菜，一个人完全够吃！广东人吃辣实力一般哈哈哈。旁边就是集散中心，溜了溜了，打算回怀化了，这边也不好玩。找寻凤凰历史文化博物馆本来吃完打算逛完这边历史文化博物馆再回去的，因为担心赶不上车还买了后面的票，没想到博物馆倒闭了。。。。说实话这玩意儿能倒闭我是没想到的，或许政府想着更新一下吧，反正里面全空的，也有可能合并到其他博物馆里面去了。磁悬浮人生中第一次坐磁悬浮列车，主要还很担心赶不上高铁，怕磁悬浮列车很慢，结果一问就十来分钟，那还蛮早的。高铁站返程这会儿回去的人超多，可能都到5.4了，大家伙们已经玩够了想回去了。笑死，全国都已经在推行取消车票领取了，只有凤凰古城还可以领取到车票。不管在哪里，总能看到你！广铁U彩！你到底卷走了多少人的车票钱。晚餐回到怀化了，由于司机特别推荐，晚上去吃了烧烤小龙虾。怀化人可能过的还是蛮压抑的，因为司机师傅说他一辈子都不想买房了，他看起来还蛮年轻的。年轻人都在往外面跑打工，怀化的工资比较低，然后消费又比较高，不过哪个城市都一样吧，这就是快速城市现代化导致的结果。前代人享受的东西，需要后代人不断去还债，所以大家才会这么颓废吧。但是还是希望大家充满对生活的希望，找到也爱到对的人，互相在这个世道下好好的生存下去…

怀化之旅-2025.5.3
type: item
date: 2025-05-08T15:36:00+08:00
description: 怀化之旅-2025.5.3好像没办法不去古商城，毕竟网红打卡地，虽然去之前已经看到评价一般了，不过终归还是想去尝试看一下。对了去这俩古城很麻烦，就是本地人都是开车。嗯，作为外地人的我选择了大巴，前一晚还在各种做攻略。没想到怀化的交通一般，但是汽运站还是很不错的，建议大家出行可以选坐大巴。大早上来吃小笼包听说这个很出名，所以还是来尝试一下，我自己本人对皮厚皮薄没什么特别的偏爱，不过怀化的小笼包确实偏向北方，因为我在扬州的时候尝试过，面皮筋道而且厚实。不错，还配了海带汤，可能知道水份比较少，怕客人噎着了。怀化人好像真的蛮喜欢做生意，结账都是互相道发财，这点和广东逢人便说帅哥可能有异曲同工之妙。云集路大早上没什么人，还蛮空的：今天准备去的洪江古商城和黔阳古城都没什么好玩的，说实话，不是很有看点。洪江古商城确实很差，黔阳古城稍微有点人气吧，还是可以逛逛。出发从怀化南客运站买票出发，其实微信公众号可以买，但是就只有电子票，怎么说呢，如果你想要留纸质票是可以线下过来买的，毕竟没多少人，反正随便买。从怀化南到洪江古商城需要一个半钟头的大巴，注意要看好汽运站上面对应的车牌号，不要上错车，车上其实是随便坐的。当然也有一些老年人可能比较较真，大家多体谅一下。中间是要路过黔城的，天气蛮不错的，坐大巴其实也可以略微欣赏一下沿途风景。哦，这里是黔城高铁站，但是吧，反正都是差不多的时间，坐高铁真不如坐大巴。现在我知道某人为什么对我发的风景照不是很感兴趣了，如果一直生活在山清水秀的地方，确实会对城市里面一些突然出现的风景完全没感觉。洪江古商城大巴车会指引各位下车，因为它就开去前面不远的客运站，反正洪江古商城是可以下车的，如果你实在觉得可能会坐过站，请直接跟司机大声说到洪江古商城指引你下车。（但是我觉得还是没必要来玩）可能是我来的有点早，反正没多少人，这个是比较标志性的建筑了，一把伞一个包袱，然后来洪江当老板。这地方开发的不怎么样，反而门票还要收你90块钱，我觉得真的没啥意思。只能说可以留个纪念，里面的明清时代的房子是有，但是能作为展示的一些参观地区不多，还有一些人在住，然后还有正在进行修缮的，整个景区弄得不是特别好。我怀疑钱都投到这里做一些摆设了。古城区花了钱进来可以看古城区，当然古城区没什么特别好看的。外面免费的新城区建设的也还行，但是主要没啥人，所以很多店铺也没有开放。整个古城区都是类似这种建筑，其实吧，这种建筑风格其实在潮汕地区也很多见。洪商开的几个展区，说实话不多，也就稍微可以看一看。古人的商训，现在要是这么做估计就没办法做买卖了。外面好像有卖这个的，但是应该运不回去哈哈哈。其实整个片区蛮多各种不同的会馆的，古时候这里应该也是一个交通枢纽和一些会馆驻扎的地方，类似于一个租界一样的感觉。里面是药王孙思邈，感觉还蛮常见。然后又要走一些很麻烦的台阶路，感觉古人也会觉得很痛苦吧，比较马车也动不了。接下来就可以看到这个很典型的宣传语了——一个包袱，一把伞，来到洪江，当老板。遇到了一个表演团的人，在讨论怎么作表演，但是说实话，居然不是训练好的，说明团队一直在变动，感觉应该没什么人来看导致的。据说洪江这地方的福字比较特殊，有洪福齐天的说法，当然这个是它自己标识的，我个人认为不可考据。没去动他，毕竟我也已经不是顽皮的小孩了，当然很可能棋子也是粘住的。这里搭了一个喜房，挺好的，怎么说呢，可能算是比较出乎我意料的一个展厅。常德会馆其实是碑文展，碑文其实怎么说呢，我是看不懂，但是写的确实好，神韵之类的吧，但是我艺术鉴赏能力有限，不是很感兴趣。镖局有表演，反正我是没看，因为据说只表演个2-3min，没啥意思。看一下关公还是可以的，左右两侧有兵器房，可以看一下一些冷兵器的形状，反正也肯定是假的。阿嫲在那里一通算，这个算盘是可以动的，被我拍的不好意思了哈哈哈，其实感觉她算的应该还蛮自信的。这就是以前地方收税的地方，粮食收成后，地方从民众手里收钱。看了一下有点意思，可能这边也有新的房子建设，emmm，不过谁买在这里，感觉都不好。哈哈哈，我真的好受小狗狗欢迎，上次去温州那只也是躺好了肚皮想让我rua，这次这只也是很想奔向我和我玩。这个是我爬上去打算看看有没有什么好玩的，结果发现并没有，好吧，上面就一户人家。新城区这个大佛寺其实香火还蛮鼎盛的，里面有很多老阿嫲在念经，现在谨慎一些了，反正不好拍里面的佛像，有兴趣的可以去新城区溜溜，我个人认为外面这层新城比里面有看头。根本没人来这里玩！我爬上上面的这个楼阁对着对面拍的。这里简述了洪江古商城的历史变更，说真的你这个放外面，我进去里面看什么了，里面一点说明和指引都没有，整个景区开发得稀巴烂。阿姨们在外面跳舞——社会主义好，哈哈哈，一方面感叹湖南确实受到毛主席影响颇深，另一方面就是感叹老年人的活力比年轻人强多了。这里有很多店铺基本没开，旁边…

怀化之旅-2025.5.2
type: item
date: 2025-05-08T09:29:00+08:00
description: 怀化之旅-2025.5.2说实话，作为一个广东人，如果选择去湖南的话，应该首选是长沙、衡阳、郴州、岳阳之类的地方。我选择了怀化确实蛮神奇的，我来怀化的初心是感受一下这座城市的文化。出发从广州南站高铁站出发抵达怀化一共需要五个多小时，因为怀化地理位置比较偏僻，夹在贵州和广西中间，按理来说这种地理位置大概率是要出现很多山山水水的，果不其然，怀化的交通确实没有想象中的便利。我这天选择的是七点多的车，所以我还是蛮赶的，不过幸好无惊无险，通过了五一节的大考验。很多游客正在集中排队检票入站。路过郴州，阳光还算明媚，这趟车从广州往粤北开，第一站是韶关，反正这种路线肯定不是去长沙的，所以车上的人都是去衡阳之类的地方。在列车上消磨时间其实是很麻烦的，现在的我有点迷上了纪实文学，这本《饱食穷民》推荐给大家，讲述了关于社会经济状态变换后，人民对生活和精神双层的诱惑、打击和调解，还是蛮有看头。抵达由于本趟列车总共也就五个多小时，其实和我之前去福州上学时间是差不多的，所以还可以忍受，相对来说开往这个方向的列车时速还要更快一些，所以感受可能更好，从广州开往福州的列车反而因为时速变得很慢，让人可能难以忍受。出站就可以看到这个国际陆港的大招牌，当然实际上确实有这么个陆港，但是不在市内，往后可能会给大家pou上这个照片，怀化也是一个物流城市，跟攀枝花一样，也是火车拉来的城市。其实我是蛮兴奋的，不知道是来到一座新城市的兴奋呢，还是因为当时觉得还没弄丢自己的一个兴奋。午饭到了出站口去B1社会停车场就可以打车了，怀化打车相对方便，不愁打不到车，当然如果你恰好碰上那群去医学院的学生就除外。这是我第一天来到怀化，看到那个小笼包了吗？后续我会去吃它。怀化的公共交通确实不够便利，但是共享电动我还是会开的，不过在这里没有开，因为我怕不熟悉路况。后续在凤凰古城是真的开了，因为实在受不了打不到车。说实话这条街如果再拥挤一点真的很像香港，香港给我的压迫感太强了，幸好怀化不是。随便找了家农家餐馆，某个被我同样弄丢的人推荐了血鸭，于是迫不及待找了这家餐馆，打算吃一下。还不错，我发现出了广东的好处就是任何餐馆都愿意提供纸巾，这点广东能不能学一下？我没去过湖南其他地方，怀化这个地方的特点是直接给你上一大桶饭，老板娘见我一个人，说建议别点那么多菜了。我点了份血鸭也有可能吃不完，顺带点了份清蒸丝瓜（广东人真的很害怕吃辣）。血压味道不错，肉质韧性十足，同时还有点辣，就是肉其实可能没那么多。清蒸丝瓜我就不介绍了，这玩意儿在哪里吃都是那个味道。香洲桥因为某人推荐我去喝杯茶颜悦色，我原以为只有长沙有，没想到大湖南可能分布的店还蛮广，反正我吃饱了不饿正好溜达溜达。这里其实有个香洲公园，旁边怀化三中在这里有个停车场，离我想去的怀化博物馆也蛮近。大中午路上没多少人，天气有点热，但是还好，我比较兴奋。这里的路感觉根本没有修，怀化市应该对这段路再修理一下，这样别人接送孩子，或者接送老师都比较方便。今天能做的其实不多，反正逛一逛，主要看了博物馆和三中。前往茶颜悦色去找最近的茶颜悦色的路上需要先经过三中，远处拍了一张照片，后面再来会会它你或许无法理解怀化这条路为什么搞了个很大的地下通道，说实话这里面乌漆嘛黑的，如果不是有个儿童乐园，估计很难走这条路。我很怀疑怀化市民是不是走惯了，这里面的指示牌确实比较难分辨，主要是我不熟悉这些指示牌的地点，不过还好，导航还可以接受。差不多快到了，这里面有个商场，商场里就有我需要喝的东西了。茶颜悦色一如既往的多人，不过这个还好吧，至少应该比长沙人少了很多。点了杯幽兰拿铁，嗯，某人推荐的，确实好喝，怎么说呢，这玩意儿很容易上瘾，因为你喝了感觉跟没喝一个样子。就特别舒爽的茶底，我记得很久之前喜茶也这样，然后古茗的乌龙茶底没换之前也这样，就非常好喝，可惜现在已经完全不行了。公路局实在是没人给我指引了，迫不得已找了一下怀化的网友（其实也是以前认识的学生），让我去他老爸单位看看。还蛮不错的，感觉只是因为守门的在睡大觉，反正我进来他没能抓到我，但是后面醒来就开始盯着我了，不过怀化对市民包容度还是很高的，不会直接赶你出去。过来拍几张照片就遛了，总不能真的去拜访叔叔哈哈哈，不然影响人家工作（当然估计如果不是值班可能在家里睡大觉）相信我，如果看到毛主席的头像，你也会忍不住和他合影的。怀化市民一角来到一个地方必须了解一下当地的市民街角，这里给大家来几张比较有趣的。我觉得怀化市这条路修的是很不错，很宽敞，就是电动还是有点太猛了，不过要是我在这里生活可能也这样。这个建筑的风格也是蛮有意思的，过来的时候看了一下哈哈哈。怀化人民可能真的喜欢辣椒，在路上也能看到别人晒辣椒。这里是地下通道的菜市场，很多本地人在这里买水果和买菜（！！！傻了，早知道在这里买水果，酒店附近那家坑了我几十块的杨梅！！！！）怀化三中到三中来…