#include <iostream>
using namespace std;
class Base{
public:
virtual void f(){
std::cout << "Base\n";
}
};
class Derived1 : public Base{
public:
void f(){
std::cout << "Derived1\n";
}
};
class Derived2 : public Base{
public:
void f(){
std::cout << "Derived2\n";
}
};
int main() {
Derived1 d1;
Derived2 d2;
Base& ref = d1;
ref.f();
ref = d2;
ref.f();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
据说不能重新分配引用。在这里,编译器接受此代码并且输出对我来说是无法理解的。输出:
派生 1 派生 1
那么,ref = d2;
实际上是什么意思呢?
我编写了一个生成子集子集的函数。当我以下列方式使用时,它导致堆栈溢出subsets [1..]
。当涉及到“正常”(非懒惰)语言时,这是“正常”行为。现在,我想改进我的功能,使其变得懒惰。
PS我不理解懒惰(我试图理解它)所以也许我的问题对你来说很奇怪 - 请解释一下。:)
PS 2 请随意谈谈我在 Haskell 中的残疾情况;)
subsets :: [a] -> [[a]]
subsets (x:xs) = (map (\ e -> x:e) (subsets xs)) ++ (subsets xs)
subsets [] = [[]]
Run Code Online (Sandbox Code Playgroud) 我们考虑一下:
type Name = String -- variable names
data Exp = Lit Integer -- expressions
| Var Name
| Plus Exp Exp
| Abs Name Exp
| App Exp Exp
deriving (Show)
data Value = IntVal Integer -- values
| FunVal Env Name Exp
deriving (Show)
type Env = Map.Map Name Value -- mapping from names to values
eval0 :: Env -> Exp -> Value
eval0 env (Var n) = fromJust (Map.lookup n env )
Run Code Online (Sandbox Code Playgroud)
以上是0版本.
现在,让我们考虑monadic,1版本:
type Eval1 a …
Run Code Online (Sandbox Code Playgroud) instance Functor (State s) where
fmap f (State g) = State $ \s0 ->
let (a, s1) = g s0
in (f a, s1)
Run Code Online (Sandbox Code Playgroud)
它是Functor
for的实现State
.我无法理解它是如何工作的?特别是,g
因为它是一个功能,但在我看来它不是一个功能.它只是对象(也许是函数),但我无法理解为什么它是函数.毕竟,它应该是某种状态,所以它可以是例如Int
请说清楚.
引用来自:http://blog.ragozin.info/2012/10/safepoints-in-hotspot-jvm.html
安全点状态检查本身以非常狡猾的方式实现.正常的内存变量检查需要昂贵的内存屏障.但是,安全点检查是在内存读取障碍时实现的.然后需要安全点,JVM取消映射页面,该地址在应用程序线程上引发页面错误(由JVM的处理程序处理).这样,HotSpot维护其JITed代码CPU管道友好,但确保正确的内存语义(页面取消映射强制内存屏障处理核心).
我有些疑惑:
它写在http://psy-lob-saw.blogspot.com/2015/12/safepoints.html
Java 线程在执行 JNI 代码时处于安全点。在越过本机调用边界之前,堆栈在移交给本机代码之前保持一致状态。这意味着线程仍然可以在安全点运行。
这怎么可能?毕竟,我可以将对象的引用传递给JNI
. 在 JNI 中,我可以在该对象中设置一个字段。
很明显是收不到的(我们有本地参考)。但是,它可以在完整的 gc 收集期间通过 GC 移动到老年代。所以,我们有以下情况:
GC collector: | Thread executing JNI code
compact old generation | modify object fields that can be
and move object from young generation | moved now! A catastrophe.
to old generation. |
Run Code Online (Sandbox Code Playgroud)
JVM 如何处理?
我有常春藤桥CPU.以下代码每次迭代需要3个周期:
L1:
movapd xmm1, [rsi+rax] ; X[i], X[i+1]
mulpd xmm1, xmm2
movapd xmm0, [rdi+rax] ; Y[i], Y[i+1]
subpd xmm0, xmm1
movapd [rdi+rax], xmm0 ; Store result
add rax, 16
cmp rax, rcx
jl L1
Run Code Online (Sandbox Code Playgroud)
以下每次迭代需要9个周期:
L1:
movapd xmm1, [rsi+rax] ; X[i], X[i+1]
mulpd xmm1, xmm2
movapd xmm0, [rdi+rax] ; Y[i], Y[i+1]
add rax, 16
subpd xmm0, xmm1
movapd [rdi+rax], xmm0 ; Store result
cmp rax, rcx
jl L1
Run Code Online (Sandbox Code Playgroud)
唯一的区别是order(add rax, 16
).并且它导致程序慢3倍.为什么差异如此之大?
消除列表元素的连续重复.
我的解决方案是:
compress([X,X|Xs], Q) :-
compress([X|Xs], Q).
compress([X,Y|Xs], Q) :-
X \= Y,
compress([Y|Xs], QR),
append([X], QR, Q).
compress([X|[]], Q) :-
compress([], QR),
append([X], QR, Q).
compress([], []).
Run Code Online (Sandbox Code Playgroud)
并且,由于我是初学者并且我没有逻辑范例的经验,我请求您说出我可以改进的内容以及为什么我的解决方案不尽如人意.
例如,X \= Y
对我来说并不漂亮.
让我们考虑以下代码:
package index;
public class Main {
public static void main(String[] args) {
Inner inner = new Inner();
Type t = inner.getClass().getGenericSuperclass();
ParameterizedType p = (ParameterizedType) t;
Type[] a = p.getActualTypeArguments();
try {
Custom c = (Custom) ((Class) a[0]).newInstance();
c.f();
} catch (Exception e){}
}
private static abstract class AbstractClass<T> {
public abstract void doSth();
}
private static class Inner extends AbstractClass<Custom>{
public void doSth() {
}
}
private static class Custom{
public Custom(){
}
public void f(){
System.out.println("Custom");
} …
Run Code Online (Sandbox Code Playgroud) 我写这篇文章是为了深入理解 Java 中的 volatile
public class Main {
private int x;
private volatile int g;
public void actor1(){
x = 1;
g = 1;
}
public void actor2(){
put_on_screen_without_sync(g);
put_on_screen_without_sync(x);
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我正在分析 JIT 为上述代码生成的内容。从我们在上一篇文章中的讨论中我们知道输出1, 0
是不可能的,因为:
写挥发v
的原因,每一个动作a
前述v
原因,那a
之前是可见的(将被刷新到内存)v
将是可见的。
.................(I removed not important body of method).....
0x00007f42307d9d5e: c7460c01000000 (1) mov dword ptr [rsi+0ch],1h
;*putfield x
; - package.Main::actor1@2 (line 14)
0x00007f42307d9d65: bf01000000 (2) mov edi,1h
0x00007f42307d9d6a: 897e10 (3) mov …
Run Code Online (Sandbox Code Playgroud) jvm ×4
haskell ×3
java ×2
c++ ×1
list ×1
optimization ×1
prolog ×1
prolog-dif ×1
reflection ×1
volatile ×1
x86 ×1