<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
            <title type="text">Owen老师</title>
            <subtitle type="text">一直专注 “数据、技术、架构、产品” 领域 <br/> 邮箱：513253817@163.com</subtitle>
    <updated>2025-12-29T17:58:58+08:00</updated>
        <id>https://blog.shareworld.vip</id>
        <link rel="alternate" type="text/html" href="https://blog.shareworld.vip" />
        <link rel="self" type="application/atom+xml" href="https://blog.shareworld.vip/atom.xml" />
    <rights>Copyright © 2026, Owen老师</rights>
    <generator uri="https://halo.run/" version="1.5.4">Halo</generator>
            <entry>
                <title><![CDATA[深入浅出 React Context：从入门到源码，彻底搞懂 `useContext`]]></title>
                <link rel="alternate" type="text/html" href="https://blog.shareworld.vip/archives/react-context-1" />
                <id>tag:https://blog.shareworld.vip,2025-12-29:react-context-1</id>
                <published>2025-12-29T17:32:57+08:00</published>
                <updated>2025-12-29T17:58:58+08:00</updated>
                <author>
                    <name>Owen Jia</name>
                    <uri>https://blog.shareworld.vip</uri>
                </author>
                <content type="html">
                        <![CDATA[<p>今天我将带你从最基础的用法开始，一步步深入，最后潜入 React 源码的海洋，彻底把 Context 看个通透。准备好了吗？发车！</p><h2 id="%E4%B8%80%E3%80%81%E4%B8%BA%E4%BB%80%E4%B9%88%E9%9C%80%E8%A6%81-context%EF%BC%9F-props-%E7%9A%84%E2%80%9C%E5%88%87%E8%82%A4%E4%B9%8B%E7%97%9B%E2%80%9D" tabindex="-1">一、为什么需要 Context？ props 的“切肤之痛”</h2><p>在 React 的世界里，数据是自顶向下，通过 props 单向流动的。这就像一条清晰的河流，父组件将数据缓缓“流”向子组件。对于层级不深的组件结构，这种方式清晰、可控，非常优雅。<br />但想象一下，如果你的组件树长成这样：</p><pre><code class="language-XML">&lt;App&gt;  &lt;Header&gt;    &lt;Navbar&gt;      &lt;UserAvatar&gt;        &lt;UserInfo /&gt;      &lt;/UserAvatar&gt;    &lt;/Navbar&gt;  &lt;/Header&gt;  &lt;MainContent&gt;    &lt;Article&gt;      &lt;AuthorInfo /&gt;    &lt;/Article&gt;  &lt;/MainContent&gt;&lt;/App&gt;</code></pre><p>现在，App 组件里有一个 theme（主题）状态，UserInfo 和 AuthorInfo 这两个组件都需要根据这个 theme 来改变自己的样式。按照传统的 props 传递方式，我们需要这样做：</p><p>App 组件把 theme 传给 Header 和 MainContent。<br />Header 再把 theme 传给 Navbar。<br />Navbar 再传给 UserAvatar。<br />UserAvatar 再传给 UserInfo。<br />MainContent 把 theme 传给 Article。<br />Article 再传给 AuthorInfo。</p><p>我的天！Header、Navbar、UserAvatar、MainContent、Article 这些中间组件，它们自己可能根本不需要 theme 这个状态，但为了把它传递给真正需要的后代组件，它们被迫当起了“快递员”。这种现象，我们称之为 “props drilling”（属性钻探） 。<br />“属性钻探”会带来几个非常蛋疼的问题：</p><p>代码冗余和维护困难：大量的中间组件都需要写重复的 props 定义和传递逻辑，如果将来需要修改 prop 的名字或者类型，你需要修改整条链路上的所有组件，简直是噩梦。<br />组件耦合度增高：中间组件被迫与它们本不关心的 prop 耦合，降低了组件的复用性和独立性。<br />可读性差：当你想追踪一个 prop 的来源时，需要在组件树中上上下下地反复横跳，非常影响开发效率。</p><p>为了解决这种“切肤之痛”，React 官方为我们提供了一把利器——Context。<br />Context 提供了一种在组件之间共享此类值的方式，而不必显式地通过组件树的逐层传递 props。 简单来说，它开辟了一个“全局”空间，任何在这个空间内的组件，无论层级多深，都可以直接访问到共享的数据，从而彻底告别了“属性钻探”。</p><h2 id="%E4%BA%8C%E3%80%81%E4%B8%8A%E6%89%8B%E5%AE%9E%E6%88%98%EF%BC%9A%E4%B8%89%E6%AD%A5%E7%8E%A9%E8%BD%AC-usecontext" tabindex="-1">二、上手实战：三步玩转 useContext</h2><p>从用户提供的示例代码中，我们可以清晰地看到使用 Context 的标准流程。我们以此为基础，来构建一个简单的主题切换功能。</p><h3 id="%E7%AC%AC-1-%E6%AD%A5%EF%BC%9A%E5%88%9B%E5%BB%BA-context-%E5%AF%B9%E8%B1%A1" tabindex="-1">第 1 步：创建 Context 对象</h3><p>首先，我们需要使用 React.createContext API 来创建一个 Context 对象。这个对象就像一个信息的“容器”，之后的数据共享都将围绕它展开。</p><pre><code class="language-js">import { createContext } from &quot;react&quot;;​// createContext() 接受一个默认值作为参数// 只有当组件在组件树中找不到对应的 Provider 时，这个默认值才会生效export const ThemeContext = createContext(&quot;light&quot;);</code></pre><p>这里我们创建了一个名为 ThemeContext 的上下文，并给它提供了一个默认值 ‘light’。这个默认值非常重要，它是一个备胎，只有在万不得已（即找不到 Provider）的时候才会上场。</p><h3 id="%E7%AC%AC-2-%E6%AD%A5%EF%BC%9A%E4%BD%BF%E7%94%A8-provider-%E6%8F%90%E4%BE%9B%E6%95%B0%E6%8D%AE" tabindex="-1">第 2 步：使用 Provider 提供数据</h3><p>创建好 Context 对象后，我们需要使用它的 Provider 组件来“包裹”那些需要访问共享数据的组件。Provider 接收一个 value 属性，这个 value 就是我们要共享给后代组件的数据。</p><pre><code class="language-">import { useState } from &#39;react&#39;;import Page from &#39;./components/Page&#39;; // 假设 Page 组件存在import { ThemeContext } from &#39;./ThemeContext&#39;;​function App() {  const [theme, setTheme] = useState(&#39;dark&#39;);​  return (    // 使用 ThemeContext.Provider 包裹子组件    // 并通过 value 属性将当前的 theme 状态传递下去    &lt;ThemeContext.Provider value={theme}&gt;      &lt;Page /&gt;      &lt;button onClick={() =&gt; setTheme(theme === &#39;dark&#39; ? &#39;light&#39; : &#39;dark&#39;)}&gt;        切换主题      &lt;/button&gt;    &lt;/ThemeContext.Provider&gt;  );}​export default App;</code></pre><p>在 App.jsx 中，我们用 ThemeContext.Provider 包裹了 Page 组件和一个按钮。Provider 的 value 属性被设置为 App 组件自身的 theme 状态。这意味着，Page 组件以及它内部的任何子组件，现在都可以访问到这个 theme 值了。<br />敲黑板！ Provider 的 value 属性值的变化是触发 Context 更新的关键。每当 value 的值发生变化时（React 使用 <a href="http://Object.is" target="_blank">Object.is</a> 算法来比较），所有消费了这个 Context 的后代组件都会重新渲染。</p><h3 id="%E7%AC%AC-3-%E6%AD%A5%EF%BC%9A%E4%BD%BF%E7%94%A8-usecontext-%E6%B6%88%E8%B4%B9%E6%95%B0%E6%8D%AE" tabindex="-1">第 3 步：使用 useContext 消费数据</h3><p>万事俱备，只欠东风。现在，我们可以在任何被 Provider 包裹的后代组件中，使用 useContext Hook 来轻松获取共享的数据。<br />假设 Page 组件内部有一个 Content 组件：</p><pre><code class="language-javascript">// components/Content.jsximport { useContext } from &#39;react&#39;;import { ThemeContext } from &#39;../../ThemeContext&#39;;​function Content() {  // 直接调用 useContext，传入对应的 Context 对象  const theme = useContext(ThemeContext);​  // 根据获取到的 theme 值来设置样式  const style = {    color: theme === &#39;dark&#39; ? &#39;#fff&#39; : &#39;#000&#39;,    backgroundColor: theme === &#39;dark&#39; ? &#39;#000&#39; : &#39;#fff&#39;,    padding: &#39;20px&#39;,    border: &#39;1px solid #ccc&#39;  };​  return (    &lt;div style={style}&gt;      &lt;p&gt;当前主题是: {theme}&lt;/p&gt;      &lt;p&gt;这是一段根据主题变换颜色的内容。&lt;/p&gt;    &lt;/div&gt;  );}​export default Content;</code></pre><p>看，就这么简单！只需要一行 const theme = useContext(ThemeContext);，我们就跨越了千山万水，直接在 Content 组件中拿到了 App 组件提供的 theme 状态。没有了 props 的层层传递，代码瞬间清爽了许多。<br />为了让代码更优雅，我们还可以创建一个自定义 Hook，将 useContext 的逻辑封装起来，这也是示例代码 useTheme.js 所做的事情，是社区的最佳实践之一：</p><pre><code class="language-javascript">// useTheme.jsimport { useContext } from &#39;react&#39;;import { ThemeContext } from &#39;../ThemeContext&#39;;​// 将 useContext 的逻辑封装成一个自定义 Hookexport function useTheme() {    return useContext(ThemeContext);}这样，在 Content 组件中，我们就可以这样使用：javascript 体验AI代码助手 代码解读复制代码// components/Content.jsx (使用自定义 Hook)import { useTheme } from &#39;../../useTheme&#39;;​function Content() {  const theme = useTheme(); // 使用自定义 Hook，更加简洁明了  // ...}</code></pre><p>至此，我们已经完整地走了一遍 useContext 的使用流程。总结一下就是：创建（createContext）-&gt; 提供（Provider）-&gt; 消费（useContext） 。是不是很简单？<br />但是，作为一个有追求的开发者，我们不能止步于此。接下来，让我们一起潜入水下，看看 React 内部到底是如何实现这套神奇的机制的。</p><h2 id="%E4%B8%89%E3%80%81%E6%B7%B1%E5%85%A5%E5%BA%95%E5%B1%82%EF%BC%9Acontext-%E7%9A%84%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86%E4%B8%8E%E5%AE%9E%E7%8E%B0%E6%9C%BA%E5%88%B6" tabindex="-1">三、深入底层：Context 的工作原理与实现机制</h2><p>要理解 Context 的底层原理，我们需要从 React 的协调（Reconciliation）过程和 Fiber 架构说起。当 Provider 的 value 发生变化时，React 是如何通知到所有消费它的组件并触发它们重新渲染的呢？</p><h3 id="1.-context-%E7%9A%84%E2%80%9C%E8%AE%A2%E9%98%85-%E5%8F%91%E5%B8%83%E2%80%9D%E6%A8%A1%E5%BC%8F" tabindex="-1">1. Context 的“订阅-发布”模式</h3><p>Context 的核心机制可以理解为一种“订阅-发布”模式。每个 Context 对象内部都维护着一个订阅者列表。当一个组件通过 useContext Hook 消费某个 Context 时，它实际上就成为了这个 Context 的一个“订阅者”。<br />当 Context.Provider 的 value 属性发生变化时，Provider 会“发布”一个更新通知。React 会遍历所有订阅了这个 Context 的组件，并将它们标记为需要重新渲染。在下一次协调阶段，这些被标记的组件就会重新执行它们的渲染逻辑。</p><h3 id="2.-fiber-%E6%9E%B6%E6%9E%84%E4%B8%8E-context-%E7%9A%84%E4%BC%A0%E6%92%AD" tabindex="-1">2. Fiber 架构与 Context 的传播</h3><p>React 16 引入了 Fiber 架构，这是一个对核心算法的重写，旨在提高渲染性能和用户体验。在 Fiber 架构中，每个 React 元素都对应一个 Fiber 节点。组件树的更新过程就是 Fiber 树的构建和遍历过程。<br />Context 的值是如何在 Fiber 树中向下传递的呢？<br />当 React 渲染 Context.Provider 组件时，它会将 Provider 的 value 值存储在一个内部的“上下文栈”（Context Stack）中。这个栈是 Fiber 节点的一部分，并且在遍历 Fiber 树时会不断地更新。</p><p>向下传递：当 React 从 Provider 节点向下遍历到其子节点时，Provider 的 value 会被推入上下文栈。这样，所有位于 Provider 下方的子组件，在它们渲染时，都可以从这个栈中获取到最新的 Context 值。<br />向上查找：当一个组件（例如，通过 useContext）需要获取 Context 值时，React 会沿着其 Fiber 节点的父链向上查找，直到找到最近的 Context.Provider。一旦找到，它就会从该 Provider 对应的上下文栈中取出 value 值。</p><p>这个上下文栈的机制确保了 Context 值能够高效地在组件树中传递，并且每个组件都能获取到离它最近的 Provider 所提供的值。</p><h3 id="3.-usecontext-%E7%9A%84%E5%86%85%E9%83%A8%E5%AE%9E%E7%8E%B0" tabindex="-1">3. useContext 的内部实现</h3><p>useContext Hook 的内部实现相对复杂，但我们可以简化理解。当你在函数组件中调用 useContext(MyContext) 时，React 会做以下几件事：</p><p>查找最近的 Provider：React 会沿着当前组件的 Fiber 节点向上遍历，寻找最近的 MyContext.Provider 节点。<br />获取 Context 值：一旦找到 Provider，React 就会从该 Provider 内部维护的上下文栈中取出当前的 value 值。<br />注册订阅：同时，React 会将当前组件（更准确地说是其 Fiber 节点）注册为该 Context 的订阅者。这意味着，当 Provider 的 value 发生变化时，React 会知道需要重新渲染这个组件。</p><h3 id="4.object.is-%E6%AF%94%E8%BE%83%E4%B8%8E%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96" tabindex="-1"><a href="http://4.Object.is" target="_blank">4.Object.is</a> 比较与性能优化</h3><p>在前面我们提到，Provider 的 value 属性值的变化是触发 Context 更新的关键。React 在判断 value 是否发生变化时，使用的是 <a href="http://Object.is" target="_blank">Object.is</a> 算法进行比较。<br /><a href="http://Object.is" target="_blank">Object.is</a> 是一种比 === 更严格的相等性判断：</p><p><a href="http://Object.is" target="_blank">Object.is</a>(NaN, NaN) 返回 true，而 NaN === NaN 返回 false。<br /><a href="http://Object.is" target="_blank">Object.is</a>(0, -0) 返回 false，而 0 === -0 返回 true。<br />对于其他情况，<a href="http://Object.is" target="_blank">Object.is</a> 的行为与 === 相同。</p><p>这意味着，如果你在 Provider 的 value 中传递了一个对象或数组，即使其内部属性发生了变化，但如果对象引用没有改变，Context 也不会触发更新。例如：</p><pre><code class="language-javascript">// 错误示例：对象引用未变，不会触发更新function App() {  const [state, setState] = useState({ theme: &#39;dark&#39;, user: &#39;Manus&#39; });​  const handleClick = () =&gt; {    state.theme = state.theme === &#39;dark&#39; ? &#39;light&#39; : &#39;dark&#39;; // 直接修改对象属性    setState(state); // 引用未变  };​  return (    &lt;MyContext.Provider value={state}&gt;      {/* ... */}    &lt;/MyContext.Provider&gt;  );}​// 正确示例：创建新对象，触发更新function App() {  const [state, setState] = useState({ theme: &#39;dark&#39;, user: &#39;Manus&#39; });​  const handleClick = () =&gt; {    setState(prevState =&gt; ({      ...prevState,      theme: prevState.theme === &#39;dark&#39; ? &#39;light&#39; : &#39;dark&#39;,    })); // 创建新对象  };​  return (    &lt;MyContext.Provider value={state}&gt;      {/* ... */}    &lt;/MyContext.Provider&gt;  );}</code></pre><p>因此，在使用 Context 时，尤其是在 value 中传递复杂数据结构时，务必注意 value 的引用变化。通常，结合 useState 或 useReducer 来管理 Context 的 value，并确保在数据更新时返回新的引用，是最佳实践。</p><h3 id="5.-context-%E7%9A%84%E5%B1%80%E9%99%90%E6%80%A7%E4%B8%8E%E6%80%A7%E8%83%BD%E8%80%83%E9%87%8F" tabindex="-1">5. Context 的局限性与性能考量</h3><p>尽管 Context 解决了 props drilling 的问题，但它并非银弹。在使用 Context 时，我们需要注意以下几点：</p><ul><li><p>过度使用可能导致性能问题：当 Provider 的 value 发生变化时，所有消费该 Context 的组件都会重新渲染，即使它们只使用了 value 中的一小部分数据。如果 Context 承载的数据量很大，或者更新非常频繁，这可能会导致不必要的渲染，从而影响应用性能。<br />解决方案：</p></li><li><p>拆分 Context：将一个大的 Context 拆分成多个小的 Context，每个 Context 只负责一部分相关的数据。这样，当某个数据更新时，只有消费了对应 Context 的组件才会重新渲染。<br />使用 memo 或 useMemo：对于不经常变化的组件，可以使用 React.memo 进行包裹，或者使用 useMemo 缓存 Context 的 value，避免不必要的重新计算。</p></li><li><p>难以追踪数据流：虽然 Context 避免了 props drilling，但它也使得数据流变得不那么显式。当一个组件消费了 Context 时，你无法直接从组件的 props 中看出它依赖了哪些外部数据。这在大型应用中可能会增加调试的难度。</p></li><li><p>不适合频繁更新的数据：Context 的更新机制决定了它不适合承载那些需要极高更新频率的数据（例如，动画帧数据）。对于这类数据，更推荐使用状态管理库（如 Redux、Zustand 等）或者更底层的事件订阅机制。</p></li></ul><p>总而言之,Context 是一个强大的工具，但它更适合传递那些不经常变化、且在组件树中广泛使用的“全局”数据，例如主题、用户信息、国际化语言等。对于复杂的状态管理和频繁的数据更新，专业的全局状态管理库可能更合适。</p><p>在 React 生态中，除了 Context，还有许多其他的状态管理方案，例如 Redux、Zustand、Jotai 等。它们各有优劣，适用于不同的场景。</p><p><img src="https://oscimg.oschina.net/oscnet/up-ce6b569e4a3df01ed6f465576aeb35fb647.png" alt="" /></p><h2 id="%E6%80%BB%E7%BB%93" tabindex="-1">总结</h2><p>如果你只是想解决简单的 props drilling 问题，或者管理一些不频繁更新的全局数据，Context 是一个轻量且高效的选择。<br />如果你的应用状态复杂，需要进行大量的异步操作，或者需要强大的调试能力和可预测的状态变更，那么 Redux 或其他专业的全局状态管理库可能更适合你。</p><p>值得一提的是，很多现代的状态管理库（如 Zustand、Jotai）在底层也利用了 Context 的能力，但它们在其之上构建了更高级的抽象和优化，提供了更好的开发体验和性能。</p><h2 id="%E4%BA%94%E3%80%81%E6%80%BB%E7%BB%93%E4%B8%8E%E5%B1%95%E6%9C%9B" tabindex="-1">五、总结与展望</h2><p>通过今天的深入探讨，相信你对 React Context 已经有了更全面、更底层的理解。我们从 props drilling 的痛点出发，学习了 Context 的基本用法，然后深入剖析了其在 React Fiber 架构下的工作原理，包括“订阅-发布”模式、上下文栈的传递机制以及 <a href="http://Object.is" target="_blank">Object.is</a> 比较对性能的影响。最后，我们还简要对比了 Context 与其他状态管理方案的异同。</p><p>Context 是 React 提供的一个强大而灵活的工具，它极大地简化了组件间的数据共享。但正如所有工具一样，它也有自己的适用场景和局限性。合理地使用 Context，结合 memo、useMemo 等性能优化手段，能够让你的 React 应用更加健壮和高效。</p>]]>
                </content>
            </entry>
            <entry>
                <title><![CDATA[使用cursor工具尝试一个人开发一个项目]]></title>
                <link rel="alternate" type="text/html" href="https://blog.shareworld.vip/archives/aicoding1" />
                <id>tag:https://blog.shareworld.vip,2025-11-10:aicoding1</id>
                <published>2025-11-10T15:32:37+08:00</published>
                <updated>2025-11-10T15:37:26+08:00</updated>
                <author>
                    <name>Owen Jia</name>
                    <uri>https://blog.shareworld.vip</uri>
                </author>
                <content type="html">
                        <![CDATA[<p>一个突破性尝试，使用AI编程工具Cursor进行全项目代码编写，开发一个“电子书平台”，从0-1过程，涵盖了UI设计、前端React开发、后端Java开发。</p><p>在整个研发周期里，由我完成的部分包括“产品设计、工程脚手架搭建、约10%优化代码、打包部署”，而项目的“9成半”代码是AI自己生成，包括建表sql。可怕的是这个项目在仅仅7天内开发完成并上线。</p><p>像cursor这类工具真的太强大了，对于每一个工程师来说都必须尽快掌握，这就是一个你不卷就被卷子的时代。</p><p><img src="https://blog.shareworld.vip/upload/2025/11/%E6%88%AA%E5%B1%8F2025-11-08%2014.05.53.png" alt="截屏2025-11-08 14.05.53" /></p><p>哪怕是项目规模在小，按过去软件开发思路，也是需要3个角色分工进行的“产品兼设计、前端工程师、后端工程师”，3个人很难省掉。产品与设计分开，再算上运维，需要5个人，而如今的事实情况是1个人就可以完成。</p><p>仅仅7天上线一套系统，包含25个接口、10个页面、7张表，真的就这么快速实现了。从一个想法开始进行产品设计、系统设计、前端开发、后端开发、上线部署，这一切工作在AI工具加持下是那么简单粗暴，并且不给你一点狡辩机会，不接受反驳。</p><p>这次使用AI编程中很明显可以看出来，AI编程可以完成至少80%的工作，为何说是80%呢，因为剩下的20%是“客户需求和技术需求”的不完善的，在真实交付给客户情况下，客户需求与技术需求是有复杂度的，而我这个项目在这个点上要求相对低。所以先定80%。</p><p>在纯代码生成上，AI有非常明显优势，要超越几乎所有工程师。在设计上AI还不能完全精准实现需求或者说很便捷的让AI理解需求，但随着AI不断的成长，未来是可以完全实现。</p><p>时代真的变了！软件开发已不再像过去那般了，这个行业会很快迎来大考，大量失业是必然的，相信没几年时间了。</p><p>作者：<a href="https://blog.shareworld.vip" target="_blank">owen老师</a></p>]]>
                </content>
            </entry>
            <entry>
                <title><![CDATA[第一个APP开发经历]]></title>
                <link rel="alternate" type="text/html" href="https://blog.shareworld.vip/archives/第一个app开发经历" />
                <id>tag:https://blog.shareworld.vip,2025-09-18:第一个app开发经历</id>
                <published>2025-09-18T14:34:38+08:00</published>
                <updated>2025-09-18T14:36:29+08:00</updated>
                <author>
                    <name>Owen Jia</name>
                    <uri>https://blog.shareworld.vip</uri>
                </author>
                <content type="html">
                        <![CDATA[<p>今天 <strong>APP开发</strong> 终于是0-1的突破。</p><blockquote><p>关于App开发一直以来都是我的痛，多少年了…</p></blockquote><p>不断的摸索路上，尝试了3种方案：uni-app｜react native｜expo</p><h3 id="%E6%96%B9%E6%A1%88%E4%B8%80%EF%BC%9Areact-native" tabindex="-1">方案一：react native</h3><p>采用react-native进行开发，很多年前一次搭建react-native环境失败经历（搞了好几天，一直无法成功）。在今天其实也未全部成功，但是好在以<code>npx @react-native-community/cli init test1</code>方式把环境和项目都搭建好，并能跑起来。功劳是react-native自身，0.81版本比我多年前简单多了。</p><p><img src="https://blog.shareworld.vip/upload/2025/09/14bf1ed9-43cd-44e1-bb0c-4b6135715f96.png" alt="14bf1ed9-43cd-44e1-bb0c-4b6135715f96" /></p><p>舍弃了ios环境适配，目前android环境ok。</p><h3 id="%E6%96%B9%E6%A1%88%E4%BA%8C%EF%BC%9Auni-app" tabindex="-1">方案二：uni-app</h3><p>不得点个赞，采用uni-app进行app开发，搭建环境上真的是简单，下载xbuilder工具（一条龙全部搞定），这真是让人意外。从创建项目到运行，到手机上（usb）真机测试，到打包apk文件（手机安装）。关键是人家还有一堆模版可以采用，一堆ui库可以使用。坦率说，假如我不会前端react，我肯定选uni-app进行，毕竟vue我也会。</p><p><img src="https://blog.shareworld.vip/upload/2025/09/be123698-4806-48f6-91b4-07fc96c26c87.png" alt="be123698-4806-48f6-91b4-07fc96c26c87" /></p><h3 id="%E6%96%B9%E6%A1%88%E4%B8%89%EF%BC%9Aexpo" tabindex="-1">方案三：expo</h3><p>花了1小时研究了官方文档，按文档一步步，搭建环境，创建项目，运行项目，真机测试。哇哦，厉害。expo-cli加expo go组合使用，真的简单高效，关键是工程结构（react、ts）让人熟悉啊。</p><p><img src="https://blog.shareworld.vip/upload/2025/09/1ef977aa-99f4-48b8-adbc-af3a67de4c77.png" alt="1ef977aa-99f4-48b8-adbc-af3a67de4c77" /></p><h2 id="%E6%80%BB%E7%BB%93%E8%BF%99%E4%B8%89%E7%A7%8D" tabindex="-1">总结这三种</h2><p>expo和uni-app两个都是封装很好的成套框架工具，对‘新手’特别友好。<br />react-native有点复杂，需要结合android studio工具、xcode工具进行组合使用。搞过的人，你肯定懂其中痛苦。新人想全部跑通，要不少精力去研究学习。</p><p>比较下来，我选择expo开发app。这里不是uni-app不好，而是我更习惯用react进行开发。其实对国内友好的还是uni-app，expo go工具你还得通过google play进行安装，至少要会‘爬梯子’。</p><p>后面会找机会用uni-app进行app开发，再比较看看，最终回到react native上。为何这样呢？主要是uni-app和expo的原生扩张不行，特别集成一些三方时会很难受，而react-native完全没有限制。</p>]]>
                </content>
            </entry>
            <entry>
                <title><![CDATA[android_studio_初学]]></title>
                <link rel="alternate" type="text/html" href="https://blog.shareworld.vip/archives/androidstudio01" />
                <id>tag:https://blog.shareworld.vip,2023-08-13:androidstudio01</id>
                <published>2023-08-13T16:50:08+08:00</published>
                <updated>2023-08-13T16:50:08+08:00</updated>
                <author>
                    <name>Owen Jia</name>
                    <uri>https://blog.shareworld.vip</uri>
                </author>
                <content type="html">
                        <![CDATA[<p>Android Studio新建项目以及目录结构介绍</p><div id="content_views" class="markdown_views prism-atom-one-dark"><svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path></svg><p></p><div class="toc"><h3>目录结构</h3><ul><li>一、新建项目</li><li>二、目录结构</li><li><ul><li>2.1 .gradle和.idea</li><li>2.2 app</li><li><ul><li>2.2.1 libs</li><li>2.2.2 src</li><li>2.2.3 其他文件</li></ul></li><li>2.3 gradle</li></ul></li></ul></div><p></p> <h2><a id="_1"></a>一、新建项目</h2> <p>1、打开android studio，新建项目，选择模板，点击next<br> <img src="https://img-blog.csdnimg.cn/20210417155208109.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMTc4MTA5,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述" referrerpolicy="no-referrer"><br> 2、填写项目名称，选择项目路径和开发语言，点击finish<br> <img src="https://img-blog.csdnimg.cn/20210417155346576.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMTc4MTA5,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述" referrerpolicy="no-referrer"></p> <h2><a id="_7"></a>二、目录结构</h2> <p>文件目录如下：<br> <img src="https://img-blog.csdnimg.cn/20210417155455666.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMTc4MTA5,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述" referrerpolicy="no-referrer"></p> <h2><a id="21_gradleidea_10"></a>2.1 .gradle和.idea</h2> <p>这两个放置的是android studio自动生成的文件，无需关心，无需手动编辑。</p> <h2><a id="22_app_12"></a>2.2 app</h2> <p>项目中的代码、资源都在这个目录下。<br> app中目录如下：<br> <img src="https://img-blog.csdnimg.cn/20210417155758843.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMTc4MTA5,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述" referrerpolicy="no-referrer"></p> <h3><a id="221_libs_16"></a>2.2.1 libs</h3> <p>存放第三方的jar包</p> <h3><a id="222_src_18"></a>2.2.2 src</h3> <p>1、androidtest<br> 主要编写android test测试用例，可以对项目进行自动化测试。<br> 2、main<br> java中放置所有的java代码或kotlin代码<br> res中存放项目中使用到的所有图片、布局、字符等资源。<br> drawable存放图片，layout存放布局，values存放字符串。<br> AndroidManifest.xml是整个Android项目的配置文件。<br> 3、test<br> 用来编写Unit Test测试用例</p> <h3><a id="223__28"></a>2.2.3 其他文件</h3> <p>1、.gitigore<br> 用于将app模块内指定的目录或文件排除在版本控制之外。<br> 2、build.gradle<br> app模块的gradle构建脚本</p> <h2><a id="23_gradle_33"></a>2.3 gradle</h2> <p>包含gradle wrapper的配置文件</p></div><hr /><p>学习之路永无止境</p><p>直接收录了网上内容<a href="https://www.ngui.cc/el/3376858.html?action=onClick" target="_blank">www.ngui.cc</a>整理的不错</p>]]>
                </content>
            </entry>
            <entry>
                <title><![CDATA[初试websphere工具]]></title>
                <link rel="alternate" type="text/html" href="https://blog.shareworld.vip/archives/chu-shi-websphere-gong-ju" />
                <id>tag:https://blog.shareworld.vip,2023-08-01:chu-shi-websphere-gong-ju</id>
                <published>2023-08-01T21:55:30+08:00</published>
                <updated>2023-08-01T21:55:30+08:00</updated>
                <author>
                    <name>Owen Jia</name>
                    <uri>https://blog.shareworld.vip</uri>
                </author>
                <content type="html">
                        <![CDATA[<h1 id="websphere" tabindex="-1">websphere</h1><h1 id="web%E5%BA%94%E7%94%A8%E6%9C%8D%E5%8A%A1%E5%99%A8" tabindex="-1">WEB应用服务器</h1><p>软件开发领域两大架构，分别是B/S与C/S。</p><p>B/S模式下软件工程师，对web应用服务器没有不了解的，经过20年发展，web应用服务器也大不相同了。如早期websphere\weblogic\tomcat等等，现如今springboot天下，内置web应用服务器成为主流，也契合微服务发展趋势，tomcat\jetty内置到应用系统内部，成为一个组件包方式部署；</p><p>websphere\weblogic 属于商用领域里佼佼者，大型应用服务器；tomcat属于开源领域里，非常优先，使用范围也最广的。我进入软件领域10多年了，入门也是从了解tomcat开始的，后续逐步使用springboot的tomcat内核\jetty内核。</p><h1 id="%E4%BD%BF%E7%94%A8websphere" tabindex="-1">使用websphere</h1><p>最近搞一个非常古老的项目，采用jsp/osgi/struct那套框架开发的，eclipse年代，对我来说已经10几年前东西了，现今的工程师怕都不知道是啥。我也是有关短暂的eclipse rcp开发经历，才接触一些osgi知识。</p><p><img src="https://blog.shareworld.vip/upload/2023/08/websphere.png" alt="" /></p><p><img src="https://blog.shareworld.vip/upload/2023/08/websphere1.png" alt="" /></p><p>但，对于应用服务器来说，websphere整体设计和功能完善性真的非常棒，比tomcat全太多太多了。我认为，不论技术如何演进发展，软件设计是一样的思路和架构，围绕场景的解决方案也是不变的。简单来说，问题还是那个问题，换一种技术你还得解决。</p><p>未来不论是tomcat的继续，还是完全内置方式，应用服务器所面临的问题都还在，也许都会进入应用系统内部，成为其一部分（目前已看到这样趋势）；也或者，完全抛弃，交给独立三方解决，而应用服务越来越小、越来越精简。</p><h2 id="%E9%A1%B9%E7%9B%AEvs%E4%BA%A7%E5%93%81" tabindex="-1">项目vs产品</h2><p>做产品，一套架构很多年，架构演进迭代也是渐进式；<br />做项目，一个客户一套架构，预算不变架构永远不改；</p><p><em>谁更好呢？</em></p>]]>
                </content>
            </entry>
            <entry>
                <title><![CDATA[安全漏洞扫描1]]></title>
                <link rel="alternate" type="text/html" href="https://blog.shareworld.vip/archives/iast01" />
                <id>tag:https://blog.shareworld.vip,2023-08-01:iast01</id>
                <published>2023-08-01T21:31:30+08:00</published>
                <updated>2023-08-01T21:31:30+08:00</updated>
                <author>
                    <name>Owen Jia</name>
                    <uri>https://blog.shareworld.vip</uri>
                </author>
                <content type="html">
                        <![CDATA[<h1 id="%E5%BA%94%E7%94%A8%E5%AE%89%E5%85%A8%E6%B5%8B%E8%AF%95" tabindex="-1">应用安全测试</h1><p>应用开发绝大多数人都是正向逻辑，能够把反向场景想到并修复调的极少，特别是国内几乎未曾见过，不知是国内外文化不同，还是国内竞争压力太大；</p><p>2B市场，软件系统的交付往往伴随‘安全性’自证，关于这个‘自证’本身非常值得吐槽，特别是金融市场的客户，几乎都是网络封闭环境，TMD的漏洞检测。</p><p>漏洞扫描市场是非常大，其本身也非常专业，有较高门槛（对于大多数软件开发人员来说）；这个门槛，也说明了在安全领域了这么多家企业的存在是有价值的，还有好几家都上市了。</p><h2 id="%E5%BA%94%E7%94%A8%E6%BC%8F%E6%B4%9E%E6%A3%80%E6%B5%8B" tabindex="-1">应用漏洞检测</h2><p>这次的漏洞主要围绕应用软件系统，不包括服务器、数据库之类。</p><p>借着本次机会，盘点了漏洞扫描市场现状。首先，从0开始自己扫描这条路非安全领域内人员请不要尝试；其次，采用开源的检测工具，围绕怎么用好它展开，又或者采购服务商检测软件或者能力；最后，在开源基础上二次开发（加入特性），非大平台不建议。</p><h2 id="ast%E6%9C%89%E5%93%AA%E4%BA%9B" tabindex="-1">AST有哪些</h2><p>漏洞扫描AST，分为SAST、DAST、IAST几种，“静态、动态、集成”应用程序安全测试；</p><p><img src="https://blog.shareworld.vip/upload/2023/08/%E6%BC%8F%E6%B4%9E%E6%89%AB%E6%8F%8F.png" alt="漏洞扫描" /></p><h3 id="%E5%BC%80%E6%BA%90%E5%87%A0%E6%AC%BE" tabindex="-1">开源几款</h3><ul><li>openrasp-iast</li></ul><p>百度开源的，主动检测类型，就是安装好后他会主动发起检测。</p><p><a href="https://rasp.baidu.com/" target="_blank">https://rasp.baidu.com/</a></p><ul><li>洞态iast</li></ul><p>北京火线安全提供，属于被动类型，需要主动点击功能，通过javaagent模式检测。</p><p><a href="https://www.dongtai.io/" target="_blank">https://www.dongtai.io/</a></p><p><ins><em>留给未来反思总结</em></ins></p>]]>
                </content>
            </entry>
            <entry>
                <title><![CDATA[部署weblogic]]></title>
                <link rel="alternate" type="text/html" href="https://blog.shareworld.vip/archives/部署weblogic" />
                <id>tag:https://blog.shareworld.vip,2023-07-31:部署weblogic</id>
                <published>2023-07-31T15:40:59+08:00</published>
                <updated>2023-08-09T13:50:52+08:00</updated>
                <author>
                    <name>Owen Jia</name>
                    <uri>https://blog.shareworld.vip</uri>
                </author>
                <content type="html">
                        <![CDATA[<h1 id="weblogic" tabindex="-1">weblogic</h1><p><img src="https://blog.shareworld.vip/upload/2023/08/weblogic.png" alt="weblogic" /></p><p>本次安装版本：fmw_12.1.3.0.0_wls.jar<br />java：jdk1.7.0_80</p><p>weblogic安装和websphere类似，都是较为复杂，和开源绿色软件不同风格，本质是一个大型软件系统。</p><h2 id="window10" tabindex="-1">window10</h2><p>管理启动cmd命令，这一步是关键；之后运行java -jar fmw_12.1.3.0.0_wls.jar会弹出安装操作界面，按步骤往下即可，采用默认配置。</p><h2 id="centos7" tabindex="-1">centos7</h2><p><img src="https://blog.shareworld.vip/upload/2023/08/weblogic-start.png" alt="weblogic-start" /></p><p>linux安装比较复杂，没有弹框界面，必须采用’静默‘方式运行：-silent</p><p>/usr/java/jdk1.7.0_80/bin/java -jar /opt/weblogic/fmw_12.1.3.0.0_wls.jar -silent -responseFile /opt/weblogic/wls.rsp -invPtrLoc /opt/weblogic/oraInst.loc</p><h3 id="%E5%AE%89%E8%A3%85" tabindex="-1">安装</h3><p>确认jdk安装完成，建议1.7（不超过1.8）；</p><h4 id="%E5%88%9B%E5%BB%BA%E7%94%A8%E6%88%B7%E8%AE%BE%E7%BD%AE%E7%9B%B8%E5%85%B3%E6%96%87%E4%BB%B6%E5%A4%B9" tabindex="-1">创建用户设置相关文件夹</h4><p>WebLogic 无法在 root 用户下安装，所以先来创建一个用户，然后给刚刚新建的用户 weblogic 设置密码</p><pre><code class="language-">useradd weblogicpasswd weblogic</code></pre><p>在 /opt 目录下新建 weblogic 文件夹，</p><pre><code class="language-">mkdir /opt/weblogic</code></pre><p>把weblogic安装包fmw_14.1.1.0.0_wls_lite_generic.jar上传到服务器，</p><p>然后移动到 /opt/weblogic 目录下，</p><pre><code class="language-">mv fmw_14.1.1.0.0_wls_lite_generic.jar /opt/weblogic/</code></pre><p>设置 weblogic 文件夹所有者为 weblogic，</p><pre><code class="language-">chown -R weblogic:weblogic /opt/weblogic</code></pre><p>切换到  /opt/weblogic  目录，输入命令：cd /opt/weblogic<br />新增两个文件<br />vim oraInst.loc</p><pre><code class="language-">Inventory_loc=/opt/weblogic/oraInventoryInst_group=weblogic</code></pre><p>vim  wls.rsp</p><pre><code class="language-">[ENGINE]Response File Version=1.0.0.0.0[GENERIC]ORACLE_HOME=/opt/weblogic/oracle/middlewareINSTALL_TYPE=WebLogic ServerDECLINE_SECURITY_UPDATES=trueSECURITY_UPDATES_VIA_MYORACLESUPPORT=false</code></pre><h4 id="%E9%9D%99%E9%BB%98%E5%AE%89%E8%A3%85" tabindex="-1">静默安装</h4><p>切换 weblogic 用户，</p><pre><code class="language-">su weblogic</code></pre><p>#安装命令</p><pre><code class="language-">/usr/java/jdk1.7.0_80/bin/java -jar /opt/weblogic/fmw_12.1.3.0.0_wls.jar -silent -responseFile /opt/weblogic/wls.rsp -invPtrLoc /opt/weblogic/oraInst.loc</code></pre><h4 id="%E5%88%9B%E5%BB%BA%E5%9F%9F" tabindex="-1">创建域</h4><p>切换回 root 用户<br />切换目录<br />cd /opt/weblogic/oracle/middleware/wlserver/common/bin/</p><p>执行wlst.sh文件，开始创建域，<br />./wlst.sh</p><p>依次下列命令：</p><pre><code class="language-">readTemplate(&#39;/opt/weblogic/oracle/middleware/wlserver/common/templates/wls/wls.jar&#39;)cd(&#39;Servers/AdminServer&#39;)set(&#39;ListenAddress&#39;,&#39;&#39;)set(&#39;ListenPort&#39;, 7001)cd(&#39;/&#39;)cd(&#39;Security/base_domain/User/weblogic&#39;)cmo.setPassword(&#39;weblogic1234&#39;)setOption(&#39;OverwriteDomain&#39;, &#39;true&#39;)writeDomain(&#39;/opt/weblogic/oracle/middleware/user_projects/domains&#39;)closeTemplate()exit()</code></pre><h4 id="%E5%90%AF%E5%8A%A8" tabindex="-1">启动</h4><p>cd /opt/weblogic/oracle/middleware/user_projects/domains/bin</p><p>使用后台启动模式，命令：nohup ./startWebLogic.sh &amp;</p><p>./stopWebLogic.sh</p><p>有防火墙的，记得开放下7001端口</p><p>访问weblogic，输入：<a href="http://192.168.224.11:7001/console" target="_blank">http://192.168.224.11:7001/console</a></p><p>输入登录用户和密码就可以了（weblogic/weblogic1234)</p><h2 id="%E5%8F%82%E8%80%83" tabindex="-1">参考</h2><p><a href="https://blog.csdn.net/qq_55494759/article/details/131324000" target="_blank">https://blog.csdn.net/qq_55494759/article/details/131324000</a></p><p><a href="https://blog.csdn.net/weixin_54093404/article/details/127897690" target="_blank">https://blog.csdn.net/weixin_54093404/article/details/127897690</a></p><p><a href="https://blog.csdn.net/wen459/article/details/126933062" target="_blank">https://blog.csdn.net/wen459/article/details/126933062</a></p>]]>
                </content>
            </entry>
            <entry>
                <title><![CDATA[数据中台建设思考]]></title>
                <link rel="alternate" type="text/html" href="https://blog.shareworld.vip/archives/数据中台建设思考" />
                <id>tag:https://blog.shareworld.vip,2023-07-26:数据中台建设思考</id>
                <published>2023-07-26T20:18:46+08:00</published>
                <updated>2023-07-26T14:34:18+08:00</updated>
                <author>
                    <name>Owen Jia</name>
                    <uri>https://blog.shareworld.vip</uri>
                </author>
                <content type="html">
                        <![CDATA[<h2 id="%E6%95%B0%E6%8D%AE%E4%B8%AD%E5%8F%B0" tabindex="-1">数据中台</h2><p>对其起源不是很清楚，推测与阿里有关系，他们首先提出的。近些年来看，阿里对这个领域推进不是很积极，加上又拆分，后续真不好说。</p><p>数据中台，这块业务方向是有价值的，不然也不会有很多人响应。我真正进入该领域是2022年，偶然机会加入了数据中台团队，早在2013年我有数据仓库在银行信贷领域的经验，也算是步入老本行。</p><h2 id="%E6%95%B0%E6%8D%AE%E4%BB%93%E5%BA%93" tabindex="-1">数据仓库</h2><p>在这近1年的时间里，发现（起码是我们目前的团队）大家对‘数据中台’的理解本质还是‘数据仓库’，加了WEB界面加以控制。数仓领域，数据模型和ETL是核心业务，中台里‘数仓’是其很重要的一部分，但不仅仅是数据仓库。</p><p>数据中台，还包括‘元数据管理、数据源、数据标准、数据建模、数据质量、调度、数据地图、数据服务、数据管控、数据血缘、多源比对’等业务。这其中，数据建模、数据服务、调度是数据主业务流程，数据质量、数据地图、数据血缘、多源比对更多是一个辅助业务流程，价值相对次之。</p><h2 id="%E6%95%B0%E6%8D%AE%E8%B4%A8%E9%87%8F" tabindex="-1">数据质量</h2><p>一年时间看着不短，其也不长，将将够把’数据质量‘玩透。调研了市面竞品不下20家，大版本迭代也近5轮，基本形成了较为标准的产品体系，经历多场景客户实际运行认可。客户的认可，对整个团队起到非常大的鼓舞。</p><p>数据质量的核心逻辑，是检查数据内容是否满足要求，将发行的问题反馈给对应人员修正，检查对象主要是’数据库‘。</p><p><img src="https://blog.shareworld.vip/upload/2023/07/16903520711250.png" alt="16903520711250" /></p><p>整体功能设计：</p><p><img src="https://blog.shareworld.vip/upload/2023/07/16903521439205.png" alt="16903521439205" /></p><h2 id="%E4%BA%A7%E5%93%81vs%E9%A1%B9%E7%9B%AE" tabindex="-1">产品VS项目</h2><p>写点项目与产品的感悟，过往多年一直在产品化的路线上奔跑，而如今在一个项目部的团队中，这里考核重心是“成本、资源、时间“，对于”标准化“是认可但融合遗忘。</p><p>简单点，选择加入产品团队，对个人来说也许是低成本的。但对于产品、项目的合作模式的探索来说，这只是逃避，问题还在那。也许有些公司不存在此类问题，路已经趟过，但我目前面临的是一个’产品化方向‘不明阶段，需要借助项目实施来积累摸索一条产品化之路。离不开，项目实施经验，或者说真实客户的需求场景。</p><p>遇到几个问题：</p><ul><li>需求功能的开发，随项目实施在不断发散，离标准化越来越远；</li><li>项目团队的人员一直围绕‘成本’考虑，更多是短期利益的‘短平快’；</li><li>产品化之路，本身早期高投入，成本随客户推广开，而指数下降；</li><li>人员观念不同，产品考虑问题思维和项目完全不同；</li><li>项目围绕客户要什么就给什么，完全一致才好交付；</li><li>产品会思考客户要的以什么样方式给此客户，同时其他客户也直接使用；</li></ul><p>数据中台本身也契合’数字化‘的大趋势。</p>]]>
                </content>
            </entry>
            <entry>
                <title><![CDATA[jenkins流水线配置用户密码的npm私服]]></title>
                <link rel="alternate" type="text/html" href="https://blog.shareworld.vip/archives/npm" />
                <id>tag:https://blog.shareworld.vip,2023-01-08:npm</id>
                <published>2023-01-08T19:32:31+08:00</published>
                <updated>2023-01-08T19:32:31+08:00</updated>
                <author>
                    <name>Owen Jia</name>
                    <uri>https://blog.shareworld.vip</uri>
                </author>
                <content type="html">
                        <![CDATA[<h3 id="%E9%9C%80%E6%B1%82" tabindex="-1">需求</h3><p>通过jenkins配置react工程流水线部署。</p><p>原本构建部署都很简单，npm install&amp;npm run build，dist搬迁到部署路径即可。</p><h3 id="%E5%9C%BA%E6%99%AF" tabindex="-1">场景</h3><p>相对于自己公司的npm registry，这种registry一般是开启账号/密码，必须要登录进行package依赖下载。在流水线里通过脚本执行命令，是无法人工输入账号密码的。本地手动可以command中断等待输入，流水线完全行不通。</p><h3 id="%E6%96%B9%E6%A1%88" tabindex="-1">方案</h3><p>解决方案就出在npm上，npm的命令拉取不同的registry是可以指定的，全局指定一个私服，或者某些前缀依赖拉取指定registry。</p><p>npm本身提供机制来解决下载包时的授权问题，文件：<code>.npmrc </code></p><p>npm读取.npmrc的优先级关系：</p><p>项目配置文件: /project/.npmrc<br />用户配置文件：~/.npmrc<br />全局配置文件：/etc/npmrc</p><p>对于.npmrc文件格式：</p><pre><code class="language-">registry=http://221.238.115.163:18080/verdaccio///http://221.238.115.163:18080/verdaccio/:_auth=LW4gJWluOjEyMzQ1NicgDQo=</code></pre><p>这里面的&quot;_auth&quot;是“admin:password&quot;格式，并且base64编码的结果。可以使用命令<code>echo &quot;admin:123&quot;|openssl base64</code> 。</p><p>另外，在_auth机制外还有_authToken方式可以解决。</p>]]>
                </content>
            </entry>
            <entry>
                <title><![CDATA[python学习总结]]></title>
                <link rel="alternate" type="text/html" href="https://blog.shareworld.vip/archives/pythonjava" />
                <id>tag:https://blog.shareworld.vip,2022-12-29:pythonjava</id>
                <published>2022-12-29T13:49:48+08:00</published>
                <updated>2022-12-29T13:49:48+08:00</updated>
                <author>
                    <name>Owen Jia</name>
                    <uri>https://blog.shareworld.vip</uri>
                </author>
                <content type="html">
                        <![CDATA[<p>Python一门非常优秀的开发语言，带你入门编程的世界。</p><p>学习python对于我来说不是为了进入编程，而是为了丰富我自己编程世界的边界，不想被一两门语言而限制自身发展，限制有趣的方向。Java是我立身语言，入行的敲门砖，已经10年多了，玩的很溜，一路成长为架构师。</p><p>语言其实已经掌握很多了，如：java、sql、javascript、go、perl、shell、react、vue、scala等。因为每个语言的诞生都是有自身的定位，它是为了某个场景某个领域而被创造出来，所以它天然尤其生命特性，也有其自身弊端。选择多学一门语言，能很好帮助工程师跨领域积累知识，开阔思路，也有打开职业机会。</p><p>Python和Java有着自身特性，现在回来对比。我认为，python替代java还为时尚早、还很早，但python有着java无法跨越的优势，解释型语言和编译型语言相比，在类似脚本类任务场景是十分突出的优势，另外python语法的不严谨也降低了入门难度，这样的降低让它非常迅速的积累了生态，甚至生态更甚，如科学计算相关函数库。python在科学计算领域的积累，奠定了其江湖地位，占领了庞大的市场。</p><p>特地在年底不太忙时间里，系统了学习python，包括“语法、系统库、框架、三方优秀库”，对工程搭建、运行、部署都做了充分实战练习。因为本身10多年编程积累，再去学一门新的语言确实是触类旁通的，短短2周拿下，还接了一个地图数据清洗的活，也算干成了项目。</p><p>早前也学过go，当时是一眼就喜欢上了，简洁的语法特性，让人着迷。另外go对系统api的支持，做java对jvm的了解，让我们对go汗颜。要是go出现早些，我肯定学go去了，可是后端及web领域，已经有个java了并且掌握很好，再学go有点多余，出发抛弃java全力转型，确实有很多互联网公司全员转go，考虑到当前情况，我只选择了掌握入门语法，帮助自己能看懂。另外go在硬件设备领域，有着c/c++无法超越的优势，这个领域必然选go。</p><p>python对我来说是补充，这些年一直在找一门语言弥补java在脚本领域-短、平、块的不足，让我很快速方便的做一些小事情，特别是文件、数据、网络之类。在b/s这块web开发，当是java天下，短时间无法取代，就是后起之秀迅猛，但这个市场java任然很好。我想未来，是年轻人的，为了避开软件开发高速发展的拉扯，我下沉到了数据领域-我的老本行。</p><p>我认为数据是软件的后市场，规模很大，竞争强度也不低。</p><p>python有几点对我十分有益：一个是，可快速搭建脚本处理问题，不要java这个工程那个框架的；另一个是，桌面程序封装，简单开发一个桌面交互，从而实现流转使用，比java-swing之类轻多了；最后一个，是python的庞大生态，github库大量python项目可借鉴，能看懂加使用和稍微修改，这就是能力的边界。</p><p>从此，我是java和pyhon并行。</p>]]>
                </content>
            </entry>
            <entry>
                <title><![CDATA[python进阶学习之django框架]]></title>
                <link rel="alternate" type="text/html" href="https://blog.shareworld.vip/archives/django1" />
                <id>tag:https://blog.shareworld.vip,2022-12-22:django1</id>
                <published>2022-12-22T18:50:15+08:00</published>
                <updated>2023-08-09T13:17:07+08:00</updated>
                <author>
                    <name>Owen Jia</name>
                    <uri>https://blog.shareworld.vip</uri>
                </author>
                <content type="html">
                        <![CDATA[<p>回归学习python的初衷，有三个目标，如下。</p><ul><li>作为常用的脚本开发语言，用来处理临时性的需求</li><li>作为桌面软件开发语言，用来开发小程序提供给用户使用</li><li>作为web系统的开发语言，调研主流web开发框架</li></ul><p>本篇就是第三个目标的调研结果分享，前两个以及完成。</p><p>python web开发框架django目前引用很广泛，也十分的成熟，首先对它的调研学习。把官网的Tutorial的用例全套学习下来，各种用例手动写并运行、分析。搞了不少天，收获非常大，对django开发web系统的project有了全局了解，包括路由、页面、静态资源、数据库、持久化、sql、接口等等。</p><p><img src="https://oscimg.oschina.net/oscnet/up-559b164a86531a4466af9848fc4b3ebcdae.png" alt="" /></p><p><img src="https://oscimg.oschina.net/oscnet/up-4d3cf29a0a3acd8f6f80ed5bcc8482616df.png" alt="" /></p><p><img src="https://oscimg.oschina.net/oscnet/up-45a8793d36e52035f0eb53b8736301f3051.png" alt="" /></p><p><img src="https://oscimg.oschina.net/oscnet/up-b60ff0872b5612682eae494961a993b9df2.png" alt="" /></p><p>对django框架的使用，总结来说分以下节点。</p><ul><li>页面通过模板方式实现，和freemarker\themeleaf\jsp很像，也包括php</li><li>框架很全，涵盖了web系统需要的各个方面，特别像路由等</li><li>UI在框架内已经模块化、组件化，可直接使用</li><li>和vue、react前端开发语言有很多区别</li></ul><p>感受下来，django和freemarker之类属于同一模式的，比这些框架要全面而强大。但是，非主要前端开发语言，有学习成本，适用性属于小众市场，大型web系统没见过用它的，并且真正用起来怕是会非常难受。</p><p>我的样例代码地址：<a href="https://github.com/owen-jia/empty-py-demo" target="_blank">https://github.com/owen-jia/empty-py-demo</a></p><p><img src="https://oscimg.oschina.net/oscnet/up-4da736ee2249fe4630488549df2460e0213.png" alt="" /></p>]]>
                </content>
            </entry>
            <entry>
                <title><![CDATA[python进阶之GUI开发和构建exe程序]]></title>
                <link rel="alternate" type="text/html" href="https://blog.shareworld.vip/archives/gui-tkinter" />
                <id>tag:https://blog.shareworld.vip,2022-12-21:gui-tkinter</id>
                <published>2022-12-21T22:51:43+08:00</published>
                <updated>2022-12-23T16:15:12+08:00</updated>
                <author>
                    <name>Owen Jia</name>
                    <uri>https://blog.shareworld.vip</uri>
                </author>
                <content type="html">
                        <![CDATA[<p>GUI必学</p><p>作为辅助脚本语言的python，我的定位是工程java语言的补充，所以对于做一些小工具的语言进行学习，自然离不开GUI库掌握。</p><p>python3自带官方库 tkinter 已经算是小场景下的全面工具集。</p><p><img src="https://blog.shareworld.vip/upload/2022/12/tkinter.png" alt="tkinter" /></p><p>引用源码tkinter.init介绍</p><blockquote><p>Tkinter provides classes which allow the display, positioning and<br />control of widgets. Toplevel widgets are Tk and Toplevel. Other<br />widgets are Frame, Label, Entry, Text, Canvas, Button, Radiobutton,<br />Checkbutton, Scale, Listbox, Scrollbar, OptionMenu, Spinbox<br />LabelFrame and PanedWindow.</p></blockquote><blockquote><p>Properties of the widgets are specified with keyword arguments.<br />Keyword arguments have the same name as the corresponding resource<br />under Tk.</p></blockquote><blockquote><p>Widgets are positioned with one of the geometry managers Place, Pack<br />or Grid. These managers can be called with methods place, pack, grid<br />available in every Widget.</p></blockquote><blockquote><p>Actions are bound to events by resources (e.g. keyword argument<br />command) or with the method bind.</p></blockquote><blockquote><p>Example (Hello, World):<br />import tkinter<br />from tkinter.constants import *<br />tk = <a href="http://tkinter.Tk" target="_blank">tkinter.Tk</a>()<br />frame = tkinter.Frame(tk, relief=RIDGE, borderwidth=2)<br />frame.pack(fill=BOTH,expand=1)<br />label = tkinter.Label(frame, text=“Hello, World”)<br />label.pack(fill=X, expand=1)<br />button = tkinter.Button(frame,text=“Exit”,command=tk.destroy)<br />button.pack(side=BOTTOM)<br />tk.mainloop()</p></blockquote><p>tkinter的简单已用，超级吸引到我了。随便写了个交互界面，发现就十几行代码，这简直让人不可思议。真的是时代进步了，新语言已经解决了过去各种棘手问题。在java世界里，GWT Swing 包也可以写GUI程序，但总受制于java特性，太重。</p><p>有一种很普遍场景，在window或者mac下做一些小程序，用来处理一些数据或者文件文件转换，或者内容格式化等等。用python的GUI界面，用户只需要简单界面配置，然后“启动”按钮一点，等待一会就能完成目标。这样的小工具，对于很多不懂技术的人来说，牛上天了。</p><p><img src="https://blog.shareworld.vip/upload/2022/12/tkinter_demo.png" alt="tkinter_demo" /></p><p>使用机制和Swing差不多，编程上看却简化太多，我只要一个py脚本即可完成小工具开发，真无论如何都是吸引人的。</p><p><strong>可执行程序exe</strong></p><p>python打包一个exe程序，居然也是如此便捷，让人乍舌。</p><p><code>pip install pyinstaller</code> 安装 pyinstaller工具即可。</p><p>进入工程文件所在目录，直接<code>pyinstaller src/app.py</code>就会在当前目录下生成一个dist文件夹，里面有个app目录，这app目录里就是完成可执行程序。复制window电脑，进入目录里，找到exe后缀程序，直接双击运行。</p><p><img src="https://blog.shareworld.vip/upload/2022/12/tkinter_demo_exe.png" alt="tkinter_demo_exe" /></p><p>小技巧：将.py文件后缀改成.pyw，这样启动的程序即可隐藏控制台。</p><p><code>Python学习，快如闪电</code></p>]]>
                </content>
            </entry>
            <entry>
                <title><![CDATA[python进阶打包部署docker]]></title>
                <link rel="alternate" type="text/html" href="https://blog.shareworld.vip/archives/packaging-deploy" />
                <id>tag:https://blog.shareworld.vip,2022-12-21:packaging-deploy</id>
                <published>2022-12-21T21:55:15+08:00</published>
                <updated>2022-12-23T14:58:41+08:00</updated>
                <author>
                    <name>Owen Jia</name>
                    <uri>https://blog.shareworld.vip</uri>
                </author>
                <content type="html">
                        <![CDATA[<h3 id="%E6%89%93%E5%8C%85" tabindex="-1">打包</h3><p>目前了解下来python是没有打包构建可执行文件，类似java的flat jar概念的。我想这正和‘解释型语言’与‘编译型语言’的区别，.java文件先要编译.class文件才能执行，而.py直接即能执行。</p><p>所以在python的部署里，只要把工程文件全部copy或者zip下放到服务器上，再把python环境在服务器上安装好即可，对于有venv环境的，三方包已经在venv的site-packages下，所以理论上copy过去就能直接<code>python app.py</code>这般执行。</p><p>也支持类似nohup命令 <code>nohup /bin/python3 app.py&gt;/dev/null 2&gt;&amp;1 &amp;</code>是可行的，这个<code>java -jar app.jar</code>是一样。</p><p><img src="https://blog.shareworld.vip/upload/2022/12/http-server-docker.png" alt="http-server-docker" /></p><p>特地借用python标准库中http包，写了一个简单的http服务器，这样就能保持服务一直拉起状态，方便测试。</p><pre><code class="language-python">import http.serverimport httpclass request_handle(http.server.SimpleHTTPRequestHandler):    &quot;&quot;&quot;    自定义请求处理类    &quot;&quot;&quot;    def do_GET(self):        print(&#39;client_address&#39;, self.client_address)        print(&#39;headers&#39;, self.headers)        print(&#39;path&#39;, self.path)        print(&quot;command:&quot;, self.command)        self.send_response(200)        self.wfile.write(&quot;i get your message by get&quot;.encode(&quot;utf-8&quot;))    def do_POST(self):        print(&#39;client_address&#39;, self.client_address)        print(&#39;headers&#39;, self.headers)        print(&#39;path&#39;, self.path)        print(&quot;command:&quot;, self.command)        self.send_response(200)        self.wfile.write(&quot;i get your message by post&quot;.encode(&quot;utf-8&quot;))def my_server():    addr = &quot;127.0.0.1&quot;    port = 8080    server_o = (addr, port)    httpd = http.server.HTTPServer(server_o, request_handle)    return httpddef info():    print(&#39;http...&#39;)if __name__ == &#39;__main__&#39;:    info()    my_server().serve_forever()</code></pre><p>通过命令<code>curl http:/127.0.0.1:8080/test/ok</code>测试。</p><h3 id="%E9%83%A8%E7%BD%B2" tabindex="-1">部署</h3><p>另外像docker一样部署，也完全是与java一致，或者说docker部署可编程语言是解耦的，docker 的 <code>cmd []</code>命令只要拉起程序就行。</p><pre><code class="language-docker">FROM python:3.9WORKDIR /appADD . /appRUN pip install -r requirements.txtCMD [&quot;python&quot;,&quot;app.py&quot;]</code></pre><p>docker 部署启动，构建image起本质与服务器上直接python启动是相同的，只是对加了一个沙盒。</p><p>工程目录直接zip，然后在服务器上unzip，用python命令启动也挺快。有时候一个单文件的脚本.py的移动并可执行，真的是很方便。确实在这块来说，比java吸引人，特别是哪些只是作为一个脚本用的人来说。</p><p><code>学海无涯，苦作舟</code></p>]]>
                </content>
            </entry>
            <entry>
                <title><![CDATA[python学习之virtualenv&pip&namespace]]></title>
                <link rel="alternate" type="text/html" href="https://blog.shareworld.vip/archives/irtualenvpipnamespace" />
                <id>tag:https://blog.shareworld.vip,2022-12-20:irtualenvpipnamespace</id>
                <published>2022-12-20T21:15:10+08:00</published>
                <updated>2022-12-22T18:02:08+08:00</updated>
                <author>
                    <name>Owen Jia</name>
                    <uri>https://blog.shareworld.vip</uri>
                </author>
                <content type="html">
                        <![CDATA[<p>继续python进阶学习</p><h3 id="virtualenv" tabindex="-1">virtualenv</h3><p>虚拟环境变量，virtualenv 本身是一个工具，命令行工具<br />通过<code> pip install virtualenv</code> 安装</p><p>pip是一个package管理工具，有点java maven、node webpack &amp; npm &amp;yarn。和npm非常像。</p><p>virtualenv 目的是在你工程目录下创建一个独立的python命令及相关命令库，同时把依赖的第三方包都房主工程目录下统一管理。也就是每个project的运行环境独立了，用java的体系来讲就是每个project有个自己的jdk和三方jar库。这个也和前端工程目录结构类似，node_modules 就是跟工程走，而不是全局的，因为每个工程对用的package有自己的版本诉求。</p><ul><li>my_project<br />├── src<br />├── tests<br />└── venv<ul><li>├── Scripts<br />└── Lib<ul><li>└── site-packages</li></ul></li></ul></li></ul><p>这里的site-package就是三分包安装目录。通过 <code>pip install package_name</code>安装。</p><p>问题：</p><ol><li>工程内的site-packages和全局python/Lib下的site-packages存在依赖继承关系。理论是工程内先读取自己虚拟环境内，此前读取全局，这块具体什么个机制没有多少文档加以指导。</li><li>开启虚拟环境是，package并没有理想的安装在虚拟目录site-packages下，反而安装在全局，这块也没找到多少文档指导。</li></ol><p>pycharm 和 cmd 两种方式都试了virtualenv机制，同时测试 --system-site-packages 参数，都不太好用。少数情况下安装在虚拟目录中，大多安装在全局目录下，这块问题待后续慢慢查找吧。要么理论没学好（文档少），要么python自身bug。</p><h3 id="class-namespace" tabindex="-1">class namespace</h3><p>类机制作为一个高级语言是必备支持能力，就是面向对象编程理论。python也不例外的支持class。学习class就得学习命名空间和变量作用域，这个一定得懂，不然看不懂代码。</p><p>官网给了一段code，非常准确的描述了作用域关系。</p><pre><code class="language-python">def scope_test():    def do_local():        spam = &quot;local spam&quot;    def do_nonlocal():        nonlocal spam        spam = &quot;nonlocal spam&quot;    def do_global():        global spam        spam = &quot;global spam&quot;    spam = &quot;test spam&quot;    do_local()    print(&quot;After local assignment:&quot;, spam)    do_nonlocal()    print(&quot;After nonlocal assignment:&quot;, spam)    do_global()    print(&quot;After global assignment:&quot;, spam)scope_test()print(&quot;In global scope:&quot;, spam)</code></pre><p>运行结果：</p><pre><code class="language-python">After local assignment: test spamAfter nonlocal assignment: nonlocal spamAfter global assignment: nonlocal spamIn global scope: global spam</code></pre><p>原理（看懂这个，跨一大步）：<br />局部 赋值（这是默认状态）不会改变 scope_test 对 spam 的绑定。 nonlocal 赋值会改变 scope_test 对 spam 的绑定，而 global 赋值会改变模块层级的绑定。</p><h3 id="%E5%85%B6%E4%BB%96" tabindex="-1">其他</h3><p>如conda 工具值 anaconda、miniconda的使用，和pip&amp;virtualenv是一样的。</p><p><code>学海无涯，逆行而上。</code></p>]]>
                </content>
            </entry>
            <entry>
                <title><![CDATA[python学习进阶package_module]]></title>
                <link rel="alternate" type="text/html" href="https://blog.shareworld.vip/archives/packagemodule02" />
                <id>tag:https://blog.shareworld.vip,2022-12-20:packagemodule02</id>
                <published>2022-12-20T20:05:28+08:00</published>
                <updated>2022-12-20T20:05:28+08:00</updated>
                <author>
                    <name>Owen Jia</name>
                    <uri>https://blog.shareworld.vip</uri>
                </author>
                <content type="html">
                        <![CDATA[<p>python进阶之路</p><blockquote><p>学海苦行，逆流而上</p></blockquote><p>本地跑些py脚本，加上自带的lib，可以完成很多场景的应用开发。和java一样，你就使用jdk自带tool，也可以完成一座大楼的建立，就是苦了些（一切从头来）。python也是如此，自带库肯定是必须掌握的，很多无网情况下，只能人肉从头开发。</p><p>高级就是要站在巨人肩膀上。</p><p>类似java的maven中央仓库，python也有自己中央仓库pip：<a href="https://pypi.org/" target="_blank">https://pypi.org/</a><br />还有想docker image registry一样，都是中央仓库机制，同时支持私服（私有仓库）。<br /><img src="https://oscimg.oschina.net/oscnet/up-e54e6d6ed8b421a864b6090e275c042193f.png" alt="" /></p><p>类似maven，pip也是本地一个工具，python install pip安装即可。pip有个本地仓库site-packages，和maven的repository一样。默认site-packages在python安装目录lib里，idea工具会把这个目录加载进开发环境，所以在代码里import package-names 即可用。</p><p>项目迁移高效做法就是直接负责site-packages文件夹，和maven的repository直接复制一样，提供迁移效率（网络永远只是辅助）。</p><p><img src="https://oscimg.oschina.net/oscnet/up-4c32f15e6464e432c1ca251b0578ab779c3.png" alt="" /></p><p>特地引入了requests包，用来演示pip引入机制。顺道，研究了module机制，就是引入自己的packge，一版就是目录级管理。高级的就是上传自己的package到中央仓库供别人使用（暂时不研究了，以后出现场景时，再搞也不迟）。</p><pre><code class="language-python">def post(url, data=None, json=None, **kwargs):    r&quot;&quot;&quot;Sends a POST request.    :param url: URL for the new :class:&#96;Request&#96; object.    :param data: (optional) Dictionary, list of tuples, bytes, or file-like        object to send in the body of the :class:&#96;Request&#96;.    :param json: (optional) json data to send in the body of the :class:&#96;Request&#96;.    :param \*\*kwargs: Optional arguments that &#96;&#96;request&#96;&#96; takes.    :return: :class:&#96;Response &lt;Response&gt;&#96; object    :rtype: requests.Response    &quot;&quot;&quot;    return request(&#39;post&#39;, url, data=data, json=json, **kwargs)</code></pre><p>python搞定一个http post请求真心简单，这里json数据格式可直接写，和javastrict语法机制一样，天然支持json。json要是在java里写很麻烦，一堆“{}”，容易缺这缺那。</p><p>还是回到python定为，在我个人看来，作为一个万能的脚本，搞定‘短平快’需求，python处于绝对地位，想perl、shell、bat之类脚本靠后、靠后。</p>]]>
                </content>
            </entry>
            <entry>
                <title><![CDATA[python学习进阶threading]]></title>
                <link rel="alternate" type="text/html" href="https://blog.shareworld.vip/archives/python012" />
                <id>tag:https://blog.shareworld.vip,2022-12-18:python012</id>
                <published>2022-12-18T19:48:22+08:00</published>
                <updated>2022-12-18T19:48:22+08:00</updated>
                <author>
                    <name>Owen Jia</name>
                    <uri>https://blog.shareworld.vip</uri>
                </author>
                <content type="html">
                        <![CDATA[<p>已经不愿意止步与python的简单语法：if for while print import time sys</p><p>安装一个python软件，创建一个*.py文本，直接python *.py已经没有任何难度，剩下的就是熟悉内置各种包，但是这个需要项目或者场景的支持才能够深入掌握包。目前，大致记住有这么一个lib即可，自带的挺丰富。</p><p>近期把python自带的doc打开，发现新天地。和jdk安装包一个思路，python3的安装包自带该版本全部文档，这东西和研究jdk包是一样的，经常回顾就能建立知识体系。掌握一门语言，翻包，是基本能力，还有翻源码习惯。</p><p><img src="https://oscimg.oschina.net/oscnet/up-db035137e78bf53dd3b3d650928bca7c6e4.png" alt="" /></p><p>进阶学，发现python的thread模块居然这么全面。像：线程本地数据、队列、锁、并发、事件，和java很类似（虽然没有细看每个模块的定义，但既然是编程语言，详细和java之类不会反着来）。</p><p><img src="https://oscimg.oschina.net/oscnet/up-d98d9c31d282c665a187279c9dbf0b4a08a.png" alt="" /></p><p><img src="https://oscimg.oschina.net/oscnet/up-0062205bb9f8849483b52a0e02635b93ce7.png" alt="" /></p><p>新建一个thread：<br />python：threading.Thread()，构造方法支持几个参数</p><pre><code class="language-">class threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)¶</code></pre><p>相对于java的new Thread or new Running，这个参数量真的很少了。参数里面target就是thread要执行的模块，可以引入一个function，函数式编程这里提醒出便捷，def 一个function直接作为参数传入thread，真心方便。</p><p>另外python还支持Lock和RLock，特别是RLock全程 reentrant lock，可重入锁，完全和java一致。</p><p>在这里python的class居然支持重写method，这点厉害了（学到这里，理解了python为何这么火，全球第一火）。在编程语言创立圈子里，应该也有“标准化委员会”或者“非一致委员会”，像JRE标准、SQL标准等等，编程语言里面逻辑、数据类型、class、function等等定义，都有着基本标准（虽不是强一致，但大家都会遵守）。所以，才有掌握一门语言，其他语言也易学。</p><p>高阶python里，还有multiprocessing 之Pool Process，有 sched（调度），完全把一门语言搞到精通、架构级别，考自学基本知识是很难的，得有大量项目历练。</p><p>学海无涯苦作舟，沧海一叶！！！</p>]]>
                </content>
            </entry>
            <entry>
                <title><![CDATA[python学习class+exception]]></title>
                <link rel="alternate" type="text/html" href="https://blog.shareworld.vip/archives/classexception" />
                <id>tag:https://blog.shareworld.vip,2022-12-17:classexception</id>
                <published>2022-12-17T11:39:40+08:00</published>
                <updated>2022-12-17T11:39:40+08:00</updated>
                <author>
                    <name>Owen Jia</name>
                    <uri>https://blog.shareworld.vip</uri>
                </author>
                <content type="html">
                        <![CDATA[<p><strong>类模块</strong></p><p>class 定义语法格式虽与java不同，但理念是一样的，也支持继承夫类，重写父类方法，这里叫函数，本职都相同。</p><p>python里没有接口一说，这点却是显著的不同。</p><p><strong>异常模块</strong></p><p>python的异常，最父级是BaseException类，Exception是继承自它，还有一堆XXXError继承自Exception。像自定义异常直接继承Exception，也是官方推荐方式。</p><p>像 try  except  finally 结构也是一样，raise 就是 java里的throw 。</p><p><img src="https://blog.shareworld.vip/upload/2022/12/exception-class-1671766180051.png" alt="exception-class-1671766180051" /></p><p>这两块属于python的基本知识点，学起来很快，看几遍文档基本就掌握了。</p><p><strong>总结</strong></p><p>写到这里，对Python的掌握其实进入了一个里程碑，很多场景是够用了。处理一些临时问题，直接*.py文件即可处理，环境的安装也比较简单，推荐python原生环境，conda作为辅助。也有例外，项目构建选啥，就延续下去。</p><p>我对python的学习，还有2块要突破，分别是：</p><ul><li>GUI编程，都支持开发一些界面交互处理，这对很多不会技术的人配置执行就方便很多。</li><li>打包可执行包，类似java的flat jar这种，或者exe，还是为了小白能够运行py脚本准备。</li></ul><p>先从可执行包开始吧，研究python怎么处理。</p>]]>
                </content>
            </entry>
            <entry>
                <title><![CDATA[python学习]]></title>
                <link rel="alternate" type="text/html" href="https://blog.shareworld.vip/archives/xue-xi-python" />
                <id>tag:https://blog.shareworld.vip,2022-12-10:xue-xi-python</id>
                <published>2022-12-10T13:00:08+08:00</published>
                <updated>2023-08-09T13:53:19+08:00</updated>
                <author>
                    <name>Owen Jia</name>
                    <uri>https://blog.shareworld.vip</uri>
                </author>
                <content type="html">
                        <![CDATA[<h1 id="%E5%AD%A6%E4%B9%A0python" tabindex="-1">学习python</h1><p>在技术语言这条路上，再加一”城墙“，语言越多越”好“</p><h2 id="%E5%AD%A6%E4%B9%A0%E8%B7%AF%E5%BE%84%E8%AE%BE%E8%AE%A1" tabindex="-1">学习路径设计</h2><ul><li>官方文档 安装环境python3.x（直接放弃2，从3开始）</li><li>搭建开发工具idea，选用pycharm</li><li>学习基础语法，通过《菜鸟教程》网站</li><li>搭建学习project，练习基础语法，运行demo</li><li>掌握python3.x命令行常用命令</li><li>了解自带的lib，并掌握一些常用lib的使用</li><li>进阶<ul><li>框架学习django，构建web服务</li><li>掌握python工程化搭建，构建一个应用集成project</li><li>掌握python工程部署</li><li>python工程的性能常识</li><li>了解python应用生态</li></ul></li></ul><p>这条路目标还是学会python这门技术的运用，这样在任何环境下都可以结合业务进行落地。</p><h2 id="%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0" tabindex="-1">学习笔记</h2><h3 id="%E5%AE%89%E8%A3%85%E7%8E%AF%E5%A2%83" tabindex="-1">安装环境</h3><p>python.exe 环境比较好装，直接官网（<a href="http://www.python.org" target="_blank">www.python.org</a>）下载安装包即可，支持window、linux、mac多个操作系统。</p><blockquote><p>语言本身也开源，有能力的可以基于源代码构建安装包。<br />和jdk思路差不多</p></blockquote><p>pycharm idea安装，官网 <a href="http://www.jetbrains.com" target="_blank">www.jetbrains.com</a> 可以自己下载。学习阶段我直接安装社区版，免费的，将来考虑破解或者购买正版（显然，从未买过）。</p><p>环境搭建至此，完成</p><h3 id="%E5%AE%89%E8%A3%85%E5%8C%85%E7%9B%AE%E5%BD%95" tabindex="-1">安装包目录</h3><p><img src="https://img-blog.csdnimg.cn/4c18cde9742e4992927a64b7333894f3.png#pic_center" alt="python3.11安装包目录-windows" /></p><ul><li>Doc 是文档，全部是html格式，可以直接离线阅读</li><li>Lib 是常用的工具包库，像 html http email json logging 这些工具包</li><li>Tools 里有 demo 目录，是一些样例。<br /><img src="https://img-blog.csdnimg.cn/5e0afd97204e49ed96e9de6ba44ae320.png#pic_center" alt="redemo.py" /></li></ul><p>python做一些桌面小应用，这不错！</p><h3 id="%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95" tabindex="-1">基础语法</h3><p>推荐几个网站，重点推进《菜鸟教程》。</p><ul><li><a href="https://www.runoob.com/python3/python3-tutorial.html" target="_blank">https://www.runoob.com/python3/python3-tutorial.html</a></li><li><a href="https://docs.python.org/release/3.11.0/tutorial/index.html" target="_blank">https://docs.python.org/release/3.11.0/tutorial/index.html</a></li><li><a href="https://www.runoob.com/manual/pythontutorial3/docs/html/index.html" target="_blank">https://www.runoob.com/manual/pythontutorial3/docs/html/index.html</a></li></ul><p>这三个基本够用。</p><p>另外python安装包路径下有html版的doc，本机可直接查看。</p><h2 id="%E7%BB%93%E5%B0%BE" tabindex="-1">结尾</h2><p>写到这里，python的基础学习，我已经到了”掌握常用lib阶段“，对”命令行命令“还需要再补补，语法过了有几轮（必须常动手，容易忘）。</p><p>期待”进阶“阶段了。</p><p>demo会在”抓取数据“和”数据分析“两个方向尝试。</p>]]>
                </content>
            </entry>
            <entry>
                <title><![CDATA[达梦数据库-DM8-国产]]></title>
                <link rel="alternate" type="text/html" href="https://blog.shareworld.vip/archives/dm801" />
                <id>tag:https://blog.shareworld.vip,2022-11-20:dm801</id>
                <published>2022-11-20T21:23:50+08:00</published>
                <updated>2022-11-20T21:23:50+08:00</updated>
                <author>
                    <name>Owen Jia</name>
                    <uri>https://blog.shareworld.vip</uri>
                </author>
                <content type="html">
                        <![CDATA[<p>近期因平台需要”信创“支持的需要，原有的数据中台系统需要集成国产数据库，也因为客户的实际场景就是运行了”达梦M8“，我做了些研究。</p><h2 id="%E4%BA%86%E8%A7%A3%E8%BE%BE%E6%A2%A6%E6%95%B0%E6%8D%AE%E5%BA%93" tabindex="-1">了解达梦数据库</h2><p>达梦数据库，是武汉达梦数据库股份有限公司的拳头产品，数据库名就叫”达梦数据库“，目前已经更新到了DM8版本。</p><p>商业数据库，没有开源，也就没有社区版本，官方支持1年的试用。（1年很多场景能够跑起来验证，个人觉得还是不错的，额外的需求相信淘宝也能支持）</p><p>2000年成立的公司，支持不少2G企业。国产趋势里，达梦占比是比较高的，已经不是第一次听到这款数据库产品。</p><p><img src="https://blog.shareworld.vip/upload/2022/11/%E8%BE%BE%E6%A2%A6%E6%95%B0%E6%8D%AE%E5%BA%93_20221121153727.png" alt="达梦数据库_20221121153727" /></p><h2 id="%E5%AD%A6%E4%B9%A0%E8%BE%BE%E6%A2%A6%E6%95%B0%E6%8D%AE%E5%BA%93-dm8" tabindex="-1">学习达梦数据库-DM8</h2><p>下载了它们DM8数据库产品，zip包700+M，windows支持iso安装，安装工具很标准，跟oracle、mysql类似的。</p><p>工具集也很丰富，客户端工具、数据库服务、命令行工具，监控和管理服务都很齐。</p><p><img src="https://blog.shareworld.vip/upload/2022/11/%E5%AE%89%E8%A3%85%E6%96%87%E4%BB%B6%E5%A4%B9_20221121155151.png" alt="安装文件夹_20221121155151" /></p><p>另外，文档真心详细，很用心了。比如，像我这样第一次用的小白，四个文档解决了我关心的问题，”DBA、Instal、Program、SQL“.pdf。安装先搞定，再查看DBA文档，搞定数据库系统本身的字典表，基本了解7788，最后查看应用基础文档，像jdbc这种及spring、mybaits这种搞清楚，标准sql基本数据厂商都会去支持，差异可以后期遇到再慢慢看。</p><p><img src="https://blog.shareworld.vip/upload/2022/11/%E6%96%87%E6%A1%A3_20221121155418.png" alt="文档_20221121155418" /></p><h2 id="%E6%B5%8B%E8%AF%95" tabindex="-1">测试</h2><p>客户端工具，界面简洁，拖拽做的挺好，集成很多后期数据库客户端便捷功能，比如选中表-拖拽到sql编辑框-自动生成sql完整语句，这个就真心的从用户角度来考虑，体验非常好。</p><p><img src="https://blog.shareworld.vip/upload/2022/11/DM-manager_20221121160538.png" alt="DM-manager_20221121160538" /></p><p>数据库架构：user、schema、view、function、proc、table，和国际标准数据模式都是兼容的，达梦很类似oracle，dba.pdf里有非常详细的运维介绍，包括存储表空间、页、日志、性能等等。</p><p><img src="https://blog.shareworld.vip/upload/2022/11/image.png" alt="数据架构" /></p><p>可借鉴我的思路：</p><ul><li>数据源运用，重点学习Program、SQL两个文档，基本够了。</li><li>数据库运维，重点DBA、Install文档，另外监控和工具文档也有掌握。</li></ul><p>达梦DM8驱动已支持有：ODBC、JDBC、PHP、.NET、NODE、GO。像Node、Go的支持，值得思考（入行语言优先参考），另外pyhton的支持被单独拉出一章进行介绍，文档也是独立的。</p><p><a href="https://eco.dameng.com/document/dm/zh-cn/pm/index.html" target="_blank">官网在线手册</a></p><h2 id="%E5%90%8E%E7%BB%AD" tabindex="-1">后续</h2><p>信创，国内是一个风口，目前趋势来看还要扩大。特别是数据及工具产品，在2G、2F上都是上升，2C目前还不明朗。</p>]]>
                </content>
            </entry>
            <entry>
                <title><![CDATA[发现一个比Postman更好的东西Apifox]]></title>
                <link rel="alternate" type="text/html" href="https://blog.shareworld.vip/archives/apifox01" />
                <id>tag:https://blog.shareworld.vip,2021-11-19:apifox01</id>
                <published>2021-11-19T13:50:34+08:00</published>
                <updated>2022-09-27T18:10:18+08:00</updated>
                <author>
                    <name>Owen Jia</name>
                    <uri>https://blog.shareworld.vip</uri>
                </author>
                <content type="html">
                        <![CDATA[<p>超过Postman的好工具!</p><p>Postman这个工具是个“新生代农民工”，我想就没有人不知道是什么。</p><p>Postman，一个API调试工具。目前已知最主流的，且市场占有率不低于50%，机会所有后端研发工程师都用过它，甚至一直用它。</p><h2 id="apifox优势">apifox优势</h2><p>今天推荐的是另外一个工具Apifox，这是一个桌面工具也支持带web页面展现工具。还有点像项目Swagger工具，但它的优势是不用集成到代码里面，没有耦合，同时页面也好看非常多。</p><p>桌面特性同Postman是一样的，win与mac都有支持。</p><p>Apifox支持“发布”，会直接生成一个API的网站，这个就很厉害了。</p><p>比如，Axure也支持发布，可以在WEB页面上查看，但是它是单账户的。每个项目每个公司只能看自己的，或者自己主动分享。Apifox支持分享自己平台API，相当于公开API接口展现给其他人，这点同Github思路差不多，也能自己搜索。创新上，这不是什么高升能力或者模式，但是之前就没有人做出来和做的好的，比较早期盈利模式还没有，搭出来的平台就是成本。</p><p>对于小的团队来说，这个工具非常实用方便。</p><h2 id="apifox样例">Apifox样例</h2><p><img src="https://blog.shareworld.vip/upload/2021/11/%E6%88%AA%E5%B1%8F2021-11-19%20%E4%B8%8B%E5%8D%881.42.55-615e77a6310d43749d4b83cddce33b31.png" alt="截屏20211119 下午1.42.55.png" /></p><p><img src="https://blog.shareworld.vip/upload/2021/11/%E6%88%AA%E5%B1%8F2021-11-19%20%E4%B8%8B%E5%8D%881.43.40-50f956b2ab3749b789221b5de70de0c3.png" alt="截屏20211119 下午1.43.40.png" /></p>]]>
                </content>
            </entry>
</feed>
