https://users.cs.fiu.edu/~downeyt/webdev/Hibernate_Validator_Reference_Guide.htm

https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#section-method-validation-prerequisite-relaxation
https://my.oschina.net/u/4390157/blog/3476201
https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-initbinder

<?xml version="1.0" encoding="UTF-8"?>
<validation-config
xmlns="http://jboss.org/xml/ns/javax/validation/configuration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/configuration validation-configuration-1.0.xsd">
<default-provider>org.hibernate.validator.HibernateValidator</default-provider>

<property name="hibernate.validator.allow_parameter_constraint_override">true</property>
<property name="hibernate.validator.allow_multiple_cascaded_validation_on_result">true</property>
<property name="hibernate.validator.allow_parallel_method_parameter_constraint">true</property>
</validation-config>

ConditionalOnNacosDiscoveryEnabled
@ConditionalOnProperty(value = “spring.cloud.nacos.discovery.enabled”, matchIfMissing = true)
@ConditionalOnProperty(value = “spring.cloud.service-registry.auto-registration.enabled”, matchIfMissing = true)

thread join 实现(java层)

public final void join() throws InterruptedException {
join(0);
}

public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;

if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}

if (millis == 0) {
while (isAlive()) {
//等待唤醒
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}

什么时候被唤醒呢

Threadc++实现


static void ensure_join(JavaThread* thread) {
// We do not need to grap the Threads_lock, since we are operating on ourself.
Handle threadObj(thread, thread->threadObj());
assert(threadObj.not_null(), "java thread object must exist");
ObjectLocker lock(threadObj, thread);
// Ignore pending exception (ThreadDeath), since we are exiting anyway
thread->clear_pending_exception();
// Thread is exiting. So set thread_status field in java.lang.Thread class to TERMINATED.
java_lang_Thread::set_thread_status(threadObj(), java_lang_Thread::TERMINATED);
// Clear the native thread instance - this makes isAlive return false and allows the join()
// to complete once we've done the notify_all below
java_lang_Thread::set_thread(threadObj(), NULL);
//唤醒所有执行了wait方法的线程
lock.notify_all(thread);
// Ignore pending exception (ThreadDeath), since we are exiting anyway
thread->clear_pending_exception();
}

ensure_join在什么时候执行呢

// For any new cleanup additions, please check to see if they need to be applied to
// cleanup_failed_attach_current_thread as well.
void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
//...
// Notify waiters on thread object. This has to be done after exit() is called
// on the thread (if the thread is the last thread in a daemon ThreadGroup the
// group should have the destroyed bit set before waiters are notified).
ensure_join(s)
}

线程执行完毕(退出时)

public class TestVolatile1{
public volatile static int i=0;
/**
* 0 getstatic #2 <online/githuboy/concurrent/TestVolatile1.i>
* 3 iconst_1
* 4 iadd
* 5 putstatic #2 <online/githuboy/concurrent/TestVolatile1.i>
* 8 return
*/
public void add(){
i++;
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
add();
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
add();
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(i);
}
}

i = 10
t1
int temp = i + 1
//ThreadContextSwitch t2
t2
int tmep = i+ 1
i = 11
//write result to main memory

t1
continue execute
reread from temp
write i = 11
sync to main memory

今天访问这个网站查看i7-10700F
查看性能参数,谁知道给我弹出一个密码输入框
p1

然后需要关注公众号,才能获取密码,我开始以为是免费的。结果需要3元RMB.
本着研究的精神,决定看下网站是如何验证的。

F12本以为能打开浏览器调试工具,结果直接弹出一个新的window.

好吧那只能通过菜单栏打开调试工具了。

通过快捷按键无法打开调试工具,说明该网站拦截了keyDown事件.

关键代码如下:

document.onkeydown=function(){
var e = window.event||arguments[0];
if(e.keyCode==123){
window.open('/huoqumima.html?requestname=123', "_blank", "scrollbars=yes,resizable=1,modal=false,alwaysRaised=yes");
return false;
}else if((e.ctrlKey)&&(e.shiftKey)&&(e.keyCode==73)){
window.open('/huoqumima.html?requestname=73', "_blank", "scrollbars=yes,resizable=1,modal=false,alwaysRaised=yes");
return false;
}else if((e.ctrlKey)&&(e.keyCode==85)){
window.open('/huoqumima.html?requestname=85', "_blank", "scrollbars=yes,resizable=1,modal=false,alwaysRaised=yes");
return false;
}else if((e.ctrlKey)&&(e.keyCode==83)){
window.open('/huoqumima.html?requestname=83', "_blank", "scrollbars=yes,resizable=1,modal=false,alwaysRaised=yes");
return false;
}
}

试着删除密码输入框的元素,结果整个网页reload.
逻辑如下
p2

既然不能删除元素,那就加个样式吧display: none;

p3

结果还是模糊的。

审查元素发现加了模糊过滤

p4

基本分析差不多了,就开始写代码吧。

用的油猴脚本管理器

// ==UserScript==
// @name xincanshu crack
// @namespace http://tampermonkey.net/
// @version 0.1
// @description Hidden password login dialog and blur mask,just for personal use
// @author githuboy
// @match *://*.xincanshu.com/*
// @grant GM_log
// @run-at document-body
// ==/UserScript==

(function() {
'use strict';
console.log("script init success");
setTimeout(function(){
var $ = jq;
$(".zheceng").remove();
$("#chart-wrapper").css("filter","blur(0px)");
$(".paofenjietu").css("filter","blur(0px)");
$("#chart-wrapper").css("color","red");
var t = $(".tishitubiao");
if(t){
$(t).parent().css("display","none");
}
},0);
})();

很简单的逻辑,就改下相关Element的样式

reference

Tampermonkey documentation

Match patterns

基础参数

java -XX:+PrintFlagsFinal -version 获取JVM 所有提供的参数选项

formats
Type | Name | Operator | Value | Application

[Global flags]
#type name # =defaultValue :=overrideValue #{}
intx ActiveProcessorCount = -1 {product}
uintx AdaptiveSizeDecrementScaleFactor = 4 {product}
uintx AdaptiveSizeMajorGCDecayTimeScale = 10 {product}

java -XX:+PrintCommandLineFlags 打印当前运行JVM的参数

运行时

-Xmx20M 设置堆内存最大为20M

-Xms20M 设置堆内存最小为20M

-Xmn10M 设置新生代内存为10M

-verbose:gc 打印GC日志

-XX:SurvivorRatio=8 edian = 8/10 survivorFrom = 1/10, survivorTo = 1/10

-XX:+PrintGCDetails 打印gc详细日志

-XX:+PrintGCTimeStamps 打印gc时间戳

-Xloggc:gc.log gc日志输出到文件

-XX:+PrintStringTableStatistics 打印StringTable 和SymbolTable统计信息

References

https://chriswhocodes.com/hotspot_option_differences.html

https://foojay.io/command-line-arguments/openjdk-8/?tab=alloptions

https://chenweixiang.github.io/2020/05/29/english.html

jvm-options-cheat-sheet

jvm-ergonomics

VM

Java Platform, Standard Edition HotSpot Virtual Machine Garbage Collection Tuning Guide

  1. request /actuator/bus-refresh

  2. BusRefreshEndpoint received request

  3. ApplicationEventPublisher.publish(RemoteApplicationEvent)

  4. BusAutoConfiguration#

@EventListener(classes = RemoteApplicationEvent.class)
public void acceptLocal(RemoteApplicationEvent event) {
if (this.serviceMatcher.isFromSelf(event)
&& !(event instanceof AckRemoteApplicationEvent)) {
if (log.isDebugEnabled()) {
log.debug("Sending remote event on bus: " + event);
}
//rabitmqTemplate send messsage
this.cloudBusOutboundChannel.send(MessageBuilder.withPayload(event).build());
}
}

  1. request /actuator/bus-refresh

  2. BusRefreshEndpoint received request

  3. ApplicationEventPublisher.publish(RemoteApplicationEvent)

  4. BusAutoConfiguration#

@EventListener(classes = RemoteApplicationEvent.class)
public void acceptLocal(RemoteApplicationEvent event) {
if (this.serviceMatcher.isFromSelf(event)
&& !(event instanceof AckRemoteApplicationEvent)) {
if (log.isDebugEnabled()) {
log.debug("Sending remote event on bus: " + event);
}
this.cloudBusOutboundChannel.send(MessageBuilder.withPayload(event).build());
}
}

$?表示上个命令执行的结果值,0表示上个命令执行成功,非0表示上个命令执行失败

$$当前shell的进程ID

$_ 上个命令的最后一个参数

$! 为最近一个后台执行的异步命令的进程 ID

$0 为当前 Shell 的名称(在命令行直接执行时)或者脚本名(在脚本中执行时)

$- 为当前 Shell 的启动参数。

$@$#表示脚本的参数数量

step 1

  1. 魔法上网

  2. 注册区域随便选择

  3. 过了谷歌验证

  4. 邮箱确认注册

step 2

  1. 魔法上网(节点是你想注册到哪个地区的节点(eg:russia)),需要全局proxy

  2. 输入用户名密码

  3. 提交

  4. 上述步骤没出现问题的话,应该注册成功且自动跳转到steam首页了。

  5. 点击右上角账户明细,网页加载成功后 国家/地区 应该就是魔法上网选择的节点区域

0%