实习随笔【实现Json格式化与latex渲染】

【写在前面】在实习中,遇到了如下需求:

        待格式化数据大概长这样,里面存在Json乱码以及由$$包裹的公式

        目标格式: 

 一、Json格式化

我们这里的任务主要分为两部分:

  1. 解析一个可能包含嵌套的 JSON 字符串
  2. 格式化 JSON 对象

因为我们不知道后端返回的数据嵌套了多少层,所以均采用递归的方式,具体代码如下:

1、解析一个可能包含嵌套的 JSON 字符串
      parseAndFormatNestedJson(jsonString) {
        const recursiveParse = jsonStr => {
          try {
            let parsedData = JSON.parse(jsonStr);
            
            if (typeof parsedData === 'string') {
              return recursiveParse(parsedData);
            }
            
            for (let key in parsedData) {
              if (typeof parsedData[key] === 'string') {
                try {
                  parsedData[key] = recursiveParse(parsedData[key]);
                } catch (e) {
                  // 保留原始字符串
                }
              }
            }
            return parsedData;
          } catch (e) {
            return jsonStr;
          }
        };
  
        const parsedResult = recursiveParse(jsonString);
        return this.formatJson(parsedResult).replace(/\$\$/g, '$').replace(/\\\\/g, '\\');
      },

        这个函数的目的是解析一个可能包含嵌套的 JSON 字符串,并调用 formatJson 函数来格式化解析后的对象。处理过程如下:

  • 递归解析 (recursiveParse): 这是一个内部函数,使用递归来处理嵌套的 JSON 字符串。

    • 使用 JSON.parse 尝试解析输入的字符串 jsonStr
    • 如果解析后的结果是字符串类型,表示可能是嵌套的 JSON 字符串,因此再次调用 recursiveParse 来解析这个字符串。
    • 如果结果是一个对象,遍历该对象的每个属性。如果属性值是字符串类型,尝试对这个字符串进行递归解析。
    • 如果在解析过程中遇到异常(比如非法的 JSON 格式),会捕获异常并返回原始字符串。
  • 格式化和替换: 解析完成后的 JSON 对象通过 formatJson 进行格式化。格式化完成后,使用字符串替换来处理特殊字符,如将 $$ 替换为 $(方便展示),将 \\\\ 替换为 \\(处理异常)

2、格式化 JSON 对象
      formatJson(obj, level = 0) {
        const spaces = '  '.repeat(level);
        if (typeof obj !== 'object' || obj === null) {
          return JSON.stringify(obj);
        }
        
        if (Array.isArray(obj)) {
          const items = obj.map(item => `\n${spaces}  ${this.formatJson(item, level + 1)}`);
          return `[${items.join(', ')}\n${spaces}]`;
        } else {
          const entries = Object.entries(obj).map(([key, value]) => 
            `\n${spaces}  "${key}": ${this.formatJson(value, level + 1)}`
          );
          return `{${entries.join(', ')}\n${spaces}}`;
        }
      }

这个函数用于格式化 JSON 对象,使其更易于阅读。它支持递归格式化对象和数组。

  • 基础情况: 如果输入不是对象(包括数组),或者为 null,直接使用 JSON.stringify 来转换为字符串。
  • 数组处理: 如果是数组,对每个元素递归调用 formatJson 并增加缩进,然后将结果拼接成完整的数组格式。
  • 对象处理: 如果是对象,对每个键值对递归调用 formatJson 并增加缩进,然后将结果拼接成完整的对象格式。

二、渲染latex公式

    这里涉及到 第三方库 Mathjax 的使用,Mathjax具有强大的功能,配置好latex的规则后,可以自动识别 $$ / $ 包裹的公式,并将公式优雅的呈现在页面上。

1、引入并配置

        我这里使用的 cdn 引入的方式,在vue项目的 index.html 中 <head> 下配置

<!-- 配置 MathJax -->
    <script>
      window.MathJax = {
        tex: {
          inlineMath: [['$', '$'], ['\\(', '\\)']],
          displayMath: [['$$', '$$'], ['\\[', '\\]']]
        },
        svg: {
          fontCache: 'global'
        }
      };
    </script>
    <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js" async></script>
2、组件中使用
<template>
    <div>
      <div id="json-container">{{ formattedJson }}</div>
      <!-- <div id="json-container">{{ this.parseAndFormatNestedJson(this.jsonString) }}</div> -->
    </div>
  </template>



 mounted() {
    this.$nextTick(() => {
    MathJax.typeset();
 });
3、配置样式

        配置到这里,你会发现页面上的公式正常渲染了,但是字符串的格式却乱了,所以需要加一些样式,代码如下:

#json-container {
        font-family: monospace;
        white-space: pre-wrap;
    }

        至此,整个Json格式化与渲染就完成了,希望对做同样需求的你,能够有所帮助,附上完整代码。

  • 配置文件 index.html
<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
    <!-- 配置 MathJax -->
    <script>
      window.MathJax = {
        tex: {
          inlineMath: [['$', '$'], ['\\(', '\\)']],
          displayMath: [['$$', '$$'], ['\\[', '\\]']]
        },
        svg: {
          fontCache: 'global'
        }
      };
    </script>
    <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js" async></script>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>
  • 组件文件 Mathjax.vue
<template>
    <div>
      <div id="json-container">{{ formattedJson }}</div>
      <!-- <div id="json-container">{{ this.parseAndFormatNestedJson(this.jsonString) }}</div> -->
    </div>
  </template>
  
  <script>
  
  export default {
    name: 'JsonFormatter',
    data() {
      return {
        jsonString: "{\"msg\":\"ok\",\"code\":20000,\"data\":{\"result\":[{\"probs\":0.99942553043365479,\"texts\":\"如图,菱形ABCD的边长为4,且A\",\"char_info\":[{\"pos\":[{\"x\":0,\"y\":33},{\"x\":22,\"y\":33},{\"x\":22,\"y\":60},{\"x\":0,\"y\":60}],\"char\":\"如\",\"type\":1},{\"pos\":[{\"x\":22,\"y\":33},{\"x\":43,\"y\":33},{\"x\":43,\"y\":60},{\"x\":22,\"y\":60}],\"char\":\"图\",\"type\":1},{\"pos\":[{\"x\":43,\"y\":33},{\"x\":68,\"y\":33},{\"x\":68,\"y\":60},{\"x\":43,\"y\":60}],\"char\":\",\",\"type\":1},{\"pos\":[{\"x\":68,\"y\":33},{\"x\":95,\"y\":33},{\"x\":95,\"y\":60},{\"x\":68,\"y\":60}],\"char\":\"菱\",\"type\":1},{\"pos\":[{\"x\":95,\"y\":33},{\"x\":118,\"y\":33},{\"x\":118,\"y\":60},{\"x\":95,\"y\":60}],\"char\":\"形\",\"type\":1},{\"pos\":[{\"x\":118,\"y\":33},{\"x\":140,\"y\":33},{\"x\":140,\"y\":60},{\"x\":118,\"y\":60}],\"char\":\"A\",\"type\":1},{\"pos\":[{\"x\":140,\"y\":33},{\"x\":157,\"y\":33},{\"x\":157,\"y\":60},{\"x\":140,\"y\":60}],\"char\":\"B\",\"type\":1},{\"pos\":[{\"x\":157,\"y\":33},{\"x\":174,\"y\":33},{\"x\":174,\"y\":60},{\"x\":157,\"y\":60}],\"char\":\"C\",\"type\":1},{\"pos\":[{\"x\":174,\"y\":33},{\"x\":194,\"y\":33},{\"x\":194,\"y\":60},{\"x\":174,\"y\":60}],\"char\":\"D\",\"type\":1},{\"pos\":[{\"x\":194,\"y\":33},{\"x\":216,\"y\":33},{\"x\":216,\"y\":60},{\"x\":194,\"y\":60}],\"char\":\"的\",\"type\":1},{\"pos\":[{\"x\":216,\"y\":33},{\"x\":240,\"y\":33},{\"x\":240,\"y\":60},{\"x\":216,\"y\":60}],\"char\":\"边\",\"type\":1},{\"pos\":[{\"x\":240,\"y\":33},{\"x\":263,\"y\":33},{\"x\":263,\"y\":60},{\"x\":240,\"y\":60}],\"char\":\"长\",\"type\":1},{\"pos\":[{\"x\":263,\"y\":33},{\"x\":285,\"y\":33},{\"x\":285,\"y\":60},{\"x\":263,\"y\":60}],\"char\":\"为\",\"type\":1},{\"pos\":[{\"x\":285,\"y\":33},{\"x\":301,\"y\":33},{\"x\":301,\"y\":60},{\"x\":285,\"y\":60}],\"char\":\"4\",\"type\":1},{\"pos\":[{\"x\":301,\"y\":33},{\"x\":321,\"y\":33},{\"x\":321,\"y\":60},{\"x\":301,\"y\":60}],\"char\":\",\",\"type\":1},{\"pos\":[{\"x\":321,\"y\":33},{\"x\":348,\"y\":33},{\"x\":348,\"y\":60},{\"x\":321,\"y\":60}],\"char\":\"且\",\"type\":1},{\"pos\":[{\"x\":348,\"y\":33},{\"x\":375,\"y\":33},{\"x\":375,\"y\":60},{\"x\":348,\"y\":60}],\"char\":\"A\",\"type\":1}],\"variance\":0.0010391805553808808,\"poses\":[{\"x\":0,\"y\":33},{\"x\":375,\"y\":33},{\"x\":375,\"y\":60},{\"x\":0,\"y\":60}]},{\"probs\":0.98136389255523682,\"texts\":\"$$  E \\\\bot B C $$于E,$$  A F \\\\bot C D $$于F,$$  \\\\angle B = 6 $$\",\"char_info\":[{\"pos\":[{\"x\":73,\"y\":69},{\"x\":96,\"y\":69},{\"x\":96,\"y\":96},{\"x\":73,\"y\":96}],\"char\":\"于\",\"type\":1},{\"pos\":[{\"x\":96,\"y\":69},{\"x\":115,\"y\":69},{\"x\":115,\"y\":96},{\"x\":96,\"y\":96}],\"char\":\"E\",\"type\":1},{\"pos\":[{\"x\":115,\"y\":69},{\"x\":125,\"y\":69},{\"x\":125,\"y\":96},{\"x\":115,\"y\":96}],\"char\":\",\",\"type\":1},{\"pos\":[{\"x\":231,\"y\":70},{\"x\":252,\"y\":70},{\"x\":252,\"y\":96},{\"x\":231,\"y\":96}],\"char\":\"于\",\"type\":1},{\"pos\":[{\"x\":252,\"y\":70},{\"x\":269,\"y\":70},{\"x\":269,\"y\":96},{\"x\":252,\"y\":96}],\"char\":\"F\",\"type\":1},{\"pos\":[{\"x\":269,\"y\":70},{\"x\":279,\"y\":70},{\"x\":279,\"y\":96},{\"x\":269,\"y\":96}],\"char\":\",\",\"type\":1}],\"variance\":0.048195969313383102,\"poses\":[{\"x\":0,\"y\":70},{\"x\":373,\"y\":69},{\"x\":373,\"y\":94},{\"x\":0,\"y\":94}]},{\"probs\":0.99968928098678589,\"texts\":\"$$  0 ^ { \\\\circ } $$,则菱形ABCD的面积\",\"char_info\":[{\"pos\":[{\"x\":0,\"y\":104},{\"x\":41,\"y\":104},{\"x\":41,\"y\":133},{\"x\":0,\"y\":133}],\"char\":\",\",\"type\":1},{\"pos\":[{\"x\":41,\"y\":104},{\"x\":69,\"y\":104},{\"x\":69,\"y\":133},{\"x\":41,\"y\":133}],\"char\":\"则\",\"type\":1},{\"pos\":[{\"x\":69,\"y\":104},{\"x\":93,\"y\":104},{\"x\":93,\"y\":133},{\"x\":69,\"y\":133}],\"char\":\"菱\",\"type\":1},{\"pos\":[{\"x\":93,\"y\":104},{\"x\":117,\"y\":104},{\"x\":117,\"y\":133},{\"x\":93,\"y\":133}],\"char\":\"形\",\"type\":1},{\"pos\":[{\"x\":117,\"y\":104},{\"x\":139,\"y\":104},{\"x\":139,\"y\":133},{\"x\":117,\"y\":133}],\"char\":\"A\",\"type\":1},{\"pos\":[{\"x\":139,\"y\":104},{\"x\":157,\"y\":104},{\"x\":157,\"y\":133},{\"x\":139,\"y\":133}],\"char\":\"B\",\"type\":1},{\"pos\":[{\"x\":157,\"y\":104},{\"x\":173,\"y\":104},{\"x\":173,\"y\":133},{\"x\":157,\"y\":133}],\"char\":\"C\",\"type\":1},{\"pos\":[{\"x\":173,\"y\":104},{\"x\":192,\"y\":104},{\"x\":192,\"y\":133},{\"x\":173,\"y\":133}],\"char\":\"D\",\"type\":1},{\"pos\":[{\"x\":192,\"y\":104},{\"x\":215,\"y\":104},{\"x\":215,\"y\":133},{\"x\":192,\"y\":133}],\"char\":\"的\",\"type\":1},{\"pos\":[{\"x\":215,\"y\":104},{\"x\":239,\"y\":104},{\"x\":239,\"y\":133},{\"x\":215,\"y\":133}],\"char\":\"面\",\"type\":1},{\"pos\":[{\"x\":239,\"y\":104},{\"x\":269,\"y\":104},{\"x\":269,\"y\":133},{\"x\":239,\"y\":133}],\"char\":\"积\",\"type\":1}],\"variance\":0.00050142116378992796,\"poses\":[{\"x\":0,\"y\":104},{\"x\":269,\"y\":104},{\"x\":269,\"y\":133},{\"x\":0,\"y\":133}]},{\"probs\":0.92363280057907104,\"texts\":\"为___.\",\"char_info\":[{\"pos\":[{\"x\":0,\"y\":141},{\"x\":25,\"y\":141},{\"x\":25,\"y\":171},{\"x\":0,\"y\":171}],\"char\":\"为\",\"type\":1},{\"pos\":[{\"x\":25,\"y\":141},{\"x\":41,\"y\":141},{\"x\":41,\"y\":171},{\"x\":25,\"y\":171}],\"char\":\"_\",\"type\":1},{\"pos\":[{\"x\":41,\"y\":141},{\"x\":47,\"y\":141},{\"x\":47,\"y\":171},{\"x\":41,\"y\":171}],\"char\":\"_\",\"type\":1},{\"pos\":[{\"x\":47,\"y\":141},{\"x\":87,\"y\":141},{\"x\":87,\"y\":171},{\"x\":47,\"y\":171}],\"char\":\"_\",\"type\":1},{\"pos\":[{\"x\":87,\"y\":141},{\"x\":132,\"y\":141},{\"x\":132,\"y\":171},{\"x\":87,\"y\":171}],\"char\":\".\",\"type\":1}],\"variance\":0.15443108975887299,\"poses\":[{\"x\":0,\"y\":141},{\"x\":132,\"y\":141},{\"x\":132,\"y\":171},{\"x\":0,\"y\":171}]},{\"probs\":0.998046875,\"texts\":\"A\",\"char_info\":[{\"pos\":[{\"x\":64,\"y\":171},{\"x\":87,\"y\":171},{\"x\":87,\"y\":186},{\"x\":64,\"y\":186}],\"char\":\"A\",\"type\":1}],\"variance\":0,\"poses\":[{\"x\":64,\"y\":171},{\"x\":87,\"y\":171},{\"x\":87,\"y\":186},{\"x\":64,\"y\":186}]},{\"probs\":0.99951171875,\"texts\":\"B D\",\"char_info\":[{\"pos\":[{\"x\":0,\"y\":216},{\"x\":11,\"y\":216},{\"x\":11,\"y\":232},{\"x\":0,\"y\":232}],\"char\":\"B\",\"type\":1},{\"pos\":[{\"x\":12,\"y\":216},{\"x\":143,\"y\":216},{\"x\":143,\"y\":232},{\"x\":12,\"y\":232}],\"char\":\" \",\"type\":1},{\"pos\":[{\"x\":144,\"y\":216},{\"x\":159,\"y\":216},{\"x\":159,\"y\":232},{\"x\":144,\"y\":232}],\"char\":\"D\",\"type\":1}],\"variance\":0,\"poses\":[{\"x\":0,\"y\":216},{\"x\":159,\"y\":216},{\"x\":159,\"y\":232},{\"x\":0,\"y\":232}]},{\"probs\":1,\"texts\":\"E F\",\"char_info\":[{\"pos\":[{\"x\":32,\"y\":243},{\"x\":45,\"y\":243},{\"x\":45,\"y\":259},{\"x\":32,\"y\":259}],\"char\":\"E\",\"type\":1},{\"pos\":[{\"x\":46,\"y\":243},{\"x\":107,\"y\":243},{\"x\":107,\"y\":259},{\"x\":46,\"y\":259}],\"char\":\" \",\"type\":1},{\"pos\":[{\"x\":108,\"y\":243},{\"x\":122,\"y\":243},{\"x\":122,\"y\":259},{\"x\":108,\"y\":259}],\"char\":\"F\",\"type\":1}],\"variance\":0,\"poses\":[{\"x\":32,\"y\":243},{\"x\":122,\"y\":243},{\"x\":122,\"y\":259},{\"x\":32,\"y\":259}]},{\"probs\":0.99853515625,\"texts\":\"C\",\"char_info\":[{\"pos\":[{\"x\":69,\"y\":261},{\"x\":94,\"y\":261},{\"x\":94,\"y\":277},{\"x\":69,\"y\":277}],\"char\":\"C\",\"type\":1}],\"variance\":0,\"poses\":[{\"x\":69,\"y\":261},{\"x\":94,\"y\":261},{\"x\":94,\"y\":277},{\"x\":69,\"y\":277}]}],\"rotate\":0,\"images\":[{\"poses\":[{\"x\":0,\"y\":168},{\"x\":167,\"y\":168},{\"x\":167,\"y\":279},{\"x\":0,\"y\":279}]}],\"single_box\":{\"print_text\":[{\"texts\":\"如图,菱形ABCD的边长为4,且A\",\"Confidence\":0.99942553043365479,\"stdofconfi\":0.0010391805553808808,\"poses\":[{\"x\":0,\"y\":33},{\"x\":375,\"y\":33},{\"x\":375,\"y\":60},{\"x\":0,\"y\":60}]},{\"texts\":\"$$  0 ^ { \\\\circ } $$,则菱形ABCD的面积\",\"Confidence\":0.99968928098678589,\"stdofconfi\":0.00050142116378992796,\"poses\":[{\"x\":0,\"y\":104},{\"x\":269,\"y\":104},{\"x\":269,\"y\":133},{\"x\":0,\"y\":133}]},{\"texts\":\"为___.\",\"Confidence\":0.92363280057907104,\"stdofconfi\":0.15443108975887299,\"poses\":[{\"x\":0,\"y\":141},{\"x\":132,\"y\":141},{\"x\":132,\"y\":171},{\"x\":0,\"y\":171}]},{\"texts\":\"D\",\"Confidence\":1,\"stdofconfi\":0,\"poses\":[{\"x\":144,\"y\":216},{\"x\":159,\"y\":216},{\"x\":159,\"y\":232},{\"x\":144,\"y\":232}]},{\"texts\":\"B\",\"Confidence\":0.99951171875,\"stdofconfi\":0,\"poses\":[{\"x\":0,\"y\":216},{\"x\":11,\"y\":216},{\"x\":11,\"y\":232},{\"x\":0,\"y\":232}]},{\"texts\":\"于E,\",\"Confidence\":0.99951171875,\"stdofconfi\":0.00048828125,\"poses\":[{\"x\":73,\"y\":69},{\"x\":125,\"y\":69},{\"x\":125,\"y\":96},{\"x\":73,\"y\":96}]},{\"texts\":\"于F,\",\"Confidence\":0.96321612596511841,\"stdofconfi\":0.047707688063383102,\"poses\":[{\"x\":231,\"y\":70},{\"x\":279,\"y\":70},{\"x\":279,\"y\":96},{\"x\":231,\"y\":96}]},{\"texts\":\"F\",\"Confidence\":0.99951171875,\"stdofconfi\":0,\"poses\":[{\"x\":108,\"y\":243},{\"x\":122,\"y\":243},{\"x\":122,\"y\":259},{\"x\":108,\"y\":259}]},{\"texts\":\"E\",\"Confidence\":1,\"stdofconfi\":0,\"poses\":[{\"x\":32,\"y\":243},{\"x\":45,\"y\":243},{\"x\":45,\"y\":259},{\"x\":32,\"y\":259}]},{\"texts\":\"A\",\"Confidence\":0.998046875,\"stdofconfi\":0,\"poses\":[{\"x\":64,\"y\":171},{\"x\":87,\"y\":171},{\"x\":87,\"y\":186},{\"x\":64,\"y\":186}]},{\"texts\":\"C\",\"Confidence\":0.99853515625,\"stdofconfi\":0,\"poses\":[{\"x\":69,\"y\":261},{\"x\":94,\"y\":261},{\"x\":94,\"y\":277},{\"x\":69,\"y\":277}]}],\"print_formula\":[{\"texts\":\"$$  E \\\\bot B C $$\",\"Confidence\":0.99000000953674316,\"stdofconfi\":0,\"poses\":[{\"x\":0,\"y\":70},{\"x\":74,\"y\":70},{\"x\":74,\"y\":94},{\"x\":0,\"y\":94}]},{\"texts\":\"$$  A F \\\\bot C D $$\",\"Confidence\":0.99000000953674316,\"stdofconfi\":0,\"poses\":[{\"x\":138,\"y\":70},{\"x\":233,\"y\":70},{\"x\":233,\"y\":93},{\"x\":138,\"y\":94}]},{\"texts\":\"$$  \\\\angle B = 6 $$\",\"Confidence\":0.99000000953674316,\"stdofconfi\":0,\"poses\":[{\"x\":293,\"y\":70},{\"x\":373,\"y\":69},{\"x\":373,\"y\":94},{\"x\":293,\"y\":94}]},{\"texts\":\"$$  0 ^ { \\\\circ } $$\",\"Confidence\":0.99000000953674316,\"stdofconfi\":0,\"poses\":[{\"x\":0,\"y\":107},{\"x\":21,\"y\":107},{\"x\":21,\"y\":128},{\"x\":0,\"y\":128}]}]}}}"
      };
    },
    computed: {
      formattedJson() {
        return this.parseAndFormatNestedJson(this.jsonString);
      }
    },
    methods: {
      parseAndFormatNestedJson(jsonString) {
        const recursiveParse = jsonStr => {
          try {
            let parsedData = JSON.parse(jsonStr);
            
            if (typeof parsedData === 'string') {
              return recursiveParse(parsedData);
            }
            
            for (let key in parsedData) {
              if (typeof parsedData[key] === 'string') {
                try {
                  parsedData[key] = recursiveParse(parsedData[key]);
                } catch (e) {
                  // 保留原始字符串
                }
              }
            }
            return parsedData;
          } catch (e) {
            return jsonStr;
          }
        };
  
        const parsedResult = recursiveParse(jsonString);
        return this.formatJson(parsedResult).replace(/\$\$/g, '$').replace(/\\\\/g, '\\');
      },
      formatJson(obj, level = 0) {
        const spaces = '  '.repeat(level);
        if (typeof obj !== 'object' || obj === null) {
          return JSON.stringify(obj);
        }
        
        if (Array.isArray(obj)) {
          const items = obj.map(item => `\n${spaces}  ${this.formatJson(item, level + 1)}`);
          return `[${items.join(', ')}\n${spaces}]`;
        } else {
          const entries = Object.entries(obj).map(([key, value]) => 
            `\n${spaces}  "${key}": ${this.formatJson(value, level + 1)}`
          );
          return `{${entries.join(', ')}\n${spaces}}`;
        }
      }
    },
    mounted() {
      this.$nextTick(() => {
        MathJax.typeset();
      });
    }
  };
  </script>
  
  <style scoped>
    #json-container {
        font-family: monospace;
        white-space: pre-wrap;
    }
  </style>
  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/802310.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SAP ABAP性能优化分析工具

SAP系统提供了许多性能调优的工具&#xff0c;重点介绍下最常用几种SM50, ST05, SAT等工具&#xff1a; 1.工具概况 1.1 SM50 / SM66 - 工作进程监视器 通过这两个T-code, 可以查看当前SAP AS实例上面的工作进程&#xff0c;当某一工作进程长时间处于running的状态时&#…

支持前端路由权限和后端接口权限的企业管理系统模版

一、技术栈 前端&#xff1a;iview-admin vue 后端&#xff1a;springboot shiro 二、基于角色的权限控制 1、路由权限 即不同角色的路由访问控制 2、菜单权限 即不同角色的菜单列表展示 3、按钮权限 即不同角色的按钮展示 4、接口权限 即不同角色的接口访问控制 三…

C++——类和对象(下)

文章目录 一、再探构造函数——初始化列表二、 类型转换三、static成员静态成员变量静态成员函数 四、 友元友元函数友元类 五、内部类六、匿名对象 一、再探构造函数——初始化列表 之前我们实现构造函数时&#xff0c;初始化成员变量主要使⽤函数体内赋值&#xff0c;构造函…

16_网络IPC2-寻址

进程标识 字节序 采用大小模式对数据进行存放的主要区别在于在存放的字节顺序&#xff0c;大端方式将高位存放在低地址&#xff0c;小端方式将高位存放在高地址。 采用大端方式进行数据存放符合人类的正常思维&#xff0c;而采用小端方式进行数据存放利于计算机处理。到目前…

QT使用QPainter绘制多边形维度图

多边形统计维度图是一种用于展示多个维度的数据的图表。它通过将各个维度表示为图表中的多边形的边&#xff0c;根据数据的大小和比例来确定各个维度的长度。 一、简述 本示例实现六边形战力统计维度图&#xff0c;一种将六个维度的战力统计以六边形图形展示的方法。六个维度是…

WebAssembly与JavaScript的交互(1)

前一阵子利用Balazor开发了一个NuGet站点&#xff0c;对WebAssembly进行了初步的了解&#xff0c;觉得挺有意思。在接下来的一系列文章中&#xff0c;我们将通过实例演示的方式介绍WebAssembly的一些基本概念和编程模式。首先我们先来说说什么是WebAssembly&#xff0c;它主要帮…

微调 Florence-2 - 微软的尖端视觉语言模型

Florence-2 是微软于 2024 年 6 月发布的一个基础视觉语言模型。该模型极具吸引力&#xff0c;因为它尺寸很小 (0.2B 及 0.7B) 且在各种计算机视觉和视觉语言任务上表现出色。 Florence 开箱即用支持多种类型的任务&#xff0c;包括: 看图说话、目标检测、OCR 等等。虽然覆盖面…

LRC软件、Adobe Lightroom Classic软件多版本下载+LRC教程

简介&#xff1a; Adobe Lightroom Classic&#xff08;简称LR&#xff09;是Adobe Creative Cloud大家庭中的一款专业的图片管理和编辑工具&#xff0c;用于专业摄影师、摄影爱好者以及所有不断优化数码影像的人等。其目标是以丰富的功能提供高效、一致的体验&#xff0c;帮助…

php基础: 三角形

包含&#xff1a;左三角、左上三角、右三角、右上三角、等腰三角、倒等腰三角。注意空格的数量&#xff0c;因为*号后面加了空格 /*** * 左三角形* param $n* return void*/ function triangleLeft($n){echo <pre>;for ($i 1; $i < $n; $i) {for ($j 1; $j < $i…

对服务器进行基本了解(二)

目录 一. 云服务器数据库 1.查看MYSQL版本 2.查看mysql的运行状态 3.运行mysql 4. 进入mysql的用户 5. 更改用户密码 6. 查找mysql端口号 7. 创建一个数据库 8. 查看用户 9. 查看数据库 10. 显示数据库的表 11. 修改用户的host 12. 对用户赋权 13. 开放指定端…

java.lang.IllegalArgumentException: Illegal character in path at index 40解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

数据库内核研发学习之路(三)创建postgres内置函数

本章之前已经讲明白了我们的postgres如何进行编译安装&#xff0c;这是很重要的一步&#xff0c;接下来就是学会对postgres进行小的改动&#xff0c;然后保证依然能够顺利编译安装运行&#xff01; 本章续讲内容如何创建一个内置函数。 1、内置函数和用户自定义函数的区别 熟…

基于Python+Flask+SQLite的豆瓣电影可视化系统

FlaskMySQLEcharts 基于PythonFlaskSQLite的豆瓣电影可视化系统 Echarts 不支持登录注册&#xff0c;并且信息存储在数据库中 不含爬虫代码&#xff0c;或爬虫代码已失效 简介 基于PythonFlaskMySQL的豆瓣电影可视化系统&#xff0c;采用Echart构建图表&#xff0c;支持自定…

【数据结构】二叉树全攻略,从实现到应用详解

​ &#x1f48e;所属专栏&#xff1a;数据结构与算法学习 &#x1f48e; 欢迎大家互三&#xff1a;2的n次方_ ​ &#x1f341;1. 树形结构的介绍 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做…

动手学深度学习6.3 填充和步幅-笔记练习(PyTorch)

以下内容为结合李沐老师的课程和教材补充的学习笔记&#xff0c;以及对课后练习的一些思考&#xff0c;自留回顾&#xff0c;也供同学之人交流参考。 本节课程地址&#xff1a;填充和步幅_哔哩哔哩_bilibili 代码实现_哔哩哔哩_bilibili 本节教材地址&#xff1a;6.3. 填充和…

旗晟巡检机器人的应用场景有哪些?

巡检机器人作为现代科技的杰出成果&#xff0c;已广泛应用于各个关键场景。从危险的工业现场到至关重要的基础设施&#xff0c;它们的身影无处不在。它们以精准、高效、不知疲倦的特性&#xff0c;担当起保障生产、守护安全的重任&#xff0c;为行业发展注入新的活力。那么&…

【学习笔记】无人机系统(UAS)的连接、识别和跟踪(一)-3GPP TS 23.256 技术规范概述

3GPP TS 23.256 技术规范&#xff0c;主要定义了3GPP系统对无人机&#xff08;UAV&#xff09;的连接性、身份识别、跟踪及A2X&#xff08;Aircraft-to-Everything&#xff09;服务的支持。 3GPP TS 23.256 技术规范&#xff1a; 以下是文档的核心内容总结&#xff1a; UAV系…

深入理解PostgreSql域类型(Domain),灵活定义数据约束,让表结构设计更加严谨

在PostgreSQL中&#xff0c;域&#xff08;Domain&#xff09;是一种用户定义的数据类型&#xff0c;它基于系统内已存在的数据类型&#xff0c;并可以附加约束条件。使用域可以增强数据的完整性和一致性&#xff0c;因为它允许开发者对特定列设定更为具体的规则&#xff0c;比…

Mysql缓存调优的基本知识(附Demo)

目录 前言1. 配置2. 缓存3. 策略 前言 基本的知识推荐阅读&#xff1a; java框架 零基础从入门到精通的学习路线 附开源项目面经等&#xff08;超全&#xff09;Mysql优化高级篇&#xff08;全&#xff09;Mysql底层原理详细剖析常见面试题&#xff08;全&#xff09; MySQL…

集群架构-web服务器(接入负载均衡+数据库+会话保持redis)--15454核心配置详解

紧接着前面的集群架构深化—中小型公司&#xff08;拓展到大型公司业务&#xff09;–下面图简单回顾一下之前做的及故障核心知识总结&#xff08;等后期完全整理后&#xff0c;上传资源希望能帮大家&#xff09; web集群架构-接入负载均衡部署web02服务器等 web集群-搭建web0…