angela 发布的文章

1. 前言

  1. 限于一些原因,比如穷😄哈哈,买不起服务器,但是又想看自己写完项目后的效果,怎么办呢 ,这篇文章帮你实现想法
  2. 其实非常简单 就是利用了HbuilderX 打包查看,知道如何做的就不用往下看了
  3. 就是通过 把写好的项目转为安卓apk文件 在手机上查看效果,而且不跨域

2. 打包准备工作

  1. 不管是自己的vue还是react项目亦或者其他项目
  2. 这里以vue项目举例
  3. 要理解只有前端浏览器才有跨域,手机app是没有跨域的哦
  4. 所以一些会在网页跨域的项目,也可以在手机上自己玩哦,注意一定要合法合规

3. 代码中需要注意的 打包事项 路由模式

    1. vue路由模式 一定为Hash模式
import { createRouter, createWebHashHistory } from 'vue-router'

const router = createRouter({
  history:createWebHashHistory("/#"), 
   routes
}
    1. history:createWebHashHistory("/#"),

4. baseUrl

  1. 注意项目的中代理服务器地址,要在请求里面写全,因为打包后可不走devServer哦
  2. 比如 /api换成 let baseUrl = "http://yzs.cn"
  3. 具体看自己的 请求封装
  4. 如果有在线字体图标, 图标引入地址@font-face中的url前加http
  5. 所有的代理服务器 都要写改哦

5. vue.config.js 打包注意事项

  1. publicPath : "./"
  2. 这就够用了
  3. 打包后 默然在项目根目录的 创建dist文件夹
  4. 然后可以 运行下 dist下面的 index.html文件 看看有没有界面 或者什么报错,右键以服务器运行就可以

  • 扩展
  1. 如果想要多配置点东西 比如
  2. 打包后的目录配置 outputDir:"yzs",
  3. 页面配置出口标题 等可以配置 pages字段
  4. 但是这里的配置不是我们 今天的重点,不配置也没事的
const {
    defineConfig
} = require('@vue/cli-service')
module.exports = defineConfig({
    publicPath: "./",
    transpileDependencies: true,
    lintOnSave: false,
    // 打包之后的路径
    outputDir:"yzs",
    // 打包的首页
    indexPath:"index.html",
    pages:{
      // 打包之后的页面配置
      index:{
          // 打包的入口文件
          entry:"src/main.js",
          // 打包的模板
          template:'public/index.html',
          // 打包之后的页面
          filename:"index.html",
          title:" 浏览器的标题"
      }
    },
    devServer: {
        // 启用压缩,打包之后代码压缩
        // compress:true ,
        // port:9000,
        // host:"localhost",
        open: true,
        // hot:true,// 支持热更
        proxy: {
            '/dyapi': {
                target: 'http://open.douyucdn.cn/api/RoomApi',
                ws: true, //是否支持websocket
                changeOrigin: true,
                pathRewrite: {
                    "^/dyapi": ""
                }
            }
        }
    }
})


6. HbuilderX 发布 app

  • 准备工作: 注册HbuilderX账号完成实名制验证

1.HbuilderX开发工具左下角就可以注册

  1. 一定要完成实名制验证
  2. 所以的操作按照提示做就行

  1. 打开 HbuilderX 创建 5+App项目

  2. 界面
    创建项目.png
  3. 复制上面 项目打包后的文件 :比如 dist下面 全选复制
  4. 粘贴到 刚刚创建的 5+App项目下面 , 直接替换
  5. 选择5+App项目下面的文件 ,顶部菜单选择 发行

  6. 步骤
    发行.png
  7. 选择云打包

  8. 打包配置
    1.png
  9. 证书选择 公共测试证书
  10. 不要勾选iOS

  11. 常见错误 比如 通讯录权限某某权限 解决
    1.png
  12. 选择 manifest.json文件 取消勾选对应的权限模块
    就行

  13. x86勾选
    截图.jpg

  1. 打包过程
    打包过程.png
  2. 下方控制台会有打包进度,有时候慢,有时候快
  3. 打包完成会有绿色的提示, 一般情况下打包后的 安卓apk文件
    在刚才创建的5+App项目的 项目/unpackage/release/apk/文件名.apk
  4. 绿色的提示有具体的路径 看下就行
  5. 把这个apk文件发送到手机 安装下就可以在手机上玩了

7. 后记

  1. 打开开manifest.json文件, 配置AppID, 应用名, 图标, 取消模块配置中的Contact(通讯录), 勾选App常用其他设置 中的 x86
  2. manifest.json文件是应用的配置文件,用于指定应用的名称、图标、权限等。HBuilderX 创建的工程此文件在根目录,CLI 创建的工程此文件在 src 目录。
  3. 打包遇到的问题可以百度

参考资料

manifest.json


初心

我所有的文章都只是基于入门,初步的了解;是自己的知识体系梳理,如有错误,道友们一起沟通交流;
如果能帮助到有缘人,非常的荣幸,一切为了部落的崛起;
共勉

原文链接:https://www.jianshu.com/p/d1304d4e98c4

插: 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。
坚持不懈,越努力越幸运,大家一起学习鸭~~~

3妹

2哥:3妹,题做的怎么样了啊,我游戏都打玩一局了,你做好了没呢。
3妹:不要打扰我,刚做了一题,还有2题呢。
2哥:我打游戏,你在做题,让我都有负罪感了,给我也来一道题吧。
3妹:好吧,你看这道题如何做?

讲课

题目:

给你一个字符串数组 words(下标 从 0 开始 计数)。

在一步操作中,需先选出两个 不同 下标 i 和 j,其中 words[i] 是一个非空字符串,接着将 words[i] 中的 任一 字符移动到 words[j] 中的 任一 位置上。

如果执行任意步操作可以使 words 中的每个字符串都相等,返回 true ;否则,返回 false 。

示例 1:

输入:words = ["abc","aabc","bc"]
输出:true
解释:将 words[1] 中的第一个 'a' 移动到 words[2] 的最前面。
使 words[1] = "abc" 且 words[2] = "abc" 。
所有字符串都等于 "abc" ,所以返回 true 。
示例 2:

输入:words = ["ab","a"]
输出:false
解释:执行操作无法使所有字符串都相等。

提示:

1 <= words.length <= 100
1 <= words[i].length <= 100
words[i] 由小写英文字母组成

思路:

统计每个字符出现的频次,用一个int[26]的数组,记录每个字符出现的次数,如果每个字符出现次数为words.length的整数倍的话,则可以平均分配,否则就不能平均分配。

java代码1:

class Solution {
    public boolean makeEqual(String[] words) {
        int[] ch = new int[26];
        for (String word : words) {
            for (char c : word.toCharArray()) {
                ch[c - 'a']++;
            }
        }

        for (int i = 0; i < ch.length; i++) {
            if (ch[i] != 0 && ch[i] % words.length != 0) {
                return false;
            }
        }

        return true;
    }
}

原文链接:https://www.jianshu.com/p/2f15c5258f04

前面简单描述了系统的硬件组成和操作,现在开始介绍当我们运行示例程序时到底发生了什么。在这里必须省略很多细节,稍后会做补充,但是现在我们将很满意于这种整体上的描述。

初始时,shell 程序执行它的指令,等待我们输入一个命令。假设我们现在要运行一段 hello 程序,当我们在键盘上输入字符串 “./hello” 后,shell 程序将字符逐一读入寄存器,再把它存放到内存中。

当我们在键盘上敲回车键时,shell 程序就知道我们已经结束了命令的输入。然后 shell 执行一系列指令来加载可执行的 hello 文件,这些指令将 hello 目标文件中的代码和数据从磁盘复制到主存。数据包括最终会被输入的字符串 “hello, wolrd\n”。

利用直接存储器存取(DMA,将在第 6 章中讨论)技术,数据可以不通过处理器而直接从磁盘到达主存。

一旦目标文件 hello 中的代码和数据被加载到主存,处理器就开始执行 hello 程序的 main 程序中的机器语言指令。这些指令将 “hello, world\n” 字符串中的字节从主存复制到寄存器文件,再从寄存器中复制到显示设备,最终显示在屏幕上。

整个步骤如下图所示:


原文链接:https://www.jianshu.com/p/9a6fb66a2917

在分布式架构中,我们会将不同功能模块化,部署到不同的服务器上,这时不同模块之间的通讯就由RPC框架完成,上次介绍了Dubbo的基本使用,知道了它基于Spring容器,因此在SpringBoot项目中可以很方便的使用

一、项目配置

还是利用经典的oracle部门员工表,MyBatis--初入MyBatis中可以找到创建表和数据的sql,实现mapper层和service层的分布式架构

项目依赖关系如下:

consumer最终通过Dubbo进行RPC通讯,调用provider提供的方法

创建Maven聚合项目,设置父Maven模块的pom文件为:

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.0</version>
    </parent>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
                <version>2.7.0</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <version>2.7.0</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.apache.dubbo/dubbo-spring-boot-starter -->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-spring-boot-starter</artifactId>
                <version>2.7.8</version>
            </dependency>
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-recipes</artifactId>
                <version>4.2.0</version>
            </dependency>
        </dependencies>
    </dependencyManagement>  

1. bean模块

公共的模块,被所有模块引用

导入lombok依赖:

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

创建包:

2. mapper模块

用于编写mapper层相关的代码

2.1 依赖

pom文件中导入bean模块和Mybatis相关依赖:

        <!--mybatis启动器-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--mysql jdbc-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.29</version>
        </dependency>
        <!--druid连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.9</version>
        </dependency>
        <!--mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.2</version>
        </dependency>
        <!--bean模块-->
        <dependency>
            <groupId>com.aruba</groupId>
            <artifactId>bean</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
2.2 springboot配置文件

resources目录下创建application-mybatis.yml:

# 使用mybatis-plus配置类别名
mybatis-plus:
  type-aliases-package: com.aruba.bean
  configuration:
    map-underscore-to-camel-case: true

spring:
  datasource:
    # 使用阿里的Druid连接池
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    # 填写你数据库的url、登录名、密码和数据库名
    url: jdbc:mysql://127.0.0.1:3306/mydb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    username: root
    password: root
  druid:
    # 连接池的配置信息
    # 初始化大小,最小,最大
    initial-size: 5
    min-idle: 5
    maxActive: 20
    # 配置获取连接等待超时的时间
    maxWait: 60000
    # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
    timeBetweenEvictionRunsMillis: 60000
    # 配置一个连接在池中最小生存的时间,单位是毫秒
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    # 打开PSCache,并且指定每个连接上PSCache的大小
    poolPreparedStatements: true
    maxPoolPreparedStatementPerConnectionSize: 20
    # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
    filters: stat,wall,slf4j
    # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
    connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
    # 配置DruidStatFilter
    web-stat-filter:
      enabled: true
      url-pattern: "/*"
      exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
    # 配置DruidStatViewServlet
    stat-view-servlet:
      url-pattern: "/druid/*"
      # IP白名单(没有配置或者为空,则允许所有访问)
      allow: 127.0.0.1,192.168.8.109
      # IP黑名单 (存在共同时,deny优先于allow)
      deny: 192.168.1.188
      #  禁用HTML页面上的“Reset All”功能
      reset-enable: false
      # 登录名
      login-username: admin
      # 登录密码
      login-password: 123456
2.3 日志配置

resources目录下创建logback.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
    <property name="LOG_HOME" value="${catalina.base}/logs/"/>
    <!-- 控制台输出 -->
    <appender name="Stdout" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 日志输出格式 -->
        <layout class="ch.qos.logback.classic.PatternLayout">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
            </pattern>
        </layout>
    </appender>
    <!-- 按照每天生成日志文件 -->
    <appender name="RollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
            <FileNamePattern>${LOG_HOME}/server.%d{yyyy-MM-dd}.log</FileNamePattern>
            <MaxHistory>30</MaxHistory>
        </rollingPolicy>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
            </pattern>
        </layout>
        <!--日志文件最大的大小-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>10MB</MaxFileSize>
        </triggeringPolicy>
    </appender>

    <!-- 日志输出级别 -->
    <root level="info">
        <appender-ref ref="Stdout"/>
        <!--暂时不需要输出到文件-->
        <!--<appender-ref ref="RollingFile"/>-->
    </root>

    <logger name="com.aruba.mapper" level="DEBUG"></logger>


    <!--日志异步到数据库 -->
    <!--<appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
            日志异步到数据库
            <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
               连接池
               <dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource">
                  <driverClass>com.mysql.jdbc.Driver</driverClass>
                  <url>jdbc:mysql://127.0.0.1:3306/databaseName</url>
                  <user>root</user>
                  <password>root</password>
                </dataSource>
            </connectionSource>
      </appender> -->

</configuration>

创建包:

3. api模块

用于定义Provider的对外接口

导入bean模块依赖:

        <dependency>
            <groupId>com.aruba</groupId>
            <artifactId>bean</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

4. provider模块

远程对象提供者

4.1 依赖

导入mapper模块、api模块、dubbo相关依赖:

        <!--springboot启动器-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <!--dubbo-->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
        </dependency>
        <!--zookeeper-->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
        </dependency>
        <!--mapper模块-->
        <dependency>
            <groupId>com.aruba</groupId>
            <artifactId>mapper</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!--api模块-->
        <dependency>
            <groupId>com.aruba</groupId>
            <artifactId>api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
4.2 springboot配置文件

配置dubbo相关,以及引入mapper模块中的配置:

dubbo:
  application:
    name: dubbo-provider
  registry:
    address: zookeeper://192.168.42.4:2181

# 加载其他配置文件,加载其他application-*.yml文件,多个名称之间使用逗号分隔
spring:
  profiles:
    active: mybatis
4.3 SpringBoot启动类

创建包:

创建启动类,开启Dubbo、Mapper扫描:

@SpringBootApplication
@EnableDubbo
@MapperScan("com/aruba/mapper")
public class ProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(ProviderApplication.class, args);
    }

}

5. 项目结构

完成上面步骤后,项目结构如下:

二、实现分布式项目RPC通讯

实现查询部门信息,并展示到网页上

1. bean模块下创建部门类

内容为:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Dept implements Serializable {
    /**
     * 部门编号
     */
    private Integer deptno;
    /**
     * 部门名称
     */
    private String dname;
    /**
     * 地址
     */
    private String loc;
}

2. api模块中新增查询接口

内容为:

public interface DubboDeptService {
    public List<Dept> findAllDept();
}

3. mapper模块中新增DeptMapper

内容为:

public interface DeptMapper extends BaseMapper<Dept> {
}

4. provider模块中实现对外接口

内容为:

@DubboService
public class DubboDeptServiceImpl implements DubboDeptService {

    @Autowired
    private DeptMapper deptMapper;

    @Override
    public List<Dept> findAllDept() {
        Wrapper<Dept> queryWrapper = new QueryWrapper<>();

        return deptMapper.selectList(queryWrapper);
    }

}

注意需要@DubboService注解,表示注册到Dubbo中

5. 新建dept模块

业务模块代码编写

5.1 依赖

导入springweb依赖、dubbo、api模块等:

        <!--web启动器-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--dubbo-->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
        </dependency>
        <!--zookeeper-->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
        </dependency>
        <!--thymeleaf-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!--api模块-->
        <dependency>
            <groupId>com.aruba</groupId>
            <artifactId>api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
5.2 springboot配置文件

配置dubbo:

dubbo:
  application:
    name: dubbo-dept-consumer
  registry:
    address: zookeeper://192.168.42.4:2181
5.3 springboot启动类

开启dubbo:

@SpringBootApplication
@EnableDubbo
public class DeptApplication {

    public static void main(String[] args) {
        SpringApplication.run(DeptApplication.class, args);
    }

}
5.4 service层代码

定义接口:

public interface DeptService {

    public List<Dept> findAllDept();

}

实现接口,使用provider对外对象进行调用获取部门信息:

@Service
public class DeptServiceImp implements DeptService {

    @DubboReference
    private DubboDeptService dubboDeptService;

    @Override
    public List<Dept> findAllDept() {
        return dubboDeptService.findAllDept();
    }
    
}
5.5 controller层代码
@Controller
public class DeptController {

    @Autowired
    private DeptService deptService;


    @RequestMapping("dept")
    public String dept(Model model) {
        model.addAttribute("deptList", deptService.findAllDept());
        return "dept";
    }

}
5.6 html展示

resources目录下新建templates文件夹,并创建一个html文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<style>
    #tb {
        border: burlywood 1px solid;
        width: 50%;
        margin: 0 auto;
    }

    #tb th, td {
        border: 1px solid bisque;
        text-align: center;
    }
</style>
<body>
<table id="tb" cellpadding="0px" cellspacing="0px">
    <tr>
        <th>编号</th>
        <th>部门名称</th>
        <th>地址</th>
    </tr>
    <tr th:each="dept : ${deptList}">
        <td th:text="${dept.deptno}"></td>
        <td th:text="${dept.dname}"></td>
        <td th:text="${dept.loc}"></td>
    </tr>
</table>
</body>
</html>

启动provider和dept的springboot,并进行浏览器访问:

数据库日志打印是provider输出的:

项目地址:

https://gitee.com/aruba/dubbo.git

原文链接:https://www.jianshu.com/p/c6a9526a7c19

将业务领域模型转换为程序设计

一般有2种设计思路:贫血模型,充血模型

所谓贫血模型,就是在软件设计中有很多POJO对象,他们除了get/set方法,基本没有任何业务逻辑。

vip会员的贫血模型的设计图

如vip会员的贫血模型的设计图所示,在领域模型中,有vip会员的领域对象,该对象除了有一堆属性之外,还有会员打折,会员福利,会员特权等方法。
如果将该领域模型按照贫血模型设计,就会设计一个vip会员的实体对象与service。
实体对象包含该对象的所有属性,以及这些属性包含的数据,然后将所有的方法都放入service中,再调用他们的时候,必须将领域对象作为参数进行传输。
这样的设计将领域对象中的方法,以及方法在执行过程中所需的数据,割裂到两个不同的对象中,打破了对象的封装性。

原文链接:https://www.jianshu.com/p/56a09d2c8bc7