Compare commits

...

54 Commits

Author SHA1 Message Date
libolin b9d0426bb0 4.7 1 week ago
libolin c9a00bc88f 4.4 1 week ago
libolin 425d7237db 4.3 2 weeks ago
libolin 73811cd04b 4.2 2 weeks ago
libolin 00050fe338 4.1 2 weeks ago
libolin fe59b9ef87 3.31 2 weeks ago
libolin 01a09cb61f 2026.3.30 2 weeks ago
libolin 92681d8f0c 2026.03.27 2 weeks ago
libolin d2e93cf92a Merge branch 'milestone-20260325-学习笔记' into libolin/feature-20260327153128-学习笔记 2 weeks ago
libolin 84231376db 2026.3.28 2 weeks ago
huangyongxing 51f19f9783 Merge branch 'huangyongxing/feature-20260327161252-学习笔记' into milestone-20260325-学习笔记 2 weeks ago
huangyongxing d04a111382 3.28学习笔记 2 weeks ago
吴迎召 ba081ca88d Merge branch 'wuyingzhao' into milestone-20260325-学习笔记 2 weeks ago
吴迎召 1e46f0e256 2026.03.27 2 weeks ago
huangyongxing 16753c9871 Merge branch 'huangyongxing/feature-20260327161252-学习笔记' into milestone-20260325-学习笔记 3 weeks ago
huangyongxing 2c9ea554f3 3.27学习笔记 3 weeks ago
huangyongxing 34daa9f8f0 Merge branch 'huangyongxing/feature-20260327161252-学习笔记' into milestone-20260325-学习笔记 3 weeks ago
huangyongxing 2225cbca84 更新笔记 3 weeks ago
huangyongxing 5759ec7be7 3.27股票学习笔记 3 weeks ago
huangyongxing 174aa0bc84 3.27股票学习笔记 3 weeks ago
huangyongxing d049131b30 3.27股票学习笔记 3 weeks ago
zhouxinzhong a06b8247d2 Merge branch 'milestone-20260325-学习笔记' of http://39.101.133.168:8807/majun/practiceGit into milestone-20260325-学习笔记 3 weeks ago
zhouxinzhong 2a48b6058a Merge branch 'zhouxinzhong/feature-20260327150147-学习笔记' into milestone-20260325-学习笔记 3 weeks ago
zhouxinzhong b240daf7da 3.27提交学习笔记 3 weeks ago
吴迎召 d875e4a184 Merge branch 'wuyingzhao' into milestone-20260325-学习笔记 3 weeks ago
吴迎召 20213828f1 2026.03.27 3 weeks ago
libolin 8258ea6fd9 chore(ide): 添加IDEA项目配置文件 3 weeks ago
libolin 4ed77a1459 22026.3.27 3 weeks ago
吴迎召 e9f437b326 Merge branch 'wuyingzhao' into milestone-20260325-学习笔记 3 weeks ago
吴迎召 4abc458ed9 2026.03.27 3 weeks ago
吴迎召 ec78e5b1dd 2026.03.27 3 weeks ago
吴迎召 6cb52561f7 Merge branch 'wuyingzhao' into milestone-20260325-学习笔记 3 weeks ago
吴迎召 41cc6077cd 2026.03.27 3 weeks ago
吴迎召 e88433d024 Merge branch 'wuyingzhao' into milestone-20260325-学习笔记 3 weeks ago
吴迎召 9f815af719 2026.03.27 3 weeks ago
吴迎召 4df6b27b38 Merge branch 'wuyingzhao' into milestone-20260325-学习笔记 3 weeks ago
吴迎召 2e5e2e5c6b 2026.03.27 3 weeks ago
吴迎召 f6bd9101cb 2026.03.27 3 weeks ago
吴迎召 2403ac3c99 2026.03.27 3 weeks ago
libolin 8ab9bacef9 Merge branch 'milestone-20260325-学习笔记' of http://39.101.133.168:8807/majun/practiceGit into milestone-20260325-学习笔记 3 weeks ago
libolin 432e2699ee . 3 weeks ago
libolin 7e8c7451cc Merge branch 'milestone-20260325-学习笔记' of http://39.101.133.168:8807/majun/practiceGit into milestone-20260325-学习笔记 3 weeks ago
libolin 4dd86999f8 Merge branch 'milestone-20260325-学习笔记' of http://39.101.133.168:8807/majun/practiceGit into milestone-20260325-学习笔记 3 weeks ago
吴迎召 6849fa7aae Merge branch 'wuyingzhao' into milestone-20260325-学习笔记 3 weeks ago
huangyongxing 65c80bd9c5 Merge branch 'huangyongxing' into milestone-20260325-学习笔记 3 weeks ago
libolin d4bb6cfe2c . 3 weeks ago
ZanYuPing 0d1ef14d12 Merge branch 'zanyuping' into milestone-20260325-学习笔记 3 weeks ago
zhouxinzhong 47d8240d7b 周新忠3.26笔记 3 weeks ago
ZanYuPing db7ff63b64 昝宇萍3.26的Link软件学习笔记 3 weeks ago
huangyongxing 4f70f59221 3.27学习笔记 3 weeks ago
huangyongxing 7404518e03 3.27学习笔记 3 weeks ago
ZanYuPing 4a43c59332 昝宇萍3.26、3.27的股票知识学习总结 3 weeks ago
吴迎召 85a6c786d6 吴迎召学习笔记 3 weeks ago
ZanYuPing 715f9f7f37 昝宇萍3.26、3.27的Git学习笔记总结 3 weeks ago
  1. 138
      .idea/workspace.xml
  2. 0
      README.md
  3. 10
      李柏霖学习笔记/.idea/.gitignore
  4. 6
      李柏霖学习笔记/.idea/misc.xml
  5. 8
      李柏霖学习笔记/.idea/modules.xml
  6. 6
      李柏霖学习笔记/.idea/vcs.xml
  7. 9
      李柏霖学习笔记/.idea/李柏霖学习笔记.iml
  8. 284
      李柏霖学习笔记/2026.3.28.md
  9. BIN
      李柏霖学习笔记/3.26李柏霖.docx
  10. 206
      李柏霖学习笔记/3.30.md
  11. 210
      李柏霖学习笔记/3.31.md
  12. 137
      李柏霖学习笔记/4.1.md
  13. 232
      李柏霖学习笔记/4.2.md
  14. 43
      李柏霖学习笔记/4.3.md
  15. 302
      李柏霖学习笔记/4.4.md
  16. BIN
      李柏霖学习笔记/4.7后端项目demo.7z
  17. BIN
      李柏霖学习笔记/images/021099bd151272c630107ed552ab7af2.png
  18. BIN
      李柏霖学习笔记/images/QQ20260330-143952.png
  19. BIN
      李柏霖学习笔记/images/image-20260328093542705.png
  20. BIN
      李柏霖学习笔记/images/image-20260328093613551.png
  21. BIN
      李柏霖学习笔记/images/image-20260328112106933.png
  22. BIN
      李柏霖学习笔记/images/image-20260328135132711.png
  23. BIN
      李柏霖学习笔记/images/image-20260328135416809.png
  24. BIN
      李柏霖学习笔记/朝闻道4.7总计.doc
  25. BIN
      李柏霖学习笔记/第二天.docx

138
.idea/workspace.xml

@ -0,0 +1,138 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="46fcace5-02b8-477e-a4cb-e346f99227d5" name="Changes" comment="2026.03.27" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="Git.Settings">
<option name="RECENT_BRANCH_BY_REPOSITORY">
<map>
<entry key="$PROJECT_DIR$" value="milestone-20260325-学习笔记" />
</map>
</option>
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="ProjectColorInfo">{
&quot;associatedIndex&quot;: 1,
&quot;fromUser&quot;: false
}</component>
<component name="ProjectId" id="3BWFpx21OqJ9SjBVKLMNyDgcaIv" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"ModuleVcsDetector.initialDetectionPerformed": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
"RunOnceActivity.git.unshallow": "true",
"RunOnceActivity.typescript.service.memoryLimit.init": "true",
"codeWithMe.voiceChat.enabledByDefault": "false",
"git-widget-placeholder": "libolin/feature-20260327153128-学习笔记",
"ignore.virus.scanning.warn.message": "true",
"kotlin-language-version-configured": "true",
"last_opened_file_path": "C:/Users/Administrator/Desktop/practiceGit",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "npm",
"settings.editor.selected.configurable": "preferences.language.and.region",
"vue.rearranger.settings.migration": "true"
}
}]]></component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="46fcace5-02b8-477e-a4cb-e346f99227d5" name="Changes" comment="" />
<created>1774597105469</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1774597105469</updated>
<workItem from="1774597106737" duration="1547000" />
<workItem from="1774598682364" duration="3258000" />
</task>
<task id="LOCAL-00001" summary="2026.03.27">
<option name="closed" value="true" />
<created>1774598998341</created>
<option name="number" value="00001" />
<option name="presentableId" value="LOCAL-00001" />
<option name="project" value="LOCAL" />
<updated>1774598998341</updated>
</task>
<task id="LOCAL-00002" summary="2026.03.27">
<option name="closed" value="true" />
<created>1774599148219</created>
<option name="number" value="00002" />
<option name="presentableId" value="LOCAL-00002" />
<option name="project" value="LOCAL" />
<updated>1774599148219</updated>
</task>
<task id="LOCAL-00003" summary="2026.03.27">
<option name="closed" value="true" />
<created>1774599288945</created>
<option name="number" value="00003" />
<option name="presentableId" value="LOCAL-00003" />
<option name="project" value="LOCAL" />
<updated>1774599288945</updated>
</task>
<task id="LOCAL-00004" summary="2026.03.27">
<option name="closed" value="true" />
<created>1774600524394</created>
<option name="number" value="00004" />
<option name="presentableId" value="LOCAL-00004" />
<option name="project" value="LOCAL" />
<updated>1774600524394</updated>
</task>
<task id="LOCAL-00005" summary="2026.03.27">
<option name="closed" value="true" />
<created>1774601140534</created>
<option name="number" value="00005" />
<option name="presentableId" value="LOCAL-00005" />
<option name="project" value="LOCAL" />
<updated>1774601140534</updated>
</task>
<option name="localTasksCounter" value="6" />
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>
<entry key="MAIN">
<value>
<State>
<option name="FILTERS">
<map>
<entry key="branch">
<value>
<list>
<option value="milestone-20260325-学习笔记" />
</list>
</value>
</entry>
</map>
</option>
</State>
</value>
</entry>
</map>
</option>
</component>
<component name="VcsManagerConfiguration">
<MESSAGE value="2026.03.27" />
<option name="LAST_COMMIT_MESSAGE" value="2026.03.27" />
</component>
<component name="XSLT-Support.FileAssociations.UIState">
<expand />
<select />
</component>
</project>

0
README.md

10
李柏霖学习笔记/.idea/.gitignore

@ -0,0 +1,10 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 已忽略包含查询文件的默认文件夹
/queries/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/

6
李柏霖学习笔记/.idea/misc.xml

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
李柏霖学习笔记/.idea/modules.xml

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/李柏霖学习笔记.iml" filepath="$PROJECT_DIR$/.idea/李柏霖学习笔记.iml" />
</modules>
</component>
</project>

6
李柏霖学习笔记/.idea/vcs.xml

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>

9
李柏霖学习笔记/.idea/李柏霖学习笔记.iml

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

284
李柏霖学习笔记/2026.3.28.md

@ -0,0 +1,284 @@
# 股票基础知识和交易规则
------
1. ```
一、股票与证券市场基础
证券定义 :多种经济权益凭证的统称,通常指有价证券。
股票本质 :一种有价证券,是上市公司为筹集资金向出资人发行的股份凭证。
市场三大功能 :
筹资功能 :为资金需求者筹资,为供给者提供投资对象。
定价功能 :通过供求竞争为资本决定价格。
资本配置功能 :引导资本流向报酬率高、潜力大的企业或行业。
股票五大特性 :风险性、收益性、流通性、波动性、永久性。
二、市场分类与交易规则
###1.股票分类
按上市地点/投资者划分 :
A股 :人民币计价,境内上市,面对中国公民。
B股 :外币计价(美元/港元),境内上市,面对境外投资者。
H股 :内地注册,香港上市。
N/S/T股 :分别指在美国、新加坡、日本上市的中国企业股票。
多层次资本市场 :包括主板、中小板、创业板(风险较大,需单独开通)及“新三板”(全国中小企业股份转让系统)。
###2.交易原则与规制
竞价原则 : 价格优先 (买入高价优先、卖出低价优先)与 时间优先 (同价位先申报优先)。
交易单位 :股票以“股”为单位, 100股=1手 ;基金以“份”为单位。
涨跌幅限制 :通常每只证券交易价格相对前一交易日收盘价涨跌幅度不得超过 10% 。
交收制度 :A股实行 T+1交收 ,即次日完成款项与证券收付。
三、股票分析流派与核心理论
###1.分析流派
基本面分析 :核心观点是“价值决定价格”,通过宏观政策、行业前景及公司财务状况进行评估。
技术分析 :核心观点是“供求关系决定价格”,基于三大公理:
1.市场行为包容和消化一切。
2.股价以趋势方式运行(上升、下降、横盘)。
3.历史会不断重演,但非简单重复。
###2.道氏理论(技术分析鼻祖)
平均价格包容消化一切 :股价指数反映了市场整体运行趋势。
三种价格运动 :
基本运动 :主要趋势,持续一年以上。
次级运动 :基本运动中的重要回撤,持续三周至数月。
日常运动 :波动无序,投资风险大,在策略上应坚决放弃。
趋势阶段 :分为积累阶段、稳定上涨阶段及反转过渡阶段。
##四、核心专业术语
K线图 :由实体(开盘/收盘价)和影线(最高/最低价)组成,红色代表上涨(阳线),绿色代表下跌(阴线)。
多头与空头 :
多头(牛市) :看好后市,先买后卖获利。
空头(熊市) :看坏后市,先卖后买(融券等方式)获利。
仓位操作 :包括 建仓 (买入)、 平仓 (卖出)、 满仓 、 补仓 (再次买入)及 清仓 。
财务指标 :
市盈率(P/E) :普通股每股市价/每股获利额。
市净率(P/B) :每股市价/每股净资产。
特别标示 :
N :新股上市首日标志。
ST/\*ST :财务或其他状况异常,提示市场风险。
```
# java复习:
![021099bd151272c630107ed552ab7af2](./images/021099bd151272c630107ed552ab7af2.png)
数组在计算机中的执行原理:
(1)
![image-20260328093542705](./images/image-20260328093542705.png)
(2)
![image-20260328093613551](./images/image-20260328093613551.png)
同类型的变量可以相互赋值的;
理解了浅拷贝,深拷贝的具体过程和区别
复习方法相关内容:
![image-20260328112106933](./images/image-20260328112106933.png)
# redis复习:
五大数据类型:string、list set hash zset
## string:
### 基础指令
![image-20260328135132711](./images/image-20260328135132711.png)
### 浏览量实现指令
![image-20260328135416809](./images/image-20260328135416809.png)
```
127.0.0.1:6379> set views 0# 初始浏览量为0 #set article:10000:views 查看id为10000的文章的浏览量
OK
127.0.0.1:6379> get views
"o"
127.0.0.1:6379> incr views # 自增1 浏览量变为1
(integer) 1
127.0.0.1:6379> incr views
(integer) 2
127.0.0.1:6379> get views
"2"
127.0.0.1:6379> decr views # 自减1
浏览量-1
(integer) 1
127.0.0.1:6379> decr views
(integer) 0
127.0.0.1:6379> decr views
(integer) -1
127.0.0.1:6379> get views
“-1"
127.0.0.1:6379> INCRBY Views10 #可以设置步长,指定增量!
(integer) 9
127.0.0.1:6379> INCRBY VIEWS 10
(integer) 19
127.0.0.1:6379> DECRBY Views 5
(integer) 14
```
### #字符串范围 range
```
127.0.0.1:6379>setkey1"hello,kuangshen"# 设置 key1 的值
OK
127.0.0.1:6379> get keyl
"hello,kuangshen"
127.0.0.1:6379> GETRANGE key1 03
#截取字符串[0,3]
"hel1"
127.0.0.1:6379> GETRANGE key1 0 -1
#获取全部的字符串和getkey是一样的
"hello,kuangshen"
```
### #替换
```
127.0.0.1:6379> set key2 abcdefg
OK
127.0.0.1:6379> get key2
"abcdefg""
127.0.0.1:6379> SETRANGE key2 1 XX
(integer)7
127.0.0.1:6379> get key2
"axxdefg"
```
### setex (set with expire) #设置过期时间
### setnx (set if not exist) #不存在在设置 (在分布式锁中会常常使用!)
```
127.0.0.1:6379>setex key3 30 "hello" #设置key3的值为hello,30秒后过期
OK
127.0.0.1:6379> ttl key3
(integer) 26
127.0.0.1:6379> get key3
"hello"
127.0.0.1:6379>setnx mykey"redis" # 如果mykey 不存在,创建mykey
(integer)1
127.0.0.1:6379> keys *
1) "key2"
2) "mykey""
3) "keyl"
127.0.0.1:6379> ttl key3
Cinteger) -2
127.0.0.1:6379>setnxmykey"MongoDB"#如果mykey存在,创建失败!
(integer) 0
127.0.0.1:6379> get mykey
"redis"
```
### 对象
```
set user:1 {name:zhangsan,age:3} #设置一个user:1对象 值为json字符来保存一个对象!
#这里的key是一个巧妙的设计:user:{id}:{filed},如此设计在Redis中是完全ok了!
127.0.0.1:6379> mset user:1:name zhangsan user:1:age 2
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "zhangsan"
2) "2"
getset #先get然后在set
```
## List
所有的list命令用l开头
1. ```
lpush
127.0.0.1:6379> lpush list one
(integer) 1
127.0.0.1:6379> lpush list two
(integer) 2
127.0.0.1:6379> lpush list three
(integer) 3
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> lrange list 0 1
4) "three"
5) "two"
倒着输出
```
lindex 通过下表获得值
```
127.0.0.1:6379> lindex list 1
"one"
127.0.0.1:6379> lindex list 0
"two"
```
llen返回列表长度
```
127.0.0.1:6379> lpush list one
(integer) 1
127.0.0.1:6379> lpush list two
(integer) 2
127.0.0.1:6379> lpush list three
(integer) 3
127.0.0.1:6379> llen list
(integer) 3
```
移除指定值
取关 uid
lrem
linset 在指定值的前面或者后面插入值
```
127.0.0.1:6379> rpush mylist hello
(integer) 1
127.0.0.1:6379> rpush mylist world
(integer) 2
127.0.0.1:6379> linsert mylist before world other
(integer) 3
127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "other"
"world"
127.0.0.1:6379>
```
### 总结:
1.实际上是一个双向链表
2.key不存在,创建新链表
3.移除所有元素,空链表也代表不存在
4.在两边插入或者改动值,效率高,中间元素,相对效率低
消息队列

BIN
李柏霖学习笔记/3.26李柏霖.docx

206
李柏霖学习笔记/3.30.md

@ -0,0 +1,206 @@
# go语言
## 执行流程
![](images/QQ20260330-143952.png)
Go编译器是一行行进行编译的,因此我们一行就写一条语句,不能把多条语句写在同一个,否则报错
## 转义字符
\t:制表符
\n:换行
**\\"**:一个"
\r:回车
fmt包提供格式化,输出,输入函数。
## 基本语法
使用gofmt进行格式化
**(1)**
所有的Go文件以package 开头,对于独立运行的执行文件必须是package main;
fmt.Printf("Hello, world; or 世界") 这是说需要将fmt包加入main。不是main的其他包都被称为库,其他许多编程语言有 着类似的概念。
package main 必须首先出现,紧跟着是import。
在 Go 中,package 总是首先出现, 然后是import,然后是其他所有内容。当Go程序在执行的时候,首先调用的函数 是main.main(),这是从C中继承而来。这里定义了这个函数;
Go 同其他语言不同的地方在于变量的类型在变量名的后面。不是:int a,而是a int。 当定义了一个变量,它默认赋值为其类型的null值。这意味着,在var a int后,a的 值为0。而var s string,意味着s被赋值为零长度字符串,也就是""。
**(2)**
var a int
var b bool
a = 15
b = false
------
用:= 声明
a := 15
b := false
在左边使用了关键字var声明变量,然后赋值给它。右边的代码使用了:= 使得在一 步内完成了声明和赋值(这一形式只可用在函数内)。在这种情况下,变量的类型是由 值推演出来的。值15表示是int类型,值false告诉Go它的类型应当是bool。多 个var声明可以成组;const和import同样允许这么做。留意圆括号的使用: var ( x int b
### Go 语言的字符串连接可以通过 **+** 实现:
```go
package main
import "fmt"
func main() {
fmt.Println("Google" + "Runoob")
}
```
```
GoogleRunoob
```
Go 语言中使用 **fmt.Sprintf****fmt.Printf** 格式化字符串并赋值给新串:
- **Sprintf** 根据格式化参数生成格式化的字符串并返回该字符串。
- **Printf** 根据格式化参数生成格式化的字符串并写入标准输出。
| **概念** | **Java 对应** | **Go 派生类型** |
| -------------- | ---------------- | ------------------------ |
| **对象属性** | Class (Fields) | **Struct** |
| **动态列表** | ArrayList | **Slice** |
| **键值对** | HashMap | **Map** |
| **抽象定义** | Interface | **Interface** (隐式实现) |
| **内存操作** | 引用 (Reference) | **Pointer** (显式指针) |
| **多线程通信** | BlockingQueue | **Channel** |
声明变量的一般形式是使用 var 关键字:
```go
var identifier type
```
可以一次声明多个变量:
```go
var identifier1, identifier2 type
```
### 变量声明
**第一种,指定变量类型,如果没有初始化,则变量默认为零值**。
```
var v_name v_type
v_name = value
```
bool 零值为 false
没有初始化就为零值
**第二种,根据值自行判定变量类型。**
```
var v_name = value
```
**第三种,如果变量已经使用 var 声明过了,再使用 \**:=\** 声明变量,就产生编译错误,格式:**
```
v_name := value
```
例如:
```
var intVal int
intVal :=1 // 这时候会产生编译错误,因为 intVal 已经声明,不需要重新声明
```
直接使用下面的语句即可:
```
intVal := 1 // 此时不会产生编译错误,因为有声明新的变量,因为 := 是一个声明语句
```
**intVal := 1** 相等于:
```
var intVal int
intVal =1
```
```
//类型相同多个变量, 非全局变量
var vname1, vname2, vname3 type
vname1, vname2, vname3 = v1, v2, v3
```
**所有像 int、float、bool 和 string 这些基本类型都属于值类型,使用这些类型的变量直接指向存在内存中的值:**
可以通过 &i 来获取变量 i 的内存地址
一个引用类型的变量 r1 存储的是 r1 的值所在的内存地址(数字),或内存地址中第一个字所在的位置。
![img](https://www.runoob.com/wp-content/uploads/2015/06/4.4.2_fig4.3.jpg)
这个内存地址称之为指针,这个指针实际上也被存在另外的某一个值中。
变量的初始化时省略变量的类型而由系统自动推断,声明语句写上 var 关键字其实是显得有些多余了,因此我们可以将它们简写为 a := 50 或 b := false。
### go的常量
- 显式类型定义: `const b string = "abc"`
- 隐式类型定义: `const b = "abc"`
#### iota,特殊常量,可以认为是一个可以被编译器修改的常量。
iota 在 const关键字出现时将被重置为 0(const 内部的第一行之前),const 中每新增一行常量声明将使 iota 计数一次(iota 可理解为 const 语句块中的行索引)。
iota 可以被用作枚举值
**`iota` 只能读,不能写**:永远不要写 `iota = x``iota += 1`,这是 Go 语法严格禁止的。
**`const` 块内类型一致**:同一组 `const` 里,要么全是数字,要么全是字符串,不能混用。
Go 语言支持的位运算符如下表所示。假定 A 为60,B 为13:
| 运算符 | 描述 | 实例 |
| :----- | :----------------------------------------------------------- | :------------------------------------- |
| & | 按位与运算符"&"是双目运算符。 其功能是参与运算的两数各对应的二进位相与。 | (A & B) 结果为 12, 二进制为 0000 1100 |
| \| | 按位或运算符"\|"是双目运算符。 其功能是参与运算的两数各对应的二进位相或 | (A \| B) 结果为 61, 二进制为 0011 1101 |
| ^ | 按位异或运算符"^"是双目运算符。 其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。 | (A ^ B) 结果为 49, 二进制为 0011 0001 |
| << | 左移运算符"<<"是双目运算符。左移n位就是乘以2的n次方。 其功能把"<<"左边的运算数的各二进位全部左移若干位,由"<<"右边的数指定移动的位数,高位丢弃,低位补0。 | A << 2 结果为 240 二进制为 1111 0000 |
| >> | 右移运算符">>"是双目运算符。右移n位就是除以2的n次方。 其功能是把">>"左边的运算数的各二进位全部右移若干位,">>"右边的数指定移动的位数。 | A >> 2 结果为 15 ,二进制为 0000 1111 |
# 夺宝奇兵之时空预测:
AI时空共振:
股价不可能一直涨或者跌,时间决定了一切,空间决定了你的收益到底有多大
AI时空共振功能
• 追踪股价运行背后的超级临界点,预判转折位置。
• 适用于所有股票,结合时间和空间分析。
• 以英伟达为例展示功能,识别连续上涨后的临界点。
未来预测技术
• 包含股价预测和时空预测两大内容。
• 提前标注变盘点,如距离下个变盘点5或13个交易日。
• 通过案例验证预测准确性,如高低点与实际走势吻合。
• 结合高阶数据科学与AI技术,逐步完善预测模型。
高低点规律总结
• 高点提前易暴跌,低点提前易暴涨。
• 高点延后易续涨,低点延后易续跌。
• 牛市中低点易提前,高点易延后。
• 熊市中高点易提前,低点易延后。

210
李柏霖学习笔记/3.31.md

@ -0,0 +1,210 @@
# 布尔
bool : true false
默认为false
主要在if判断中用、
# 数字型
| 序号 | 类型和描述 |
| :--- | :----------------------------------------------------------- |
| 1 | **uint8** 无符号 8 位整型 (0 到 255) |
| 2 | **uint16** 无符号 16 位整型 (0 到 65535) |
| 3 | **uint32** 无符号 32 位整型 (0 到 4294967295) |
| 4 | **uint64** 无符号 64 位整型 (0 到 18446744073709551615) |
| 5 | **int8** 有符号 8 位整型 (-128 到 127) |
| 6 | **int16** 有符号 16 位整型 (-32768 到 32767) |
| 7 | **int32** 有符号 32 位整型 (-2147483648 到 2147483647) |
| 8 | **int64**有符号 64 位整型 (-9223372036854775808 到 9223372036854775807) |
| 1 | byte类似 uint8 |
| ---- | --------------------------------------- |
| 2 | **rune类似 int32** |
| 3 | **uint 32或64位** |
| 4 | **int与 uint 一样大小** |
| 5 | **uintptr无符号整型,用于存放一个指针** |
整形不能转化为bool类型的。
按位与&、按位或|、按位异或^它们的运算规则是:
按位与& 两位全为1,结果为1,否则为0
按位或I 两位有一个为1,结果为1,否则为0
按位异或^ 两位一个为0,一个为1,结果为1,否则为0
左移运算符:<<
右移运算符:>>
&、|、^ 、<<、>>都是补码计算
### 单分支
var age int
fmt.Scanln(&age)
if age > 18 {
fmt.println()
}
### 双分支
if。。。else
*Go 没有三目运算符,所以不支持* **?:** *形式的条件判断。*
| [break 语句](https://www.runoob.com/go/go-break-statement.html) | 经常用于中断当前 for 循环或跳出 switch 语句 |
| ------------------------------------------------------------ | ------------------------------------------------ |
| [continue 语句](https://www.runoob.com/go/go-continue-statement.html) | 跳过当前循环的剩余语句,然后继续进行下一轮循环。 |
| [goto 语句](https://www.runoob.com/go/go-goto-statement.html) | 将控制转移到被标记的语句。 |
#### goto:它通常只出现在**底层框架、状态机**或者**需要极其高效地退出深层嵌套**的情况下。
例子:在多维数组中找一个数字,找到了就立刻停止所有循环
```go
package main
import "fmt"
func main() {
target := 5
matrix := [][]int{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9},
}
for i := 0; i < len(matrix); i++ {
for j := 0; j < len(matrix[i]); j++ {
if matrix[i][j] == target {
// 发现了目标,直接“瞬移”到循环外面
goto Found
}
}
}
fmt.Println("没找到...")
return // 如果没找到,执行完这里就退出了
Found:
fmt.Printf("找到了!目标 %d 在矩阵中。\n", target)
}
```
### 数组
初始化数组
```go
var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
balance := [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
```
### 指针
格式:
```
var var_name *var-type
```
例子:
```go
package main
import "fmt"
func main() {
var a int= 20 /* 声明实际变量 */
var ip *int /* 声明指针变量 */
ip = &a /* 指针变量的存储地址 */
fmt.Printf("a 变量的地址是: %x\n", &a )
/* 指针变量的存储地址 */
fmt.Printf("ip 变量储存的指针地址: %x\n", ip )
/* 使用指针访问值 */
fmt.Printf("*ip 变量的值: %d\n", *ip )
}
```
### Go 语言指针作为函数参数
```go
package main
import "fmt"
func main() {
/* 定义局部变量 */
var a int = 100
var b int= 200
fmt.Printf("交换前 a 的值 : %d\n", a )
fmt.Printf("交换前 b 的值 : %d\n", b )
/* 调用函数用于交换值
* &a 指向 a 变量的地址
* &b 指向 b 变量的地址
*/
swap(&a, &b);
fmt.Printf("交换后 a 的值 : %d\n", a )
fmt.Printf("交换后 b 的值 : %d\n", b )
}
func swap(x *int, y *int) {
var temp int
temp = *x /* 保存 x 地址的值 */
*x = *y /* 将 y 赋值给 x */
*y = temp /* 将 temp 赋值给 y */
}
```
### 结构体
结构体定义需要使用 type 和 struct 语句。struct 语句定义一个新的数据类型,结构体中有一个或多个成员。type 语句设定了结构体的名称。结构体的格式如下:
```go
type struct_variable_type struct {
member definition
member definition
...
member definition
}
```
# homily link学习:ai雷达
1. AI雷达的核心定位与功能
• AI雷达的核心定位是“跨越空间透视未来”,通过降维打击实现空间跨越。
• 天地双轨系统是天轨(蓝色线)与地轨(下方线)构成的股价空间测算模型,地轨支撑位决定反弹机会。
• 股价触及地轨可能触发反弹,但持续上涨需满足天轨突破且地轨同步上移的条件。
• 空间测算强调“无空间无利润”,股价突破天轨时若地轨已拐头向上,则可能加速上涨。
2. 天地双轨系统的实战应用
• 反弹有效性验证:股价首次反弹至天轨但地轨未动时,通常难以持续上涨。
• 三级机会判定:一级机会(反弹未破天轨)、二级机会(突破天轨且地轨启动)、三级机会(天眼雷达信号+地轨强力支撑)。
• 前兆信号识别:股价下跌至地轨前,下方异动(如地轨提前上拐)提示潜在反转机会。
• 空间极值测算:天地双轨间距对应利润空间,股价触及预警线(如天线凹口)提示风险。
3. 透视未来的三大操作流程
• 探测阶段:通过前兆信号(如地轨异动)发现潜在机会,区分一级至三级机会强度。
• 扫射阶段:雷达方向指示力度(向右为弱、向左为强),三级天眼雷达信号预示暴涨。
• 预警阶段:天线系统在股价高位形成凹口预警,跌破天轨确认趋势终结。
4. AI雷达的差异化价值
• 空间视角独特性:区别于传统技术分析,专注空间维度测算与高维趋势预判。
• 全周期覆盖:从地轨支撑探测到天轨突破扫射,最终通过天线预警完成闭环。
• 2025年应用前景:针对市场不确定性,提供跨越空间层级的预判解决方案。

137
李柏霖学习笔记/4.1.md

@ -0,0 +1,137 @@
# goframe
```
s.BindHandler("/say", hello.SayHello)
```
默认method是all
```
s.BindHandler("GET:/say", hello.SayHello)
```
将请求方式变味了get
bindObject:批量绑定方法
例:
```
func (s *Server) BindObject(pattern string, object interface{}, method ...string)
```
method ...string指定绑定的方法,不指定全都有;
BindObjectMethod:只能绑定一个方法;需要特殊路径,或一个 Controller 只想暴露少量接口时。
```
func (s *Server) BindObjectMethod(pattern string, object interface{}, method string)
```
BindObjectRest:只能绑定指定的方法名如:GET POST DELECT 只能匹配动词的方法;纯粹的资源操作(CRUD),符合标准 REST 规范。最常用的get,post
## 规范路由
GoFrame中提供了规范化的路由注册方式,注册方法如下
```
func Handler(ctx context.Context, req *Request) (res *Response, err error)
```
其中`Request`与`Response`为自定义的结构体。
通过如下方式指定请求方法与路径
```go
type HelloReq struct {
g.Meta `path:"/hello" method:"get"`
}
```
api内一般定义请求和响应的结构体的
```go
func (c *Hello) Params(ctx context.Context, req *hello.ParamsReq) (res *hello.ParamsRes, error error) {
r := g.RequestFromCtx(ctx)
name := r.GetQuery("name")
r.Response.WriteJson(name)
return
}
```
name位置是一个var的泛型
getquery第二个参数是个默认值;
| **方法名** | **返回类型** | **核心优势** | **Java 类比** |
| --------------------- | ------------------------ | -------------------------- | ------------------- |
| **GetQuery** | `*gvar.Var` | 链式转换类型极方便 | `getParameter()` |
| **GetQueryMap** | `map[string]interface{}` | 快速获取全部原始数据 | `getParameterMap()` |
| **GetQueryStruct** | `error` | **全自动绑定,代码最优雅** | **DTO 自动注入** |
| **GetQueryMapStrStr** | `map[string]string` | 类型统一,无需转型 | - |
用GetQueryMap来
```go
func (c *Hello) Params(ctx context.Context, req *hello.ParamsReq) (res *hello.ParamsRes, error error) {
r := g.RequestFromCtx(ctx)
data := r.GetQueryMap(map[string]interface{}{"name": "lisi", "age": "20"})
r.Response.Writeln(data)
return
}
```
## goframe的动态路由
主要写在g.Meta的path标签里
| **占位符格式** | **名称** | **匹配规则** | **示例** |
| --------------- | -------------- | --------------------------------- | ------------------------------------ |
| **`:name`** | **命名占位符** | 匹配两个 `/` 之间的内容(最常用) | `/user/:id` 匹配 `/user/123` |
| **`\*any`** | **模糊占位符** | 匹配从当前位置开始的所有后续内容 | `/file/*path` 匹配 `/file/img/a.png` |
| **`{pattern}`** | **正则占位符** | 使用正则表达式进行精确匹配 | `/user/{[0-9]+}` 只匹配数字 ID |
api
```
package api
import (
"github.com/gogf/gf/v2/frame/g"
)
type Res struct {
g.Meta `mime:"text/html"`
}
type ParamReq struct {
g.Meta `path:"/params/:name" method:"all"`
}
```
# homily link的ai预测大模型
1. AI预测大模型功能与特点
• 模型包含六个关键价格:买回价、卖出价、两个预测低点与两个预测高点。
• 采用深度学习算法分析历史数据,实时调整策略以捕捉市场趋势变化。
• 处理流程分为数据预处理、模型构建和数据分析决策三个阶段。
• 已从8月2日开始实际体验,用户可测试其预测功能。
2. 实际预测案例验证
• 英伟达案例显示7月31日预测的8月1日高低点与实际价格误差约0.2%-1%。
• 苹果案例中8月6日预测的次日高点214.81与实际213.64相差1.17美元。
• 通过计算预测价格中值并与当日收盘价对比,可预判次日涨跌方向。
3. 核心使用场景与方法
• 涨跌预判:用前日预测高低点均值对比当日收盘价,高于中值则预判次日上涨。
• 日内交易:依据模型提供的买回价、卖出价在日内进行低吸高抛操作。
• 上涨趋势中参考买回价寻找低吸机会,下跌趋势中按卖出价或预测高点挂单。
4. 模型应用原则与局限性
• 预测结果需结合趋势判断使用,如先确认涨跌概率再执行交易策略。
• 明确告知所有预测存在误差,核心价值在于提供量化参考依据。
• 强调通过AI技术辅助交易决策,但需保持对市场动态的独立判断。

232
李柏霖学习笔记/4.2.md

@ -0,0 +1,232 @@
## api路由
```
type ParamReq struct {
g.Meta `path:"/params" method:"post"`
UserName string `p:"name" d:"林冲"`
UserAge int `p:"age" d:"110"`
}
```
p为param,能根据标签把username对应上,p为简写,d为设置默认值
## 相应参数
## 数据库
查询数据
```go
md := g.Model("book")
bk, err := md.One()
if err == nil {
req.Response.WriteJson(bk)
}
```
调用one这个方法返回的类型本质上是一个map类型,用writeln时可以访问其中某一个字段,是泛型
## 切片:
| **特性** | **Java 数组** | **Go 数组** | **Go 切片 (Slice)** |
| ---------------------- | ------------- | ------------------------- | -------------------------- |
| **长度** | 固定 | 固定 | **动态可变** |
| **类型定义** | `int[]` | `[3]int` (长度必写) | `[]int` (不写长度) |
| **值传递 vs 引用传递** | 引用传递 | **值传递 (拷贝整个数组)** | **引用传递 (拷贝 Header)** |
| **扩容** | 不支持 | 不支持 | 使用 `append()` 自动扩容 |
go中主要用到的是切片,忘掉 Go 的数组,把 **Slice(切片)** 当作 **ArrayList** 来用,记得增加元素要用 `nums = append(nums, val)`
## model
```go
func (c *Hello) DB(req *ghttp.Request) {
md := g.Model("book")
books, err := md.All()
if err == nil {
req.Response.WriteJson(books)
}
}
```
这行代码的作用是:
创建数据库表模型
"book" 对应数据库中的表名 book
md 是一个 *gdb.Model 对象,代表对 book 表的操作句柄
Model 的优势
✅ 链式调用:可以流畅地组合多个操作
✅ 类型安全:编译时检查错误
✅ 自动映射:数据库记录自动映射到 Go 结构体
✅ 防止 SQL 注入:参数化查询
model相当于一个sql语句的调用
## Where/Where*/WhereOr/WhereOr*
查询数据时可以通过`Where`方法指定条件,如果有多个`Where`,则多个条件之间会用`AND`连接
**等于**
默认情况下条件会用=连接
```
md := g.Model("book")
books, err := md.Where("id", 1).All()
```
**不等**
如果是不等关系,需要在字段后面加上不等符号
```
md := g.Model("book")
books, err := md.Where("id>", 1).All()
```
**多个条件叠加**
有多个条件时可以多个`Where`进行链式调用,条件会用`AND`连接。
```
md := g.Model("book")
books, err := md.Where("id>=?", 2).Where("id<?", 4).All()
```
**Where系列方法**
| 方法 | 生成的SQL条件表达式 |
| ------------------------------------ | ------------------------------------------------- |
| WhereLT(column, value) | column < value |
| WhereLTE(column, value) | column <= value |
| WhereGT(column, value) | column > value |
| WhereGTE(column, value) | column >= value |
| WhereBetween(column, min, max) | column BETWEEN min AND max |
| WhereNotBetween(column, min, max) | column NOT BETWEEN min AND max |
| WhereLike(column, like) | column LIKE like |
| WhereIn(column, in) | column IN (in) |
| WhereNotIn(column, in) | column NOT IN (in) |
| WhereNot(column, value) | column != value |
| WhereNull(columns1, columns2... ) | columns1 IS NULL AND columns2 IS NULL... |
| WhereNotNull(columns1, columns2... ) | columns1 IS NOT NULL AND columns2 IS NOT NULL ... |
| | |
| | |
使用示例:
```
md := g.Model("book")
books, err := md.WhereIn("id", g.Array{1, 2, 3}).WhereLike("name", "%数据%").All()
// 生成如下SQL
// SELECT * FROM `book` WHERE (`id` IN (1,2,3)) AND (`name` LIKE '%数据%')
```
以上方法如果链式调用会生成以`AND`连接的条件,如果需要生成以`OR`连接的条件,则需要用到下列方法:
**WhereOr系列方法**
| 方法 | 生成的SQL条件表达式 |
| -------------------------------------- | ------------------------------------------------------ |
| WhereOrLT(column, value) | OR (column < value) |
| WhereOrLTE(column, value) | OR (column <= value) |
| WhereOrGT(column, value) | OR (column > value) |
| WhereOrGTE(column, value) | OR (column >= value) |
| WhereOrBetween(column, min, max) | OR (column BETWEEN min AND max) |
| WhereOrNotBetween(column, min, max) | OR (column NOT BETWEEN min AND max) |
| WhereOrLike(column, like) | OR (column LIKE like) |
| WhereOrIn(column, in) | OR (column IN (in)) |
| WhereOrNotIn(column, in) | OR (column NOT IN (in)) |
| WhereOrNot(column, value) | OR (column != value) |
| WhereOrNull(columns1, columns2... ) | OR (columns1 IS NULL AND columns2 IS NULL...) |
| WhereOrNotNull(columns1, columns2... ) | OR (columns1 IS NOT NULL AND columns2 IS NOT NULL ...) |
| WhereOr(column, value) | OR (column = value) |
| | |
示例:
```go
md := g.Model("book")
books, err := md.WhereIn("id", g.Array{1, 2, 3}).WhereOrLike("name", "%数据%").All()
// 生成如下SQL
// SELECT * FROM `book` WHERE (`id` IN (1,2,3)) OR (`name` LIKE '%数据%')
```
数据分页用page
## Scan
`One`和`All`返回的数据为`Map`或者`Map`切片,在实际使用当中查询到的数据可能需要转换为特定的数据结构方便使用,scan返回值只需要一个err。
如果对应不上数据库表,可以用‘orm:”id“’来保证与后端查询的到
```go
type Book struct {
BookId uint `orm:"id" `
BookName string `orm:"name"`
BookAuthor string `orm:"author"`
BookPrice float64 `orm:"price"`
PubTime *gtime.Time `orm:"publish_time"`
}
```
## 插入数据
| 方法 | 主键在数据库中已存在时 |
| ------- | ---------------------------------- |
| Insert | 报错,主键冲突 |
| Repalce | 用提供的数据替换已存在同主键的数据 |
| Save | 用提供的数据更新已存在的同主键数据 |
返回一个result和err来接收;
g.list是一个存map类型的切片
## 数据更新:
注意:自减 操作 如果 自减后的值小于0 数据不会更新
Update 方法如何实现只更新非空字段
更新非空字段 在Update之前添加OmitEmpty
## 软删除
**软删除**
> 软删除并不是真正从数据库中把记录删除,而是通过特定的标记在查询时过滤掉这些数据,使这些数据在页面上看不到,但实际上在数据库中仍然存在。通常用于一些需要历史追踪而不能真正删除的数据。
当数据表中有`deleted_at`字段时,使用`Delete`方法时不会物理删除数据,只是更新`deleted_at`字段的值。查询数据时,会自动加上WHERE `deleted_at` IS NULL这一条件,过滤掉已被“删除”的数据。
如果需要查询所有数据,需要使用`Unscoped`方法
```
ls, _ := md.Unscoped().All()
```
只用用model调用的时候才会总动生成,用sql不行。
## 关联查询
- 使用`With`指定需要关联的内容
# homily link 天外飞仙,双龙出海
1. 天外飞仙技术要点
该方法的核心在于识别股价突破天线的变盘点。股价上涨前需出现"红盖头"现象,即买盘力量完全压制前期波动。 白色线上穿代表多空博弈出现转折,是重要买入信号。 股价必须突破天线并保持在天线外才可持续上涨。当股价被天线重新覆盖时,意味着风险将至。
2. 双龙出海技术要点 • 该方法通过黄色变局线判断股价启动时机。30分钟线出现全红买盘信号时,往往预示暴力拉升。 需要结合多空博弈指标判断买卖力量对比。股价变局的K线是重要转折标志。 若股价始终在天线内运行,则属于弱势形态。
3. 实际案例分析以特斯拉、英伟达等股票为例展示了技术方法的实际应用。腾讯案例特别强调了波动空间和买卖力量的重要性。 苹果案例演示了30分钟线的变局信号识别。 通过对比强弱形态说明交易时机的选择标准。强调智能化工具在研判股价强弱时的辅助作用。

43
李柏霖学习笔记/4.3.md

@ -0,0 +1,43 @@
# 复习
依赖注入方面,`@Autowired` 是用得最多的,可以标注在字段、setter 方法或者构造方法上。`@Qualifier` 在有多个同类型 Bean 的时候用来指定具体注入哪一个。`@Resource` 和 `@Autowired` 功能差不多,不过它是按名称注入的。
配置相关的注解也很常用。`@Configuration` 标识配置类,`@Bean` 用来定义 Bean,`@Value` 用来注入配置文件中的属性值。我们项目里的数据库连接信息、Redis 配置这些都是用 `@Value` 来注入的。`@PropertySource` 用来指定配置文件的位置。
单例模式也是 Spring 的默认行为。默认情况下,Spring 容器中的 Bean 都是单例的,整个应用中只会有一个实例。这样可以节省内存,提高性能。可以通过 `@Scope` 注解来改变 Bean 的作用域,比如设置为 prototype 就是每次获取都创建新实例。
![二哥的 Java 进阶之路:@Scope注解](https://cdn.paicoding.com/stutymore/spring-20250618113356.png)
#### Spring如何实现单例模式
传统的单例模式是在类的内部控制只能创建一个实例,比如用 private 构造方法加 `static getInstance()` 这种方式。但是 Spring 的单例是容器级别的,同一个 Bean 在整个 Spring 容器中只会有一个实例。
具体的实现机制是这样的:Spring 在启动的时候会把所有的 Bean 定义信息加载进来,然后在 DefaultSingletonBeanRegistry 这个类里面维护了一个叫 singletonObjects 的 ConcurrentHashMap,这个 Map 就是用来存储单例 Bean 的。key 是 Bean 的名称,value 就是 Bean 的实例对象。
当我们第一次获取某个 Bean 的时候,Spring 会先检查 singletonObjects 这个 Map 里面有没有这个 Bean,如果没有就会创建一个新的实例,然后放到 Map 里面。后面再获取同一个 Bean 的时候,直接从 Map 里面取就行了,这样就保证了单例。
还有一个细节就是 Spring 为了解决循环依赖的问题,还用了三级缓存。除了 singletonObjects 这个一级缓存,还有 earlySingletonObjects 二级缓存和 singletonFactories 三级缓存。这样即使有循环依赖,Spring 也能正确处理。
而且 Spring 的单例是线程安全的,因为用的是 ConcurrentHashMap,多线程访问不会有问题。
#### bean
Bean 本质上就是由 Spring 容器管理的 Java 对象,但它和普通的 Java 对象有很大区别。普通的 Java 对象我们是通过 new 关键字创建的。而 Bean 是交给 Spring 容器来管理的,从创建到销毁都由容器负责。
从实际使用的角度来说,我们项目里的 Service、Dao、Controller 这些都是 Bean。比如 UserService 被标注了 `@Service` 注解,它就成了一个 Bean,Spring 会自动创建它的实例,管理它的依赖关系,当其他地方需要用到 UserService 的时候,Spring 就会把这个实例注入进去。
`@Primary` 注解标注主数据源,用 `@Qualifier` 来指定备用数据源。
当我们直接用 `@Autowired` 注解注入 DataSource 时,Spring 默认会使用 HikariDataSource;当加上 `@Qualifier("secondary")` 注解时,Spring 则会注入 BasicDataSource。
#### @Component@Bean 有什么区别?
首先从使用上来说,`@Component` 是标注在类上的,而 `@Bean` 是标注在方法上的。`@Component` 告诉 Spring 这个类是一个组件,请把它注册为 Bean,而 `@Bean` 则告诉 Spring 请将这个方法返回的对象注册为 Bean。

302
李柏霖学习笔记/4.4.md

@ -0,0 +1,302 @@
练手项目:java地牢
dungeon-boot/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/dungeon/
│ │ │ ├── DungeonApplication.java // 项目启动类
│ │ │ ├── common/ // 公共配置与工具
│ │ │ │ ├── config/ // MyBatis-Plus/Redis 配置
│ │ │ │ ├── exception/ // 自定义异常(如:玩家死亡异常)
│ │ │ │ └── result/ // 统一接口返回对象 (Result<T>)
│ │ │ ├── controller/ // API 控制层 (与前端交互)
│ │ │ │ ├── PlayerController.java
│ │ │ │ └── GameController.java
│ │ │ ├── entity/ // 数据库映射实体 (POJO)
│ │ │ │ ├── Player.java
│ │ │ │ ├── Room.java
│ │ │ │ └── Monster.java
│ │ │ ├── mapper/ // MyBatis-Plus Mapper 接口
│ │ │ │ ├── PlayerMapper.java
│ │ │ │ └── RoomMapper.java
│ │ │ └── service/ // 核心业务逻辑层
│ │ │ ├── PlayerService.java // 玩家属性、升级逻辑
│ │ │ ├── MapService.java // 移动、房间探索逻辑
│ │ │ └── BattleService.java // 战斗计算逻辑
│ │ └── resources/
│ │ ├── application.yml // 数据库连接与游戏全局配置
│ └── test/ // 单元测试
└── pom.xml // 项目依赖管理
controller
```java
package com.example.demo01.controller;
import com.example.demo01.common.result.Result;
import com.example.demo01.entity.Player;
import com.example.demo01.entity.Room;
import com.example.demo01.service.BattleService;
import com.example.demo01.service.MapService;
import com.example.demo01.service.PlayerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/game")
public class GameController {
@Autowired
private PlayerService playerService;
@Autowired
private MapService mapService;
@Autowired
private BattleService battleService;
@PostMapping("/move")
public Result<Room> move(@RequestBody MoveRequest request) {
// 1. 获取玩家信息
Player player = playerService.getPlayerStatus(request.getPlayerId());
if (player == null) return Result.error("玩家不存在");
// 2. 调用地图服务判断是否可以移动
Room nextRoom = mapService.move(player.getCurrentRoomId(), request.getDirection());
if (nextRoom != null) {
// 3. 移动成功,更新玩家所在的房间ID
playerService.moveToRoom(player.getId(), nextRoom.getId());
// 返回新房间的信息,让前端显示描述文字
return Result.success(nextRoom);
} else {
return Result.error("哎呀!你撞到了墙上,那里没有路。");
}
}
@PostMapping("/attack")
public Result<BattleResult> doAttack(@RequestParam Long playerId, @RequestParam Long monsterId) {
BattleResult result = battleService.attack(playerId, monsterId);
return Result.success(result);
}
}
```
```
@Data
public class MoveRequest {
/**
* 正在操作的玩家 ID
*/
private Long playerId;
/**
* 移动方向:north, south, east, west
*/
private String direction;
}
```
```
@RestController
@RequestMapping("/api/player")
public class PlayerController {
@Autowired
private PlayerService playerService;
// 获取玩家当前面板状态:GET /api/player/status?id=1
@GetMapping("/status")
public Result<Player> getStatus(@RequestParam Long id) {
Player player = playerService.getPlayerStatus(id);
if (player == null) {
return Result.error("未找到该角色");
}
return Result.success(player);
}
}
```
service
```
package com.example.demo01.service.impl;
import com.example.demo01.controller.BattleResult;
import com.example.demo01.entity.Monster;
import com.example.demo01.entity.Player;
import com.example.demo01.mapper.MonsterMapper;
import com.example.demo01.mapper.PlayerMapper;
import com.example.demo01.service.BattleService;
import com.example.demo01.service.PlayerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class BattleServiceImpl implements BattleService {
@Autowired
private PlayerMapper playerMapper;
@Autowired
private MonsterMapper monsterMapper;
@Autowired
private PlayerService playerService;
@Override
@Transactional
public BattleResult attack(Long playerId, Long monsterId) {
Player player = playerMapper.selectById(playerId);
Monster monster = monsterMapper.selectById(monsterId);
StringBuilder log = new StringBuilder();
// 1. 玩家攻击怪物
// 伤害公式:攻击力 - 防御力(最小为1)
int damageToMonster = Math.max(1, player.getAtk() - monster.getDef());
monster.setHp(Math.max(0, monster.getHp() - damageToMonster));
log.append(String.format("你攻击了 %s,造成了 %d 点伤害。 ", monster.getName(), damageToMonster));
// 2. 检查怪物是否死亡
if (!monster.isAlive()) {
log.append(String.format("%s 倒下了!你获得了 %d 经验。", monster.getName(), monster.getExpReward()));
// 结算奖励
playerService.addRewards(playerId, monster.getExpReward(), monster.getGoldReward());
// 从房间移除怪物(可选逻辑:更新Room表或者标记Monster已死)
monsterMapper.deleteById(monsterId);
return BattleResult.builder()
.log(log.toString()).monsterHp(0).playerHp(player.getHp())
.monsterDead(true).rewardsExp(monster.getExpReward()).build();
}
// 3. 怪物反击(如果还没死)
int damageToPlayer = Math.max(1, monster.getAtk() - 5); // 假设玩家基础防御5
player.setHp(Math.max(0, player.getHp() - damageToPlayer));
playerMapper.updateById(player); // 更新玩家血量
monsterMapper.updateById(monster); // 更新怪物血量
log.append(String.format("%s 发起反击,你受到了 %d 点伤害。", monster.getName(), damageToPlayer));
return BattleResult.builder()
.log(log.toString())
.playerHp(player.getHp())
.monsterHp(monster.getHp())
.playerDead(player.getHp() <= 0)
.build();
}
}
```
```
package com.example.demo01.service.impl;
import com.example.demo01.entity.Room;
import com.example.demo01.mapper.RoomMapper;
import com.example.demo01.service.MapService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class MapServiceImpl implements MapService {
@Autowired
private RoomMapper roomMapper;
@Override
public Room move(Long currentRoomId, String direction) {
// 1. 先找到玩家所在的当前房间
Room currentRoom = roomMapper.selectById(currentRoomId);
if (currentRoom == null) return null;
// 2. 根据方向获取目标房间的 ID
Long nextRoomId = null;
switch (direction.toLowerCase()) {
case "north": nextRoomId = currentRoom.getNorthRoomId(); break;
case "south": nextRoomId = currentRoom.getSouthRoomId(); break;
case "east": nextRoomId = currentRoom.getEastRoomId(); break;
case "west": nextRoomId = currentRoom.getWestRoomId(); break;
}
// 3. 如果 ID 为空,说明那边是墙
if (nextRoomId == null) return null;
// 4. 返回目标房间的完整信息
return roomMapper.selectById(nextRoomId);
}
@Override
public Room getRoomById(Long roomId) {
return roomMapper.selectById(roomId);
}
}
```
```
package com.example.demo01.service.impl;
import com.example.demo01.entity.Player;
import com.example.demo01.mapper.PlayerMapper;
import com.example.demo01.service.PlayerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class PlayerServiceImpl implements PlayerService {
@Autowired
private PlayerMapper playerMapper;
@Override
public Player getPlayerStatus(Long playerId) {
return playerMapper.selectById(playerId);
}
@Override
@Transactional // 涉及数据库修改,建议开启事务
public boolean moveToRoom(Long playerId, Long newRoomId) {
Player player = playerMapper.selectById(playerId);
if (player == null) return false;
player.setCurrentRoomId(newRoomId);
return playerMapper.updateById(player) > 0;
}
@Override
public void takeDamage(Long playerId, Integer damage) {
Player player = playerMapper.selectById(playerId);
if (player != null) {
// 计算扣血后的 HP,确保不小于 0
int newHp = Math.max(0, player.getHp() - damage);
player.setHp(newHp);
playerMapper.updateById(player);
if (newHp == 0) {
// 这里可以触发死亡逻辑,比如清空存档或传回出生点
System.out.println("玩家 " + player.getName() + " 已阵亡!");
}
}
}
@Override
public void addRewards(Long playerId, Integer exp, Integer gold) {
Player player = playerMapper.selectById(playerId);
if (player != null) {
player.setExp(player.getExp() + exp);
// 简单的升级逻辑:每 100 经验升一级
if (player.getExp() >= player.getLevel() * 100) {
player.setLevel(player.getLevel() + 1);
player.setAtk(player.getAtk() + 5); // 升级加攻击
player.setHp(player.getMaxHp()); // 升级回满血
}
playerMapper.updateById(player);
}
}
}
```

BIN
李柏霖学习笔记/4.7后端项目demo.7z

BIN
李柏霖学习笔记/images/021099bd151272c630107ed552ab7af2.png

After

Width: 501  |  Height: 381  |  Size: 85 KiB

BIN
李柏霖学习笔记/images/QQ20260330-143952.png

After

Width: 838  |  Height: 645  |  Size: 202 KiB

BIN
李柏霖学习笔记/images/image-20260328093542705.png

After

Width: 1252  |  Height: 593  |  Size: 171 KiB

BIN
李柏霖学习笔记/images/image-20260328093613551.png

After

Width: 1239  |  Height: 595  |  Size: 175 KiB

BIN
李柏霖学习笔记/images/image-20260328112106933.png

After

Width: 739  |  Height: 454  |  Size: 134 KiB

BIN
李柏霖学习笔记/images/image-20260328135132711.png

After

Width: 921  |  Height: 635  |  Size: 304 KiB

BIN
李柏霖学习笔记/images/image-20260328135416809.png

After

Width: 517  |  Height: 406  |  Size: 104 KiB

BIN
李柏霖学习笔记/朝闻道4.7总计.doc

BIN
李柏霖学习笔记/第二天.docx

Loading…
Cancel
Save