楼主: dlmxv90851
1370 0

JavaScript玩转机器学习-Tensorflow.js项目实战内附文档源码 [推广有奖]

  • 0关注
  • 0粉丝

硕士生

96%

还不是VIP/贵宾

-

威望
0
论坛币
266 个
通用积分
55.0568
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
1668 点
帖子
98
精华
0
在线时间
69 小时
注册时间
2020-4-17
最后登录
2024-9-19

楼主
dlmxv90851 发表于 2022-8-16 20:19:14 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
JavaScript玩转机器学习-Tensorflow.js项目实战内附文档源码
download链接:https://pan.baidu.com/s/1YSajArsbYdOBq2FY47fcqQ?pwd=o4y1
提取码:o4y1
--来自百度网盘超级会员V5的分享
Java 诊断工具 Arthas-实操案例
实操案例
排查函数调用异常
经过curl 恳求接口只能看到返回异常,但是看不到详细的恳求参数和堆栈信息。
shell@Alicloud:~$ curl
{"timestamp":1655435063042,"status":500,"error":"Internal Server Error","exception":"java.lang.IllegalArgumentException","message":"id < 1","path":"/user/0"}
复制代码
查看UserController的 参数/异常
在Arthas里执行:
watch com.example.demo.arthas.user.UserController * '{params, throwExp}'
复制代码

第一个参数是类名,支持通配
第二个参数是函数名,支持通配 访问watch命令会打印调用的参数和异常
再次经过curl 调用能够在arthas里面查看到详细的异常信息。
把获取到的结果展开,能够用-x参数:
watch com.example.demo.arthas.user.UserController * '{params, throwExp}' -x 2
复制代码
返回值表达式
在上面的例子里,第三个参数是返回值表达式,它实践上是一个ognl表达式,它支持一些内置对象:

loader
clazz
method
target
params
returnObj
throwExp
isBefore
isThrow
isReturn

比方返回一个数组:
watch com.example.demo.arthas.user.UserController * '{params[0], target, returnObj}'
复制代码
条件表达式
watch命令支持在第4个参数里写条件表达式,比方:
当访问 user/1 时,watch命令没有输出
当访问 user/101 时,watch会打印出结果。

当异常时捕获
watch命令支持-e选项,表示只捕获抛出异常时的恳求:
watch com.example.demo.arthas.user.UserController * "{params[0],throwExp}" -e
复制代码
依照耗时停止过滤
watch命令支持按恳求耗时停止过滤,比方:
watch com.example.demo.arthas.user.UserController * '{params, returnObj}' '#cost>200'
复制代码
热更新代码
这个也是真的秀。

访问 http://localhost:61000/user/0 ,会返回500异常:
shell@Alicloud:~$ curl http://localhost:61000/user/0
{"timestamp":1655436218020,"status":500,"error":"Internal Server Error","exception":"java.lang.IllegalArgumentException","message":"id < 1","path":"/user/0"}
复制代码
经过热更新代码,修正这个逻辑。
jad反编译UserController
jad --source-only com.example.demo.arthas.user.UserController > /tmp/UserController.java
复制代码
jad反编译的结果保管在 /tmp/UserController.java文件里了。
再翻开一个Terminal 窗口,然后用vim来编辑/tmp/UserController.java:
vim /tmp/UserController.java
复制代码
比方当 user id 小于1时,也正常返回,不抛出异常:
@GetMapping(value={"/user/{id}"})
public User findUserById(@PathVariable Integer id) {
    logger.info("id: {}", (Object)id);
    if (id != null && id < 1) {
        return new User(id, "name" + id);
        // throw new IllegalArgumentException("id < 1");
    }
    return new User(id.intValue(), "name" + id);
    }
复制代码
sc查找加载UserController的ClassLoader
[arthas@1266]$ sc -d *UserController | grep classLoaderHash
classLoaderHash   19469ea2
复制代码
classLoaderHash 是19469ea2,后面需求运用它。
mc
保管好/tmp/UserController.java之后,运用mc(Memory Compiler)命令来编译,并且经过-c或者--classLoaderClass参数指定ClassLoader:

mc --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader /tmp/UserController.java -d /tmp

[arthas@1266]$ mc --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader /tmp/UserController.java -d /tmp
Memory compiler output:
/tmp/com/example/demo/arthas/user/UserController.class
Affect(row-cnt:1) cost in 2879 ms.
复制代码
也能够经过mc -c  /tmp/UserController.java -d /tmp,运用-c参数指定ClassLoaderHash:
mc -c 19469ea2 /tmp/UserController.java -d /tmp
复制代码
redefine
再运用redefine命令重新加载新编译好的UserController.class:
[arthas@1266]$ redefine /tmp/com/example/demo/arthas/user/UserController.class
redefine success, size: 1, classes:
com.example.demo.arthas.user.UserController
复制代码
热修正代码结果
redefine胜利之后,再次访问 user/0 ,结果正常
shell@Alicloud:~$ curl http://localhost:61000/user/0
{"id":0,"name":"name0"}
复制代码
动态更新应用Logger Level
查找UserController的ClassLoader
[arthas@1266]$ sc -d *UserController | grep classLoaderHash
classLoaderHash   19469ea2
复制代码
用ognl获取logger

ognl --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader '@com.example.demo.arthas.user.UserController@logger'

[arthas@1266]$ ognl --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader '@com.example.demo.arthas.user.UserController@logger'
@Logger[
    serialVersionUID=@Long[5454405123156820674],
    FQCN=@String[ch.qos.logback.classic.Logger],
    name=@String[com.example.demo.arthas.user.UserController],
    level=null,
    effectiveLevelInt=@Integer[20000],
    parent=@Logger[Logger[com.example.demo.arthas.user]],
    childrenList=null,
    aai=null,
    additive=@Boolean[true],
    loggerContext=@LoggerContext[ch.qos.logback.classic.LoggerContext[default]],
]
复制代码
能够晓得UserController@logger实践运用的是logback。能够看到level=null,则阐明实践最终的level是从root logger里来的。
单独设置UserController的logger level
ognl --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader '@com.example.demo.arthas.user.UserController@logger.setLevel(@ch.qos.logback.classic.Level@DEBUG)'
复制代码
再次获取UserController@logger,能够发现曾经是DEBUG了。
修正logback的全局logger level
经过获取root logger,能够修正全局的logger level:
ognl --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader '@org.slf4j.LoggerFactory@getLogger("root").setLevel(@ch.qos.logback.classic.Level@DEBUG)'
复制代码
获取Spring Context,在获取 bean,再调用函数

运用tt命令获取到spring context
tt即 TimeTunnel,它能够记载下指定办法每次调用的入参和返回信息,并能对这些不同的时间下调用停止观测

tt -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod
复制代码
访问user/1,
curl http://localhost:61000/user/1
复制代码
能够看到tt命令捕获到了一个恳求:

输入 q 或者 Ctrl + C 退出上面的 tt -t命令。
运用tt命令从调用记载里获取到spring context
tt -i 1000 -w 'target.getApplicationContext()'
复制代码
获取spring bean,并调用函数

tt -i 1000 -w 'target.getApplicationContext().getBean("helloWorldService").getHelloMessage()'

结果如下:
[arthas@1266]$ tt -i 1000 -w 'target.getApplicationContext().getBean("helloWorldService").getHelloMessage()'
@String[Hello World]
Affect(row-cnt:1) cost in 1 ms.
复制代码
排查HTTP恳求返回401
恳求接口没有权限的时分普通就返回401 Unauthorized。
401通常是被权限管理的Filter拦截了,那么到底是哪个Filter处置了这个恳求,返回了401?
跟踪一切的Filter函数
开端trace:
trace javax.servlet.Filter *
复制代码
能够在调用树的最深层,找到AdminFilterConfig$AdminFilter返回了401
+---[3.806273ms] javax.servlet.FilterChain:doFilter()
|   `---[3.447472ms] com.example.demo.arthas.AdminFilterConfig$AdminFilter:doFilter()
|       `---[0.17259ms] javax.servlet.http.HttpServletResponse:sendError()
复制代码
经过stack获取调用栈
上面是经过trace命令来获取信息,从结果里,我们能够晓得经过stack跟踪HttpServletResponse:sendError(),同样能够晓得是哪个Filter返回了401
执行:
stack javax.servlet.http.HttpServletResponse sendError 'params[0]==401'

查找Top N线程
查看一切线程信息
thread
复制代码
查看详细线程的栈
查看线程ID 2的栈:
thread 2
复制代码
查看CPU运用率top n线程的栈
thread -n 3
复制代码
查看5秒内的CPU运用率top n线程栈
thread -n 3 -i 5000
复制代码
查找线程能否有阻塞
thread -b


二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:Javascript Tensor script scrip flow
相关内容:Java项目实战

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群
GMT+8, 2026-2-6 22:14